Skip to content

Commit da4af11

Browse files
authored
Merge pull request #323 from splitio/task/commons_v8
2 parents 8f881d7 + a00f165 commit da4af11

97 files changed

Lines changed: 1935 additions & 498 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGES.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
5.11.0 (Nov 12, 2025)
2+
- Split Proxy:
3+
- Added support for rule-based segment. These segments determine membership at runtime by evaluating their configured rules against the user attributes provided to the SDK.
4+
- Split-Sync:
5+
- Added support for rule-based segment. These segments determine membership at runtime by evaluating their configured rules against the user attributes provided to the SDK.
6+
- Fixed vulnerabilities:
7+
- Updated golang image to 1.24.9
8+
19
5.10.4 (Oct 3, 2025)
210
- Fixed vulnerabilities:
311
- Updated golang image to 1.24.7

docker/Dockerfile.proxy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Build stage
2-
FROM golang:1.24.7-bookworm AS builder
2+
FROM golang:1.24.9-bookworm AS builder
33

44
ARG EXTRA_BUILD_ARGS
55
ARG FIPS_MODE

docker/Dockerfile.synchronizer

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# Build stage
2-
FROM golang:1.24.7-bookworm AS builder
2+
FROM golang:1.24.9-bookworm AS builder
33

44
ARG EXTRA_BUILD_ARGS
55
ARG FIPS_MODE

go.mod

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ require (
88
github.com/gin-gonic/gin v1.10.1
99
github.com/google/uuid v1.3.0
1010
github.com/splitio/gincache v1.0.1
11-
github.com/splitio/go-split-commons/v6 v6.1.0
12-
github.com/splitio/go-toolkit/v5 v5.4.0
13-
github.com/stretchr/testify v1.10.0
11+
github.com/splitio/go-split-commons/v8 v8.0.0
12+
github.com/splitio/go-toolkit/v5 v5.4.1
13+
github.com/stretchr/testify v1.11.1
1414
go.etcd.io/bbolt v1.3.6
1515
golang.org/x/exp v0.0.0-20231006140011-7918f672742d
1616
)

go.sum

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,10 +74,10 @@ github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUA
7474
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
7575
github.com/splitio/gincache v1.0.1 h1:dLYdANY/BqH4KcUMCe/LluLyV5WtuE/LEdQWRE06IXU=
7676
github.com/splitio/gincache v1.0.1/go.mod h1:CcgJDSM9Af75kyBH0724v55URVwMBuSj5x1eCWIOECY=
77-
github.com/splitio/go-split-commons/v6 v6.1.0 h1:k3mwr12DF6gbEaV8XXU/tSAQlPkIEuzIgTEneYhGg2I=
78-
github.com/splitio/go-split-commons/v6 v6.1.0/go.mod h1:D/XIY/9Hmfk9ivWsRsJVp439kEdmHbzUi3PKzQQDOXY=
79-
github.com/splitio/go-toolkit/v5 v5.4.0 h1:g5WFpRhQomnXCmvfsNOWV4s5AuUrWIZ+amM68G8NBKM=
80-
github.com/splitio/go-toolkit/v5 v5.4.0/go.mod h1:xYhUvV1gga9/1029Wbp5pjnR6Cy8nvBpjw99wAbsMko=
77+
github.com/splitio/go-split-commons/v8 v8.0.0 h1:wLk5eT6WU2LfxtaWG3ZHlTbNMGWP2eYsZTb1o+tFpkI=
78+
github.com/splitio/go-split-commons/v8 v8.0.0/go.mod h1:vgRGPn0s4RC9/zp1nIn4KeeIEj/K3iXE2fxYQbCk/WI=
79+
github.com/splitio/go-toolkit/v5 v5.4.1 h1:srTyvDBJZMUcJ/KiiQDMyjCuELVgTBh2TGRVn0sOXEE=
80+
github.com/splitio/go-toolkit/v5 v5.4.1/go.mod h1:SifzysrOVDbzMcOE8zjX02+FG5az4FrR3Us/i5SeStw=
8181
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
8282
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
8383
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@@ -87,8 +87,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
8787
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
8888
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
8989
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
90-
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
91-
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
90+
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
91+
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
9292
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
9393
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
9494
github.com/twmb/murmur3 v1.1.6 h1:mqrRot1BRxm+Yct+vavLMou2/iJt0tNVTTC0QoIjaZg=

splitio/admin/admin.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ type Options struct {
4141
FullConfig interface{}
4242
FlagSpecVersion string
4343
LargeSegmentVersion string
44+
Hash string
4445
}
4546

4647
type AdminServer struct {
@@ -96,7 +97,7 @@ func NewServer(options *Options) (*AdminServer, error) {
9697
observabilityController.Register(admin)
9798

9899
if options.Snapshotter != nil {
99-
snapshotController := controllers.NewSnapshotController(options.Logger, options.Snapshotter)
100+
snapshotController := controllers.NewSnapshotController(options.Logger, options.Snapshotter, options.Hash)
100101
snapshotController.Register(admin)
101102
}
102103

splitio/admin/common/config.go

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,28 @@
11
package common
22

3-
import "github.com/splitio/go-split-commons/v6/storage"
3+
import (
4+
"github.com/splitio/go-split-commons/v8/engine/grammar/constants"
5+
"github.com/splitio/go-split-commons/v8/storage"
6+
)
7+
8+
var ProducerFeatureFlagsRules = []string{constants.MatcherTypeAllKeys, constants.MatcherTypeInSegment, constants.MatcherTypeWhitelist, constants.MatcherTypeEqualTo, constants.MatcherTypeGreaterThanOrEqualTo, constants.MatcherTypeLessThanOrEqualTo, constants.MatcherTypeBetween,
9+
constants.MatcherTypeEqualToSet, constants.MatcherTypePartOfSet, constants.MatcherTypeContainsAllOfSet, constants.MatcherTypeContainsAnyOfSet, constants.MatcherTypeStartsWith, constants.MatcherTypeEndsWith, constants.MatcherTypeContainsString, constants.MatcherTypeInSplitTreatment,
10+
constants.MatcherTypeEqualToBoolean, constants.MatcherTypeMatchesString, constants.MatcherEqualToSemver, constants.MatcherTypeGreaterThanOrEqualToSemver, constants.MatcherTypeLessThanOrEqualToSemver, constants.MatcherTypeBetweenSemver, constants.MatcherTypeInListSemver,
11+
constants.MatcherTypeInRuleBasedSegment}
12+
13+
var ProducerRuleBasedSegmentRules = []string{constants.MatcherTypeAllKeys, constants.MatcherTypeInSegment, constants.MatcherTypeWhitelist, constants.MatcherTypeEqualTo, constants.MatcherTypeGreaterThanOrEqualTo, constants.MatcherTypeLessThanOrEqualTo, constants.MatcherTypeBetween,
14+
constants.MatcherTypeEqualToSet, constants.MatcherTypePartOfSet, constants.MatcherTypeContainsAllOfSet, constants.MatcherTypeContainsAnyOfSet, constants.MatcherTypeStartsWith, constants.MatcherTypeEndsWith, constants.MatcherTypeContainsString,
15+
constants.MatcherTypeEqualToBoolean, constants.MatcherTypeMatchesString, constants.MatcherEqualToSemver, constants.MatcherTypeGreaterThanOrEqualToSemver, constants.MatcherTypeLessThanOrEqualToSemver, constants.MatcherTypeBetweenSemver, constants.MatcherTypeInListSemver,
16+
constants.MatcherTypeInRuleBasedSegment}
417

518
// Storages wraps storages in one struct
619
type Storages struct {
7-
SplitStorage storage.SplitStorage
8-
SegmentStorage storage.SegmentStorage
9-
LocalTelemetryStorage storage.TelemetryRuntimeConsumer
10-
EventStorage storage.EventMultiSdkConsumer
11-
ImpressionStorage storage.ImpressionMultiSdkConsumer
12-
UniqueKeysStorage storage.UniqueKeysMultiSdkConsumer
13-
LargeSegmentStorage storage.LargeSegmentsStorage
20+
SplitStorage storage.SplitStorage
21+
SegmentStorage storage.SegmentStorage
22+
LocalTelemetryStorage storage.TelemetryRuntimeConsumer
23+
EventStorage storage.EventMultiSdkConsumer
24+
ImpressionStorage storage.ImpressionMultiSdkConsumer
25+
UniqueKeysStorage storage.UniqueKeysMultiSdkConsumer
26+
LargeSegmentStorage storage.LargeSegmentsStorage
27+
RuleBasedSegmentsStorage storage.RuleBasedSegmentsStorage
1428
}

splitio/admin/controllers/dashboard.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ func (c *DashboardController) gatherStats() *dashboard.GlobalStats {
150150
FeatureFlags: bundleSplitInfo(c.storages.SplitStorage),
151151
Segments: bundleSegmentInfo(c.storages.SplitStorage, c.storages.SegmentStorage),
152152
LargeSegments: bundleLargeSegmentInfo(c.storages.SplitStorage, c.storages.LargeSegmentStorage),
153+
RuleBasedSegments: bundleRuleBasedInfo(c.storages.SplitStorage, c.storages.RuleBasedSegmentsStorage),
153154
Latencies: bundleProxyLatencies(c.storages.LocalTelemetryStorage),
154155
BackendLatencies: bundleLocalSyncLatencies(c.storages.LocalTelemetryStorage),
155156
ImpressionsQueueSize: getImpressionSize(c.storages.ImpressionStorage),

splitio/admin/controllers/helpers.go

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import (
55
"strings"
66
"time"
77

8-
"github.com/splitio/go-split-commons/v6/storage"
9-
"github.com/splitio/go-split-commons/v6/telemetry"
8+
"github.com/splitio/go-split-commons/v8/storage"
9+
"github.com/splitio/go-split-commons/v8/telemetry"
1010

1111
"github.com/splitio/split-synchronizer/v5/splitio/admin/views/dashboard"
1212
"github.com/splitio/split-synchronizer/v5/splitio/producer/evcalc"
@@ -108,6 +108,45 @@ func bundleSegmentInfo(splitStorage storage.SplitStorage, segmentStorage storage
108108
return summaries
109109
}
110110

111+
func bundleRuleBasedInfo(splitStorage storage.SplitStorage, ruleBasedSegmentStorage storage.RuleBasedSegmentStorageConsumer) []dashboard.RuleBasedSegmentSummary {
112+
names := splitStorage.RuleBasedSegmentNames()
113+
summaries := make([]dashboard.RuleBasedSegmentSummary, 0, names.Size())
114+
115+
for _, name := range names.List() {
116+
strName, ok := name.(string)
117+
if !ok {
118+
continue
119+
}
120+
121+
ruleBased, err := ruleBasedSegmentStorage.GetRuleBasedSegmentByName(strName)
122+
if err != nil {
123+
continue
124+
}
125+
126+
excluededSegments := make([]dashboard.ExcludedSegments, 0, len(ruleBased.Excluded.Segments))
127+
for _, excludedSegment := range ruleBased.Excluded.Segments {
128+
excluededSegments = append(excluededSegments, dashboard.ExcludedSegments{
129+
Name: excludedSegment.Name,
130+
Type: excludedSegment.Type,
131+
})
132+
}
133+
134+
if ruleBased.Excluded.Keys == nil {
135+
ruleBased.Excluded.Keys = make([]string, 0)
136+
}
137+
138+
summaries = append(summaries, dashboard.RuleBasedSegmentSummary{
139+
Name: ruleBased.Name,
140+
Active: ruleBased.Status == "ACTIVE",
141+
ExcludedKeys: ruleBased.Excluded.Keys,
142+
ExcludedSegments: excluededSegments,
143+
LastModified: time.Unix(0, ruleBased.ChangeNumber*int64(time.Millisecond)).UTC().Format(time.UnixDate),
144+
ChangeNumber: ruleBased.ChangeNumber,
145+
})
146+
}
147+
return summaries
148+
}
149+
111150
func bundleSegmentKeysInfo(name string, segmentStorage storage.SegmentStorageConsumer) []dashboard.SegmentKeySummary {
112151

113152
keys := segmentStorage.Keys(name)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package controllers
2+
3+
import (
4+
"testing"
5+
6+
"github.com/splitio/split-synchronizer/v5/splitio/admin/views/dashboard"
7+
8+
"github.com/splitio/go-split-commons/v8/dtos"
9+
"github.com/splitio/go-split-commons/v8/storage/mocks"
10+
"github.com/splitio/go-toolkit/v5/datastructures/set"
11+
12+
"github.com/stretchr/testify/assert"
13+
)
14+
15+
func TestBundleRBInfo(t *testing.T) {
16+
split := &mocks.SplitStorageMock{}
17+
split.On("RuleBasedSegmentNames").Return(set.NewSet("rb1", "rb2"), nil).Once()
18+
rb := &mocks.MockRuleBasedSegmentStorage{}
19+
rb.On("GetRuleBasedSegmentByName", "rb1").Return(&dtos.RuleBasedSegmentDTO{Name: "rb1", ChangeNumber: 1, Status: "ACTIVE", Excluded: dtos.ExcludedDTO{Keys: []string{"one"}}}, nil).Once()
20+
rb.On("GetRuleBasedSegmentByName", "rb2").Return(&dtos.RuleBasedSegmentDTO{Name: "rb2", ChangeNumber: 2, Status: "ARCHIVED"}, nil).Once()
21+
result := bundleRuleBasedInfo(split, rb)
22+
assert.Len(t, result, 2)
23+
assert.ElementsMatch(t, result, []dashboard.RuleBasedSegmentSummary{
24+
{Name: "rb1", ChangeNumber: 1, Active: true, ExcludedKeys: []string{"one"}, ExcludedSegments: []dashboard.ExcludedSegments{}, LastModified: "Thu Jan 1 00:00:00 UTC 1970"},
25+
{Name: "rb2", ChangeNumber: 2, Active: false, ExcludedKeys: []string{}, ExcludedSegments: []dashboard.ExcludedSegments{}, LastModified: "Thu Jan 1 00:00:00 UTC 1970"},
26+
})
27+
split.AssertExpectations(t)
28+
rb.AssertExpectations(t)
29+
}

0 commit comments

Comments
 (0)