From 8cc7e7a15de61157fe33b888166b85ffe923a240 Mon Sep 17 00:00:00 2001 From: Mauro Antonio Sanz Date: Thu, 3 Oct 2024 17:43:38 -0300 Subject: [PATCH 1/2] Adding /memberships endpoint --- go.mod | 2 +- go.sum | 6 ++- splitio/commitversion.go | 2 +- splitio/proxy/controllers/sdk.go | 30 +++++++++++ splitio/proxy/controllers/sdk_test.go | 76 +++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 35f9e160..2137b567 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/google/uuid v1.3.0 github.com/splitio/gincache v1.0.1 - github.com/splitio/go-split-commons/v6 v6.0.1 + github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003203711-098c0ea804b3 github.com/splitio/go-toolkit/v5 v5.4.0 github.com/stretchr/testify v1.9.0 go.etcd.io/bbolt v1.3.6 diff --git a/go.sum b/go.sum index 9f6e2ecd..e713f5a9 100644 --- a/go.sum +++ b/go.sum @@ -93,8 +93,10 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= github.com/splitio/gincache v1.0.1 h1:dLYdANY/BqH4KcUMCe/LluLyV5WtuE/LEdQWRE06IXU= github.com/splitio/gincache v1.0.1/go.mod h1:CcgJDSM9Af75kyBH0724v55URVwMBuSj5x1eCWIOECY= -github.com/splitio/go-split-commons/v6 v6.0.1 h1:WJcvTk8lwWw6kLQvxt8hOkY/tGlBN4w+2agkINPGugY= -github.com/splitio/go-split-commons/v6 v6.0.1/go.mod h1:TsvIh3XP7yjc7ly4vpj06AkoBND36SodPs5qfhb8rHc= +github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003202846-c19d3164beda h1:to9Km94ayhpT5mzhQe2iLdeS2nVA9wB5tFV76fnwoek= +github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003202846-c19d3164beda/go.mod h1:TsvIh3XP7yjc7ly4vpj06AkoBND36SodPs5qfhb8rHc= +github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003203711-098c0ea804b3 h1:S3h7x9d11SRMW8S9OtL9EPOEcrT6dD2jLoozq6kWes4= +github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003203711-098c0ea804b3/go.mod h1:TsvIh3XP7yjc7ly4vpj06AkoBND36SodPs5qfhb8rHc= github.com/splitio/go-toolkit/v5 v5.4.0 h1:g5WFpRhQomnXCmvfsNOWV4s5AuUrWIZ+amM68G8NBKM= github.com/splitio/go-toolkit/v5 v5.4.0/go.mod h1:xYhUvV1gga9/1029Wbp5pjnR6Cy8nvBpjw99wAbsMko= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/splitio/commitversion.go b/splitio/commitversion.go index 238005fb..360f0cb2 100644 --- a/splitio/commitversion.go +++ b/splitio/commitversion.go @@ -5,4 +5,4 @@ This file is created automatically, please do not edit */ // CommitVersion is the version of the last commit previous to release -const CommitVersion = "8d090ac" +const CommitVersion = "319e79e" diff --git a/splitio/proxy/controllers/sdk.go b/splitio/proxy/controllers/sdk.go index 3909558b..96df7b5e 100644 --- a/splitio/proxy/controllers/sdk.go +++ b/splitio/proxy/controllers/sdk.go @@ -54,6 +54,7 @@ func (c *SdkServerController) Register(router gin.IRouter) { router.GET("/splitChanges", c.SplitChanges) router.GET("/segmentChanges/:name", c.SegmentChanges) router.GET("/mySegments/:key", c.MySegments) + router.GET("/memberships/:key", c.Memberships) } // SplitChanges Returns a diff containing changes in feature flags from a certain point in time until now. @@ -140,6 +141,35 @@ func (c *SdkServerController) MySegments(ctx *gin.Context) { ctx.Set(caching.SurrogateContextKey, caching.MakeSurrogateForMySegments(mySegments)) } +// Memberships Returns +func (c *SdkServerController) Memberships(ctx *gin.Context) { + c.logger.Debug(fmt.Sprintf("Headers: %v", ctx.Request.Header)) + key := ctx.Param("key") + segmentList, err := c.proxySegmentStorage.SegmentsFor(key) + if err != nil { + c.logger.Error(fmt.Sprintf("error fetching segments for user '%s': %s", key, err.Error())) + ctx.JSON(http.StatusInternalServerError, gin.H{}) + } + + mySegments := make([]dtos.MemItem, 0, len(segmentList)) + for _, segmentName := range segmentList { + mySegments = append(mySegments, dtos.MemItem{Name: segmentName}) + } + + payoad := dtos.MembershipsDTO{ + MySegments: dtos.Member{ + Keys: mySegments, + }, + LargeSegments: dtos.Member{ + Keys: []dtos.MemItem{}, + ChangeNumber: 0, + }, + } + + ctx.JSON(http.StatusOK, payoad) + ctx.Set(caching.SurrogateContextKey, nil) +} + func (c *SdkServerController) fetchSplitChangesSince(since int64, sets []string) (*dtos.SplitChangesDTO, error) { splits, err := c.proxySplitStorage.ChangesSince(since, sets) if err == nil { diff --git a/splitio/proxy/controllers/sdk_test.go b/splitio/proxy/controllers/sdk_test.go index 0c0c1b99..87aa75e2 100644 --- a/splitio/proxy/controllers/sdk_test.go +++ b/splitio/proxy/controllers/sdk_test.go @@ -545,6 +545,82 @@ func TestMySegmentsError(t *testing.T) { segmentStorage.AssertExpectations(t) } +func TestMemberships(t *testing.T) { + gin.SetMode(gin.TestMode) + + var splitFetcher splitFetcherMock + var splitStorage psmocks.ProxySplitStorageMock + var segmentStorage psmocks.ProxySegmentStorageMock + segmentStorage.On("SegmentsFor", "testKey"). + Return([]string{"segment1", "segment2", "segmentTest"}, nil). + Once() + + resp := httptest.NewRecorder() + ctx, router := gin.CreateTestContext(resp) + + logger := logging.NewLogger(nil) + + group := router.Group("/api") + controller := NewSdkServerController(logger, &splitFetcher, &splitStorage, &segmentStorage, flagsets.NewMatcher(false, nil)) + controller.Register(group) + + ctx.Request, _ = http.NewRequest(http.MethodGet, "/api/memberships/testKey", nil) + ctx.Request.Header.Set("Authorization", "Bearer someApiKey") + ctx.Request.Header.Set("SplitSDKVersion", "go-1.1.1") + ctx.Request.Header.Set("SplitSDKMachineIp", "1.2.3.4") + ctx.Request.Header.Set("SplitSDKMachineName", "ip-1-2-3-4") + router.ServeHTTP(resp, ctx.Request) + assert.Equal(t, 200, resp.Code) + + body, err := io.ReadAll(resp.Body) + assert.Nil(t, err) + + var memberships dtos.MembershipsDTO + err = json.Unmarshal(body, &memberships) + assert.Nil(t, err) + + assert.Equal(t, dtos.MembershipsDTO{ + MySegments: dtos.Member{Keys: []dtos.MemItem{{Name: "segment1"}, {Name: "segment2"}, {Name: "segmentTest"}}}, + LargeSegments: dtos.Member{Keys: []dtos.MemItem{}}, + }, memberships) + + splitStorage.AssertExpectations(t) + splitFetcher.AssertExpectations(t) + segmentStorage.AssertExpectations(t) +} + +func TestMembershipsError(t *testing.T) { + gin.SetMode(gin.TestMode) + + var splitFetcher splitFetcherMock + var splitStorage psmocks.ProxySplitStorageMock + var segmentStorage psmocks.ProxySegmentStorageMock + segmentStorage.On("SegmentsFor", "testKey"). + Return([]string{}, errors.New("something")). + Once() + + resp := httptest.NewRecorder() + ctx, router := gin.CreateTestContext(resp) + + logger := logging.NewLogger(nil) + + group := router.Group("/api") + controller := NewSdkServerController(logger, &splitFetcher, &splitStorage, &segmentStorage, flagsets.NewMatcher(false, nil)) + controller.Register(group) + + ctx.Request, _ = http.NewRequest(http.MethodGet, "/api/memberships/testKey", nil) + ctx.Request.Header.Set("Authorization", "Bearer someApiKey") + ctx.Request.Header.Set("SplitSDKVersion", "go-1.1.1") + ctx.Request.Header.Set("SplitSDKMachineIp", "1.2.3.4") + ctx.Request.Header.Set("SplitSDKMachineName", "ip-1-2-3-4") + router.ServeHTTP(resp, ctx.Request) + assert.Equal(t, 500, resp.Code) + + splitStorage.AssertExpectations(t) + splitFetcher.AssertExpectations(t) + segmentStorage.AssertExpectations(t) +} + type splitFetcherMock struct { mock.Mock } From 4cfa9415ecafcaf198b04e454294d0676f32adca Mon Sep 17 00:00:00 2001 From: Mauro Antonio Sanz Date: Fri, 4 Oct 2024 12:32:38 -0300 Subject: [PATCH 2/2] update commons dependecy --- go.mod | 2 +- go.sum | 2 ++ splitio/proxy/controllers/sdk.go | 15 +++++++-------- splitio/proxy/controllers/sdk_test.go | 8 ++++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/go.mod b/go.mod index 2137b567..4bc9f20c 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/gin-gonic/gin v1.10.0 github.com/google/uuid v1.3.0 github.com/splitio/gincache v1.0.1 - github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003203711-098c0ea804b3 + github.com/splitio/go-split-commons/v6 v6.0.2-0.20241004152517-7bdd98db88c9 github.com/splitio/go-toolkit/v5 v5.4.0 github.com/stretchr/testify v1.9.0 go.etcd.io/bbolt v1.3.6 diff --git a/go.sum b/go.sum index e713f5a9..16bffb7a 100644 --- a/go.sum +++ b/go.sum @@ -97,6 +97,8 @@ github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003202846-c19d3164beda h1:t github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003202846-c19d3164beda/go.mod h1:TsvIh3XP7yjc7ly4vpj06AkoBND36SodPs5qfhb8rHc= github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003203711-098c0ea804b3 h1:S3h7x9d11SRMW8S9OtL9EPOEcrT6dD2jLoozq6kWes4= github.com/splitio/go-split-commons/v6 v6.0.2-0.20241003203711-098c0ea804b3/go.mod h1:TsvIh3XP7yjc7ly4vpj06AkoBND36SodPs5qfhb8rHc= +github.com/splitio/go-split-commons/v6 v6.0.2-0.20241004152517-7bdd98db88c9 h1:ohS89uGBqOu7Yk0+mbYMbilHCEgAXDrPOatzKouibIA= +github.com/splitio/go-split-commons/v6 v6.0.2-0.20241004152517-7bdd98db88c9/go.mod h1:TsvIh3XP7yjc7ly4vpj06AkoBND36SodPs5qfhb8rHc= github.com/splitio/go-toolkit/v5 v5.4.0 h1:g5WFpRhQomnXCmvfsNOWV4s5AuUrWIZ+amM68G8NBKM= github.com/splitio/go-toolkit/v5 v5.4.0/go.mod h1:xYhUvV1gga9/1029Wbp5pjnR6Cy8nvBpjw99wAbsMko= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/splitio/proxy/controllers/sdk.go b/splitio/proxy/controllers/sdk.go index 96df7b5e..65bff306 100644 --- a/splitio/proxy/controllers/sdk.go +++ b/splitio/proxy/controllers/sdk.go @@ -151,18 +151,17 @@ func (c *SdkServerController) Memberships(ctx *gin.Context) { ctx.JSON(http.StatusInternalServerError, gin.H{}) } - mySegments := make([]dtos.MemItem, 0, len(segmentList)) + mySegments := make([]dtos.Segment, 0, len(segmentList)) for _, segmentName := range segmentList { - mySegments = append(mySegments, dtos.MemItem{Name: segmentName}) + mySegments = append(mySegments, dtos.Segment{Name: segmentName}) } - payoad := dtos.MembershipsDTO{ - MySegments: dtos.Member{ - Keys: mySegments, + payoad := dtos.MembershipsResponseDTO{ + MySegments: dtos.Memberships{ + Segments: mySegments, }, - LargeSegments: dtos.Member{ - Keys: []dtos.MemItem{}, - ChangeNumber: 0, + MyLargeSegments: dtos.Memberships{ + Segments: []dtos.Segment{}, }, } diff --git a/splitio/proxy/controllers/sdk_test.go b/splitio/proxy/controllers/sdk_test.go index 87aa75e2..b87f6e44 100644 --- a/splitio/proxy/controllers/sdk_test.go +++ b/splitio/proxy/controllers/sdk_test.go @@ -575,13 +575,13 @@ func TestMemberships(t *testing.T) { body, err := io.ReadAll(resp.Body) assert.Nil(t, err) - var memberships dtos.MembershipsDTO + var memberships dtos.MembershipsResponseDTO err = json.Unmarshal(body, &memberships) assert.Nil(t, err) - assert.Equal(t, dtos.MembershipsDTO{ - MySegments: dtos.Member{Keys: []dtos.MemItem{{Name: "segment1"}, {Name: "segment2"}, {Name: "segmentTest"}}}, - LargeSegments: dtos.Member{Keys: []dtos.MemItem{}}, + assert.Equal(t, dtos.MembershipsResponseDTO{ + MySegments: dtos.Memberships{Segments: []dtos.Segment{{Name: "segment1"}, {Name: "segment2"}, {Name: "segmentTest"}}}, + MyLargeSegments: dtos.Memberships{Segments: []dtos.Segment{}}, }, memberships) splitStorage.AssertExpectations(t)