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

[SDKS-8926] Memberships endpoint #293

Merged
merged 8 commits into from
Nov 28, 2024
Merged
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.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/common/conf/advanced.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ import (

// InitAdvancedOptions initializes an advanced config with default values + overriden urls.
func InitAdvancedOptions(proxy bool) *conf.AdvancedConfig {
advanced := conf.GetDefaultAdvancedConfig()

prefix := "SPLIT_SYNC_"
if proxy {
prefix = "SPLIT_PROXY_"
advanced.LargeSegment.Enable = true
}

advanced := conf.GetDefaultAdvancedConfig()
if envSdkURL := os.Getenv(prefix + "SDK_URL"); envSdkURL != "" {
advanced.SdkURL = envSdkURL
}
Expand Down
12 changes: 8 additions & 4 deletions 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:"largesegment-version" s-def:"1.0" s-desc:"Spec version for large segments"`
}

// BuildAdvancedConfig generates a commons-compatible advancedconfig with default + overriden parameters
Expand All @@ -32,6 +33,7 @@ func (m *Main) BuildAdvancedConfig() *cconf.AdvancedConfig {
tmp.StreamingEnabled = m.Sync.Advanced.StreamingEnabled
tmp.SplitsRefreshRate = int(m.Sync.SplitRefreshRateMs / 1000)
tmp.SegmentsRefreshRate = int(m.Sync.SegmentRefreshRateMs / 1000)
tmp.LargeSegment.LazyLoad = m.Sync.Advanced.LargeSegmentLazyLoad
return tmp
}

Expand Down Expand Up @@ -68,9 +70,10 @@ type Persistent struct {

// Sync configuration options
type Sync struct {
SplitRefreshRateMs int64 `json:"splitRefreshRateMs" s-cli:"split-refresh-rate-ms" s-def:"60000" s-desc:"How often to refresh feature flags"`
SegmentRefreshRateMs int64 `json:"segmentRefreshRateMs" s-cli:"segment-refresh-rate-ms" s-def:"60000" s-desc:"How often to refresh segments"`
Advanced AdvancedSync `json:"advanced" s-nested:"true"`
SplitRefreshRateMs int64 `json:"splitRefreshRateMs" s-cli:"split-refresh-rate-ms" s-def:"60000" s-desc:"How often to refresh feature flags"`
SegmentRefreshRateMs int64 `json:"segmentRefreshRateMs" s-cli:"segment-refresh-rate-ms" s-def:"60000" s-desc:"How often to refresh segments"`
LargeSegmentRefreshRateMs int64 `json:"largeSegmentRefreshRateMs" s-cli:"largesegment-refresh-rate-ms" s-def:"3600000" s-desc:"How often to refresh large segments"`
Advanced AdvancedSync `json:"advanced" s-nested:"true"`
}

// AdvancedSync configuration options
Expand All @@ -84,6 +87,7 @@ type AdvancedSync struct {
EventsWorkers int64 `json:"eventsWorkers" s-cli:"events-workers" s-def:"10" s-desc:"#workers to forward events to Split servers"`
TelemetryWorkers int64 `json:"telemetryWorkers" s-cli:"telemetry-workers" s-def:"10" s-desc:"#workers to forward telemetry to Split servers"`
InternalMetricsRateMs int64 `json:"internalTelemetryRateMs" s-cli:"internal-metrics-rate-ms" s-def:"3600000" s-desc:"How often to send internal metrics"`
LargeSegmentLazyLoad bool `json:"largeSegmentLazyLoad" s-cli:"largesegment-lazy-load" s-def:"false" s-desc:"On/Off Large Segment Lazy Load"`
}

// Healthcheck configuration options
Expand Down
39 changes: 39 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,41 @@ 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{})
return
}

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, []string{caching.LargeSegmentSurrogate})
}

// SplitChanges Returns a diff containing changes in feature flags from a certain point in time until now.
Expand Down
Loading