From 149e50199c5b6a6008d91301dd21d96fdab5629a Mon Sep 17 00:00:00 2001 From: ElectroNafta Date: Thu, 8 Aug 2024 16:56:10 +0200 Subject: [PATCH] feat(BRIDGE-119): added feature flag relevant API calls; added Feature Flag route to fake server --- client_features.go | 19 +++++++++++++++++++ manager_features.go | 26 ++++++++++++++++++++++++++ server/backend/api.go | 21 +++++++++++++++++++++ server/backend/backend.go | 2 ++ server/features.go | 17 +++++++++++++++++ server/router.go | 3 +++ server/server.go | 8 ++++++++ 7 files changed, 96 insertions(+) create mode 100644 client_features.go create mode 100644 manager_features.go create mode 100644 server/features.go diff --git a/client_features.go b/client_features.go new file mode 100644 index 0000000..d41a3b8 --- /dev/null +++ b/client_features.go @@ -0,0 +1,19 @@ +package proton + +import ( + "context" + + "github.com/go-resty/resty/v2" +) + +func (c *Client) GetFeatures(ctx context.Context) (FeatureFlagResult, error) { + res := FeatureFlagResult{} + + if err := c.do(ctx, func(r *resty.Request) (*resty.Response, error) { + return r.SetResult(&res).Get("/feature/v2/frontend") + }); err != nil { + return FeatureFlagResult{}, err + } + + return res, nil +} diff --git a/manager_features.go b/manager_features.go new file mode 100644 index 0000000..7e8f186 --- /dev/null +++ b/manager_features.go @@ -0,0 +1,26 @@ +package proton + +import ( + "context" +) + +type FeatureFlagResult struct { + Code int `json:"Code"` + Toggles []FeatureToggle `json:"toggles"` +} + +type FeatureToggle struct { + Name string `json:"name"` + Enabled bool `json:"enabled"` +} + +func (m *Manager) GetFeatures(ctx context.Context) (FeatureFlagResult, error) { + responseData := FeatureFlagResult{} + + _, err := m.r(ctx).SetResult(&responseData).Get("/feature/v2/frontend") + if err != nil { + return FeatureFlagResult{}, err + } + + return responseData, nil +} diff --git a/server/backend/api.go b/server/backend/api.go index 1008ff9..431f9a8 100644 --- a/server/backend/api.go +++ b/server/backend/api.go @@ -1294,6 +1294,27 @@ func (b *Backend) GenerateContactID(userID string) (string, error) { }) } +func (b *Backend) GetFeatureFlags() []proton.FeatureToggle { + return readBackendRet(b, func(b *unsafeBackend) []proton.FeatureToggle { + return b.featureFlags + }) +} + +func (b *Backend) PushFeatureFlag(flagName string) { + writeBackend(b, func(b *unsafeBackend) { + b.featureFlags = append(b.featureFlags, proton.FeatureToggle{ + Name: flagName, + Enabled: true, + }) + }) +} + +func (b *Backend) DeleteFeatureFlags() { + writeBackend(b, func(b *unsafeBackend) { + b.featureFlags = []proton.FeatureToggle{} + }) +} + func buildEvent( updates []update, addresses map[string]*address, diff --git a/server/backend/backend.go b/server/backend/backend.go index 408242d..8ce276b 100644 --- a/server/backend/backend.go +++ b/server/backend/backend.go @@ -48,6 +48,8 @@ type unsafeBackend struct { enableDedup bool csTicket []string + + featureFlags []proton.FeatureToggle } func readBackendRet[T any](b *Backend, f func(b *unsafeBackend) T) T { diff --git a/server/features.go b/server/features.go new file mode 100644 index 0000000..24bc280 --- /dev/null +++ b/server/features.go @@ -0,0 +1,17 @@ +package server + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func (s *Server) handleGetFeatures() gin.HandlerFunc { + return func(c *gin.Context) { + ff := s.b.GetFeatureFlags() + c.JSON(http.StatusOK, gin.H{ + "Code": 1000, + "Toggles": ff, + }) + } +} diff --git a/server/router.go b/server/router.go index fe976c1..c149d51 100644 --- a/server/router.go +++ b/server/router.go @@ -26,6 +26,9 @@ func initRouter(s *Server) { s.applyRateLimit(), ) + // Feature flag route. Needs to be updated when user specific feature flags are implemented + s.r.GET("/feature/v2/frontend", s.handleGetFeatures()) + if core := s.r.Group("/core/v4"); core != nil { // Domains routes don't need authentication. if domains := core.Group("/domains"); domains != nil { diff --git a/server/server.go b/server/server.go index 3c5438b..ad516db 100644 --- a/server/server.go +++ b/server/server.go @@ -252,3 +252,11 @@ func (s *Server) Close() { s.proxyTransport.CloseIdleConnections() s.s.Close() } + +func (s *Server) PushFeatureFlag(flagName string) { + s.b.PushFeatureFlag(flagName) +} + +func (s *Server) DeleteFeatureFlags() { + s.b.DeleteFeatureFlags() +}