Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
sanzmauro committed Nov 26, 2024
1 parent 569561b commit 82a7dbb
Show file tree
Hide file tree
Showing 8 changed files with 127 additions and 9 deletions.
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.2-0.20241126190617-03ffbb3a100f
github.com/splitio/go-split-commons/v6 v6.0.2-0.20241125153044-959311072c68
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
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ 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.2-0.20241126190617-03ffbb3a100f h1:FbR7KHn2kdtBda7CZVxut2qfFH7ZI4XW+FV6B0JpWgM=
github.com/splitio/go-split-commons/v6 v6.0.2-0.20241126190617-03ffbb3a100f/go.mod h1:D/XIY/9Hmfk9ivWsRsJVp439kEdmHbzUi3PKzQQDOXY=
github.com/splitio/go-split-commons/v6 v6.0.2-0.20241125153044-959311072c68 h1:Nr48cVYJZCOQzfKPGPsYcHykzEa4M/ADPkzO+eo3GOI=
github.com/splitio/go-split-commons/v6 v6.0.2-0.20241125153044-959311072c68/go.mod h1:D/XIY/9Hmfk9ivWsRsJVp439kEdmHbzUi3PKzQQDOXY=
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
1 change: 1 addition & 0 deletions splitio/admin/common/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ type Storages struct {
EventStorage storage.EventMultiSdkConsumer
ImpressionStorage storage.ImpressionMultiSdkConsumer
UniqueKeysStorage storage.UniqueKeysMultiSdkConsumer
LargeSegmentStorage storage.LargeSegmentsStorage
}
3 changes: 2 additions & 1 deletion splitio/proxy/conf/sections.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ type Main struct {
Logging conf.Logging `json:"logging" s-nested:"true"`
Healthcheck Healthcheck `json:"healthcheck" s-nested:"true"`
Observability Observability `json:"observability" s-nested:"true"`
FlagSpecVersion string `json:"flagSpecVersion" s-cli:"flag-spec-version" s-def:"1.1" s-desc:"Spec version for flags"`
FlagSpecVersion string `json:"flagSpecVersion" s-cli:"flag-spec-version" s-def:"1.2" s-desc:"Spec version for flags"`
LargeSegmentVersion string `json:"largeSegmentVersion" s-cli:"large-segment-version" s-def:"1.0" s-desc:"Spec version for large segments"`
}

// BuildAdvancedConfig generates a commons-compatible advancedconfig with default + overriden parameters
Expand Down
38 changes: 38 additions & 0 deletions splitio/proxy/controllers/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"github.com/splitio/go-split-commons/v6/engine/validator"
"github.com/splitio/go-split-commons/v6/service"
"github.com/splitio/go-split-commons/v6/service/api/specs"
cmnStorage "github.com/splitio/go-split-commons/v6/storage"
"github.com/splitio/go-toolkit/v5/logging"
"golang.org/x/exp/slices"

Expand All @@ -28,6 +29,7 @@ type SdkServerController struct {
proxySegmentStorage storage.ProxySegmentStorage
fsmatcher flagsets.FlagSetMatcher
versionFilter specs.SplitVersionFilter
largeSegmentStorage cmnStorage.LargeSegmentsStorage
}

// NewSdkServerController instantiates a new sdk server controller
Expand All @@ -37,6 +39,7 @@ func NewSdkServerController(
proxySplitStorage storage.ProxySplitStorage,
proxySegmentStorage storage.ProxySegmentStorage,
fsmatcher flagsets.FlagSetMatcher,
largeSegmentStorage cmnStorage.LargeSegmentsStorage,

) *SdkServerController {
return &SdkServerController{
Expand All @@ -46,6 +49,7 @@ func NewSdkServerController(
proxySegmentStorage: proxySegmentStorage,
fsmatcher: fsmatcher,
versionFilter: specs.NewSplitVersionFilter(),
largeSegmentStorage: largeSegmentStorage,
}
}

Expand All @@ -54,6 +58,40 @@ 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)
}

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

lsList := c.largeSegmentStorage.LargeSegmentsForUser(key)
myLargeSegments := make([]dtos.Segment, 0, len(lsList))
for _, name := range lsList {
myLargeSegments = append(myLargeSegments, dtos.Segment{Name: name})
}

payoad := dtos.MembershipsResponseDTO{
MySegments: dtos.Memberships{
Segments: mySegments,
},
MyLargeSegments: dtos.Memberships{
Segments: myLargeSegments,
},
}

ctx.JSON(http.StatusOK, payoad)
ctx.Set(caching.SurrogateContextKey, nil)
}

// SplitChanges Returns a diff containing changes in feature flags from a certain point in time until now.
Expand Down
63 changes: 59 additions & 4 deletions splitio/proxy/controllers/sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
"github.com/splitio/go-split-commons/v6/engine/grammar/matchers"
"github.com/splitio/go-split-commons/v6/service"
"github.com/splitio/go-split-commons/v6/service/api/specs"
cmnStorage "github.com/splitio/go-split-commons/v6/storage"
"github.com/splitio/go-toolkit/v5/logging"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
Expand All @@ -33,6 +34,7 @@ func TestSplitChangesRecentSince(t *testing.T) {
Once()

var splitFetcher splitFetcherMock
var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
Expand All @@ -44,6 +46,7 @@ func TestSplitChangesRecentSince(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(false, nil),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand Down Expand Up @@ -83,6 +86,8 @@ func TestSplitChangesOlderSince(t *testing.T) {
Return(&dtos.SplitChangesDTO{Since: -1, Till: 1, Splits: []dtos.SplitDTO{{Name: "s1", Status: "ACTIVE"}, {Name: "s2", Status: "ACTIVE"}}}, nil).
Once()

var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)

Expand All @@ -95,6 +100,7 @@ func TestSplitChangesOlderSince(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(false, nil),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand Down Expand Up @@ -134,6 +140,8 @@ func TestSplitChangesOlderSinceFetchFails(t *testing.T) {
Return((*dtos.SplitChangesDTO)(nil), errors.New("something")).
Once()

var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)

Expand All @@ -146,6 +154,7 @@ func TestSplitChangesOlderSinceFetchFails(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(false, nil),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand All @@ -171,6 +180,7 @@ func TestSplitChangesWithFlagSets(t *testing.T) {
Once()

var splitFetcher splitFetcherMock
var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
Expand All @@ -184,6 +194,7 @@ func TestSplitChangesWithFlagSets(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(false, nil),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand Down Expand Up @@ -218,6 +229,7 @@ func TestSplitChangesWithFlagSetsStrict(t *testing.T) {
Once()

var splitFetcher splitFetcherMock
var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
Expand All @@ -231,6 +243,7 @@ func TestSplitChangesWithFlagSetsStrict(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(true, []string{"a", "c"}),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand Down Expand Up @@ -285,6 +298,7 @@ func TestSplitChangesNewMatcherOldSpec(t *testing.T) {
Once()

var splitFetcher splitFetcherMock
var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
Expand All @@ -296,6 +310,7 @@ func TestSplitChangesNewMatcherOldSpec(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(false, nil),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand Down Expand Up @@ -353,6 +368,7 @@ func TestSplitChangesNewMatcherNewSpec(t *testing.T) {
Once()

var splitFetcher splitFetcherMock
var largeSegmentStorageMock largeSegmentStorageMock

resp := httptest.NewRecorder()
ctx, router := gin.CreateTestContext(resp)
Expand All @@ -364,6 +380,7 @@ func TestSplitChangesNewMatcherNewSpec(t *testing.T) {
&splitStorage,
nil,
flagsets.NewMatcher(false, nil),
&largeSegmentStorageMock,
)
controller.Register(group)

Expand Down Expand Up @@ -408,13 +425,15 @@ func TestSegmentChanges(t *testing.T) {
Return(&dtos.SegmentChangesDTO{Name: "someSegment", Added: []string{"k1", "k2"}, Removed: []string{}, Since: -1, Till: 1}, nil).
Once()

var largeSegmentStorageMock largeSegmentStorageMock

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 := NewSdkServerController(logger, &splitFetcher, &splitStorage, &segmentStorage, flagsets.NewMatcher(false, nil), &largeSegmentStorageMock)
controller.Register(group)

ctx.Request, _ = http.NewRequest(http.MethodGet, "/api/segmentChanges/someSegment?since=-1", nil)
Expand Down Expand Up @@ -450,13 +469,15 @@ func TestSegmentChangesNotFound(t *testing.T) {
Return((*dtos.SegmentChangesDTO)(nil), storage.ErrSegmentNotFound).
Once()

var largeSegmentStorageMock largeSegmentStorageMock

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 := NewSdkServerController(logger, &splitFetcher, &splitStorage, &segmentStorage, flagsets.NewMatcher(false, nil), &largeSegmentStorageMock)
controller.Register(group)

ctx.Request, _ = http.NewRequest(http.MethodGet, "/api/segmentChanges/someSegment?since=-1", nil)
Expand All @@ -482,13 +503,15 @@ func TestMySegments(t *testing.T) {
Return([]string{"segment1", "segment2"}, nil).
Once()

var largeSegmentStorageMock largeSegmentStorageMock

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 := NewSdkServerController(logger, &splitFetcher, &splitStorage, &segmentStorage, flagsets.NewMatcher(false, nil), &largeSegmentStorageMock)
controller.Register(group)

ctx.Request, _ = http.NewRequest(http.MethodGet, "/api/mySegments/someKey", nil)
Expand Down Expand Up @@ -523,13 +546,15 @@ func TestMySegmentsError(t *testing.T) {
Return([]string(nil), errors.New("something")).
Once()

var largeSegmentStorageMock largeSegmentStorageMock

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 := NewSdkServerController(logger, &splitFetcher, &splitStorage, &segmentStorage, flagsets.NewMatcher(false, nil), &largeSegmentStorageMock)
controller.Register(group)

ctx.Request, _ = http.NewRequest(http.MethodGet, "/api/mySegments/someKey", nil)
Expand Down Expand Up @@ -563,4 +588,34 @@ type MSC struct {
MySegments []dtos.MySegmentDTO `json:"mySegments"`
}

// --
type largeSegmentStorageMock struct {
mock.Mock
}

func (s *largeSegmentStorageMock) SetChangeNumber(name string, till int64) {
s.Called()
}
func (s *largeSegmentStorageMock) Update(name string, userKeys []string, till int64) {
}
func (s *largeSegmentStorageMock) ChangeNumber(name string) int64 {
return s.Called(name).Get(0).(int64)
}
func (s *largeSegmentStorageMock) Count() int {
return s.Called().Get(0).(int)
}
func (s *largeSegmentStorageMock) LargeSegmentsForUser(userKey string) []string {
return s.Called(userKey).Get(0).([]string)
}
func (s *largeSegmentStorageMock) IsInLargeSegment(name string, key string) (bool, error) {
args := s.Called(name, key)
return args.Get(0).(bool), args.Error(1)
}
func (s *largeSegmentStorageMock) TotalKeys(name string) int {
return s.Called(name).Get(0).(int)
}

// --

var _ cmnStorage.LargeSegmentsStorage = (*largeSegmentStorageMock)(nil)
var _ service.SplitFetcher = (*splitFetcherMock)(nil)
Loading

0 comments on commit 82a7dbb

Please sign in to comment.