diff --git a/cmd/flaggio/admin.go b/cmd/flaggio/admin.go index 7084c86..779c963 100644 --- a/cmd/flaggio/admin.go +++ b/cmd/flaggio/admin.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql/playground" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" + "github.com/go-redis/redis/v7" "github.com/rs/cors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" @@ -22,42 +23,49 @@ import ( ) func startAdmin(ctx context.Context, c *cli.Context, logger *logrus.Entry) error { - logger.Info("starting admin server ...") + logger.Debug("starting admin server ...") isDev := c.String("app-env") == "dev" + // connect to mongo db, err := getMongoDatabase(ctx, c.String("database-uri")) if err != nil { return err } - // connect to redis - redisClient, err := getRedisClient(c.String("redis-uri")) - if err != nil { - return err + var redisClient *redis.Client + if c.IsSet("redis-uri") { + // connect to redis + redisClient, err = getRedisClient(c.String("redis-uri")) + if err != nil { + return err + } } // setup repositories - flgMongoRepo, err := mongo_repo.NewFlagRepository(ctx, db) + flagRepo, err := mongo_repo.NewFlagRepository(ctx, db) if err != nil { return err } - flgRedisRepo := redis_repo.NewFlagRepository(redisClient, flgMongoRepo) - sgmntMongoRepo, err := mongo_repo.NewSegmentRepository(ctx, db) + segmentRepo, err := mongo_repo.NewSegmentRepository(ctx, db) if err != nil { return err } - sgmntRedisRepo := redis_repo.NewSegmentRepository(redisClient, sgmntMongoRepo) - vrntRedisRepo := redis_repo.NewVariantRepository(redisClient, - mongo_repo.NewVariantRepository(flgMongoRepo), flgRedisRepo) - ruleRedisRepo := redis_repo.NewRuleRepository(redisClient, - mongo_repo.NewRuleRepository(flgMongoRepo, sgmntMongoRepo), flgRedisRepo, sgmntRedisRepo) + variantRepo := mongo_repo.NewVariantRepository(flagRepo.(*mongo_repo.FlagRepository)) + ruleRepo := mongo_repo.NewRuleRepository( + flagRepo.(*mongo_repo.FlagRepository), segmentRepo.(*mongo_repo.SegmentRepository)) + if redisClient != nil { + flagRepo = redis_repo.NewFlagRepository(redisClient, flagRepo) + segmentRepo = redis_repo.NewSegmentRepository(redisClient, segmentRepo) + variantRepo = redis_repo.NewVariantRepository(redisClient, variantRepo, flagRepo) + ruleRepo = redis_repo.NewRuleRepository(redisClient, ruleRepo, flagRepo, segmentRepo) + } // setup graphql resolver resolver := &admin.Resolver{ - FlagRepo: flgRedisRepo, - VariantRepo: vrntRedisRepo, - RuleRepo: ruleRedisRepo, - SegmentRepo: sgmntRedisRepo, + FlagRepo: flagRepo, + VariantRepo: variantRepo, + RuleRepo: ruleRepo, + SegmentRepo: segmentRepo, } // setup graphql server @@ -105,7 +113,6 @@ func startAdmin(ctx context.Context, c *cli.Context, logger *logrus.Entry) error router.Get("/*", func(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, buildPath+"/index.html") }) - logger.Infof("admin UI enabled") } // setup http server @@ -123,13 +130,16 @@ func startAdmin(ctx context.Context, c *cli.Context, logger *logrus.Entry) error defer shutdownCancel() if err := srv.Shutdown(shutdownCtx); err != nil { - logrus.Fatalf("admin server shutdown failed: %+v", err) + logger.Fatalf("admin server shutdown failed: %+v", err) } }() - if isDev { - logger.Infof("GraphQL playground enabled") - } - logger.WithField("listening", c.String("admin-addr")).Infof("admin server started") + + logger.WithFields(logrus.Fields{ + "cache_enabled": c.IsSet("redis-uri"), + "listening": c.String("admin-addr"), + "playground": isDev, + "admin_ui": !c.Bool("no-admin-ui"), + }).Infof("admin server started") return srv.ListenAndServe() } diff --git a/cmd/flaggio/api.go b/cmd/flaggio/api.go index 593f359..3e327f1 100644 --- a/cmd/flaggio/api.go +++ b/cmd/flaggio/api.go @@ -7,6 +7,7 @@ import ( "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" + "github.com/go-redis/redis/v7" "github.com/rs/cors" "github.com/sirupsen/logrus" "github.com/urfave/cli/v2" @@ -19,34 +20,42 @@ import ( ) func startAPI(ctx context.Context, c *cli.Context, logger *logrus.Entry) error { - logger.Info("starting api server ...") + logger.Debug("starting api server ...") + // connect to mongo db, err := getMongoDatabase(ctx, c.String("database-uri")) if err != nil { return err } - // connect to redis - redisClient, err := getRedisClient(c.String("redis-uri")) - if err != nil { - return err + var redisClient *redis.Client + if c.IsSet("redis-uri") { + // connect to redis + redisClient, err = getRedisClient(c.String("redis-uri")) + if err != nil { + return err + } } // setup repositories - flgMongoRepo, err := mongo_repo.NewFlagRepository(ctx, db) + flagRepo, err := mongo_repo.NewFlagRepository(ctx, db) if err != nil { return err } - flgRedisRepo := redis_repo.NewFlagRepository(redisClient, flgMongoRepo) - sgmntMongoRepo, err := mongo_repo.NewSegmentRepository(ctx, db) + segmentRepo, err := mongo_repo.NewSegmentRepository(ctx, db) if err != nil { return err } - sgmntRedisRepo := redis_repo.NewSegmentRepository(redisClient, sgmntMongoRepo) + if redisClient != nil { + flagRepo = redis_repo.NewFlagRepository(redisClient, flagRepo) + segmentRepo = redis_repo.NewSegmentRepository(redisClient, segmentRepo) + } // setup services - flagService := service.NewFlagService(flgRedisRepo, sgmntRedisRepo) - flagRedisService := redis_svc.NewFlagService(redisClient, flagService) + flagService := service.NewFlagService(flagRepo, segmentRepo) + if redisClient != nil { + flagService = redis_svc.NewFlagService(redisClient, flagService) + } // setup router router := chi.NewRouter() @@ -72,7 +81,7 @@ func startAPI(ctx context.Context, c *cli.Context, logger *logrus.Entry) error { Addr: c.String("api-addr"), Handler: api.NewServer( router, - flagRedisService, + flagService, ), WriteTimeout: 15 * time.Second, ReadTimeout: 15 * time.Second, @@ -85,9 +94,13 @@ func startAPI(ctx context.Context, c *cli.Context, logger *logrus.Entry) error { defer shutdownCancel() if err := srv.Shutdown(shutdownCtx); err != nil { - logrus.Fatalf("api server shutdown failed: %+v", err) + logger.Fatalf("api server shutdown failed: %+v", err) } }() - logger.WithField("listening", c.String("api-addr")).Infof("api server started") + + logger.WithFields(logrus.Fields{ + "cache_enabled": c.IsSet("redis-uri"), + "listening": c.String("api-addr"), + }).Infof("api server started") return srv.ListenAndServe() } diff --git a/internal/repository/mongodb/flag.repository.go b/internal/repository/mongodb/flag.repository.go index 1c54c60..11340dc 100644 --- a/internal/repository/mongodb/flag.repository.go +++ b/internal/repository/mongodb/flag.repository.go @@ -190,7 +190,7 @@ func (r *FlagRepository) Delete(ctx context.Context, idHex string) error { // NewFlagRepository returns a new flag repository that uses mongodb as underlying storage. // It also creates all needed indexes, if they don't yet exist. -func NewFlagRepository(ctx context.Context, db *mongo.Database) (*FlagRepository, error) { +func NewFlagRepository(ctx context.Context, db *mongo.Database) (repository.Flag, error) { col := db.Collection("flags") _, err := col.Indexes().CreateMany(ctx, []mongo.IndexModel{ { diff --git a/internal/repository/mongodb/rule.repository.go b/internal/repository/mongodb/rule.repository.go index c6777b2..a50693f 100644 --- a/internal/repository/mongodb/rule.repository.go +++ b/internal/repository/mongodb/rule.repository.go @@ -292,7 +292,7 @@ func (r *RuleRepository) DeleteSegmentRule(ctx context.Context, segmentIDHex, id } // NewRuleRepository returns a new rule repository that uses mongodb as underlying storage. -func NewRuleRepository(flagRepo *FlagRepository, segmentRepo *SegmentRepository) *RuleRepository { +func NewRuleRepository(flagRepo *FlagRepository, segmentRepo *SegmentRepository) repository.Rule { return &RuleRepository{ flagRepo: flagRepo, segmentRepo: segmentRepo, diff --git a/internal/repository/mongodb/segment.repository.go b/internal/repository/mongodb/segment.repository.go index 1eb60b3..07b7506 100644 --- a/internal/repository/mongodb/segment.repository.go +++ b/internal/repository/mongodb/segment.repository.go @@ -132,7 +132,7 @@ func (r *SegmentRepository) Delete(ctx context.Context, idHex string) error { // NewSegmentRepository returns a new segment repository that uses mongodb as underlying storage. // It also creates all needed indexes, if they don't yet exist. -func NewSegmentRepository(ctx context.Context, db *mongo.Database) (*SegmentRepository, error) { +func NewSegmentRepository(ctx context.Context, db *mongo.Database) (repository.Segment, error) { col := db.Collection("segments") _, err := col.Indexes().CreateMany(ctx, []mongo.IndexModel{ { diff --git a/internal/repository/mongodb/variant.repository.go b/internal/repository/mongodb/variant.repository.go index 0a9232e..7540095 100644 --- a/internal/repository/mongodb/variant.repository.go +++ b/internal/repository/mongodb/variant.repository.go @@ -132,7 +132,7 @@ func (r *VariantRepository) Delete(ctx context.Context, flagIDHex, idHex string) // NewVariantRepository returns a new variant repository that uses mongodb // as underlying storage. -func NewVariantRepository(flagRepo *FlagRepository) *VariantRepository { +func NewVariantRepository(flagRepo *FlagRepository) repository.Variant { return &VariantRepository{ flagRepo: flagRepo, }