Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Proxy] Support for Memberships endpoint - First iteration #286

Draft
wants to merge 2 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -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.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
Expand Down
8 changes: 6 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,12 @@ 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-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=
Expand Down
2 changes: 1 addition & 1 deletion splitio/commitversion.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
29 changes: 29 additions & 0 deletions splitio/proxy/controllers/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -140,6 +141,34 @@ 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.Segment, 0, len(segmentList))
for _, segmentName := range segmentList {
mySegments = append(mySegments, dtos.Segment{Name: segmentName})
}

payoad := dtos.MembershipsResponseDTO{
MySegments: dtos.Memberships{
Segments: mySegments,
},
MyLargeSegments: dtos.Memberships{
Segments: []dtos.Segment{},
},
}

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 {
Expand Down
76 changes: 76 additions & 0 deletions splitio/proxy/controllers/sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.MembershipsResponseDTO
err = json.Unmarshal(body, &memberships)
assert.Nil(t, err)

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)
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
}
Expand Down