diff --git a/cmd/relayproxy/config/retriever.go b/cmd/relayproxy/config/retriever.go index 60515677214..e6a54492a9c 100644 --- a/cmd/relayproxy/config/retriever.go +++ b/cmd/relayproxy/config/retriever.go @@ -30,6 +30,7 @@ type RetrieverConf struct { URI string `mapstructure:"uri" koanf:"uri"` Database string `mapstructure:"database" koanf:"database"` Collection string `mapstructure:"collection" koanf:"collection"` + Type string `mapstructure:"type" koanf:"type"` Table string `mapstructure:"table" koanf:"table"` Column string `mapstructure:"column" koanf:"column"` RedisOptions *redis.Options `mapstructure:"redisOptions" koanf:"redisOptions"` @@ -127,6 +128,10 @@ func (c *RetrieverConf) validatePostgreSQLRetriever() error { if c.URI == "" { return fmt.Errorf("invalid retriever: no \"uri\" property found for kind \"%s\"", c.Kind) } + if c.Type == "" || !(c.Type == "json") { + return fmt.Errorf("invalid retriever: no \"type\" property or not a valid type in kind \"%s\"", c.Kind) + } + return nil } diff --git a/cmd/relayproxy/service/gofeatureflag.go b/cmd/relayproxy/service/gofeatureflag.go index 5620594713c..9ffd68dd569 100644 --- a/cmd/relayproxy/service/gofeatureflag.go +++ b/cmd/relayproxy/service/gofeatureflag.go @@ -26,6 +26,7 @@ import ( "github.com/thomaspoignant/go-feature-flag/notifier/slacknotifier" "github.com/thomaspoignant/go-feature-flag/notifier/webhooknotifier" "github.com/thomaspoignant/go-feature-flag/retriever" + "github.com/thomaspoignant/go-feature-flag/retriever/azblobstorageretriever" "github.com/thomaspoignant/go-feature-flag/retriever/bitbucketretriever" "github.com/thomaspoignant/go-feature-flag/retriever/fileretriever" "github.com/thomaspoignant/go-feature-flag/retriever/gcstorageretriever" @@ -186,7 +187,7 @@ func initRetriever(c *config.RetrieverConf) (retriever.Retriever, error) { case config.MongoDBRetriever: return &mongodbretriever.Retriever{Database: c.Database, URI: c.URI, Collection: c.Collection}, nil case config.PostgreSQLRetriever: - return &postgresqlretriever.Retriever{URI: c.URI, Table: c.Table, Column: c.Column}, nil + return &postgresqlretriever.Retriever{Type: c.Type, URI: c.URI, Table: c.Table, Column: c.Column}, nil case config.RedisRetriever: return &redisretriever.Retriever{Options: c.RedisOptions, Prefix: c.RedisPrefix}, nil case config.AzBlobStorageRetriever: diff --git a/examples/retriever_postgresql/main.go b/examples/retriever_postgresql/main.go index 059a31eaa1f..46d9cc545c3 100644 --- a/examples/retriever_postgresql/main.go +++ b/examples/retriever_postgresql/main.go @@ -23,6 +23,7 @@ func main() { Context: context.Background(), Retriever: &postgresqlretriever.Retriever{ Table: "flags", + Type: "json", Column: "flag", URI: "postgres://root:example@localhost:5432/flags_db?sslmode=disable", }, diff --git a/retriever/postgresqlretriever/retriever.go b/retriever/postgresqlretriever/retriever.go index a8aaa18617d..072dcb3aec8 100644 --- a/retriever/postgresqlretriever/retriever.go +++ b/retriever/postgresqlretriever/retriever.go @@ -6,7 +6,6 @@ import ( "fmt" "github.com/jackc/pgx/v5/pgxpool" - _ "github.com/lib/pq" "github.com/thomaspoignant/go-feature-flag/retriever" "github.com/thomaspoignant/go-feature-flag/utils/fflog" ) @@ -14,7 +13,8 @@ import ( // Retriever is a configuration struct for a PostgreSQL connection type Retriever struct { // PostgreSQL connection URI - URI string + URI string + Type string // PostgreSQL table where flag column is stored Table string // PostgreSQL column where flag definitions are stored @@ -51,8 +51,8 @@ func (r *Retriever) Init(ctx context.Context, logger *fflog.FFLogger) error { r.dbPool = pool r.status = retriever.RetrieverReady - } + return nil } @@ -65,15 +65,14 @@ func (r *Retriever) Status() retriever.Status { } // Shutdown disconnects the retriever from Mongodb instance -func (r *Retriever) Shutdown(ctx context.Context) error { +func (r *Retriever) Shutdown(_ context.Context) error { r.dbPool.Close() return nil } // Retrieve Reads flag configuration from postgreSQL and returns it -// if a document does not comply with the specification it will be ignored +// If a document does not comply with the specification it will be ignored func (r *Retriever) Retrieve(ctx context.Context) ([]byte, error) { - query := fmt.Sprintf("SELECT %s FROM %s WHERE %s IS NOT NULL", r.Column, r.Table, r.Column) rows, err := r.dbPool.Query(ctx, query) if err != nil { @@ -117,5 +116,4 @@ func (r *Retriever) Retrieve(ctx context.Context) ([]byte, error) { } return flags, nil - } diff --git a/retriever/postgresqlretriever/retriever_test.go b/retriever/postgresqlretriever/retriever_test.go index d224bb14518..5ef2aebaa7e 100644 --- a/retriever/postgresqlretriever/retriever_test.go +++ b/retriever/postgresqlretriever/retriever_test.go @@ -18,12 +18,12 @@ import ( "go.mongodb.org/mongo-driver/bson" ) -func Test_MongoDBRetriever_Retrieve(t *testing.T) { +func Test_PostgreSQLRetriever_Retrieve(t *testing.T) { ctx := context.Background() - dbName := "users" - dbUser := "user" - dbPassword := "password" + dbName := "flags_db" + dbUser := "root" + dbPassword := "example" tests := []struct { name string @@ -56,7 +56,7 @@ func Test_MongoDBRetriever_Retrieve(t *testing.T) { }, } - // Start the postgres ctr and run any migrations on it + // Start the postgres container ctr, err := postgres.Run( ctx, "postgres:16-alpine", @@ -69,10 +69,11 @@ func Test_MongoDBRetriever_Retrieve(t *testing.T) { testcontainers.CleanupContainer(t, ctr) require.NoError(t, err) + // Run initialization query to create the table and the column _, _, err = ctr.Exec(ctx, []string{"psql", "-U", dbUser, "-d", dbName, "-c", "CREATE TABLE flags (id SERIAL PRIMARY KEY,flag JSONB)"}) require.NoError(t, err) - //Create snapshot of the database, which is then restored before each test + // Create snapshot of the database, which is then restored before each test err = ctr.Snapshot(ctx) require.NoError(t, err) @@ -89,7 +90,7 @@ func Test_MongoDBRetriever_Retrieve(t *testing.T) { defer conn.Close(context.Background()) if item.data != "" { - // insert data + // Insert data var documents []bson.M err = json.Unmarshal([]byte(item.data), &documents) require.NoError(t, err) @@ -100,7 +101,7 @@ func Test_MongoDBRetriever_Retrieve(t *testing.T) { } } - // retriever + // Initialize Retriever mdb := postgresqlretriever.Retriever{ URI: dbURL, Table: "flags", @@ -123,7 +124,6 @@ func Test_MongoDBRetriever_Retrieve(t *testing.T) { } require.NoError(t, err) - } }