diff --git a/gecko/server.go b/gecko/server.go index 70df6fb..d65546d 100644 --- a/gecko/server.go +++ b/gecko/server.go @@ -72,6 +72,7 @@ func (server *Server) MakeRouter() *iris.Application { router.Get("/health", server.handleHealth) router.Get("/config/{configId}", server.handleConfigGET) router.Put("/config/{configId}", server.handleConfigPUT) + router.Get("/config/list", server.handleConfigListGET) router.Delete("/config/{configId}", server.handleConfigDELETE) // Optionally keep UseRouter if needed, with safety checks @@ -105,6 +106,24 @@ func recoveryMiddleware(ctx iris.Context) { ctx.Next() } +func (server *Server) handleConfigListGET(ctx iris.Context) { + configList, err := configList(server.db) + if configList == nil && err == nil { + errResponse := newErrorResponse("No configs found", 404, nil) + errResponse.log.write(server.logger) + _ = errResponse.write(ctx) + return + } + if err != nil { + errResponse := newErrorResponse(fmt.Sprintf("%s", err), 500, nil) + errResponse.log.write(server.logger) + _ = errResponse.write(ctx) + return + } + server.logger.Info("Configs: %#v", configList) + _ = jsonResponseFrom(configList, http.StatusOK).write(ctx) +} + func (server *Server) handleConfigGET(ctx iris.Context) { configId := ctx.Params().Get("configId") doc, err := configGET(server.db, configId) @@ -190,7 +209,6 @@ func (server *Server) handleConfigPUT(ctx iris.Context) { } func (server *Server) handleHealth(ctx iris.Context) { - server.logger.Info("Entering handleHealth") err := server.db.Ping() if err != nil { server.logger.Error("Database ping failed: %v", err) diff --git a/gecko/sql.go b/gecko/sql.go index 9765070..68018e6 100644 --- a/gecko/sql.go +++ b/gecko/sql.go @@ -4,6 +4,7 @@ import ( "database/sql" "encoding/json" "errors" + "fmt" "github.com/ACED-IDP/gecko/gecko/config" "github.com/jmoiron/sqlx" @@ -15,6 +16,18 @@ type Document struct { Content json.RawMessage `db:"content"` // Store JSON as raw bytes } +func configList(db *sqlx.DB) ([]string, error) { + var names []string + err := db.Select(&names, "SELECT name FROM documents") + if err != nil { + if errors.Is(err, sql.ErrNoRows) { + return []string{}, nil + } + return nil, fmt.Errorf("error fetching config names: %w", err) + } + return names, nil +} + func configGET(db *sqlx.DB, name string) (map[string]any, error) { stmt := "SELECT name, content FROM documents WHERE name=$1" doc := &Document{} diff --git a/tests/integration/api_test.go b/tests/integration/api_test.go index b81a403..c566add 100644 --- a/tests/integration/api_test.go +++ b/tests/integration/api_test.go @@ -161,3 +161,30 @@ func TestHandleConfigDeleteOK(t *testing.T) { assert.NoError(t, err) assert.Equal(t, resp.StatusCode, 404) } + +func TestHandleListConfigsOK(t *testing.T) { + var configs []config.ConfigItem + err := json.Unmarshal([]byte(fixtures.TestConfig), &configs) + payloadBytes, err := json.Marshal(configs) + assert.NoError(t, err) + _, err = http.DefaultClient.Do(makeRequest("PUT", "http://localhost:8080/config/testdelete", payloadBytes)) + assert.NoError(t, err) + + resp, err := http.DefaultClient.Do(makeRequest("GET", "http://localhost:8080/config/list", nil)) + assert.NoError(t, err) + + buf := new(bytes.Buffer) + buf.ReadFrom(resp.Body) + resp.Body.Close() + var outdata []string + json.Unmarshal(buf.Bytes(), &outdata) + + passtest := false + for _, conf := range outdata { + if conf == "testdelete" { + passtest = true + } + } + t.Log("Configs: ", outdata) + assert.True(t, passtest) +}