Skip to content

Commit 30a11a1

Browse files
committed
Added dto and updated client and engine classes
1 parent e570e23 commit 30a11a1

File tree

46 files changed

+1098
-183
lines changed

Some content is hidden

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

46 files changed

+1098
-183
lines changed

client/src/main/java/io/split/Spec.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ private Spec() {
66
// restrict instantiation
77
}
88

9-
public static final String SPEC_VERSION = "1.1";
9+
public static String SPEC_VERSION = "1.3";
10+
public static final String SPEC_1_3 = "1.3";
11+
public static final String SPEC_1_1 = "1.1";
1012
}
1113

client/src/main/java/io/split/client/HttpSplitChangeFetcher.java

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import com.google.common.annotations.VisibleForTesting;
44

5+
import io.split.Spec;
56
import io.split.client.dtos.SplitChange;
67
import io.split.client.dtos.SplitHttpResponse;
78
import io.split.client.exceptions.UriTooLongException;
@@ -31,6 +32,7 @@ public final class HttpSplitChangeFetcher implements SplitChangeFetcher {
3132
private static final Logger _log = LoggerFactory.getLogger(HttpSplitChangeFetcher.class);
3233

3334
private static final String SINCE = "since";
35+
private static final String RB_SINCE = "rbSince";
3436
private static final String TILL = "till";
3537
private static final String SETS = "sets";
3638
private static final String SPEC = "s";
@@ -56,38 +58,48 @@ long makeRandomTill() {
5658
}
5759

5860
@Override
59-
public SplitChange fetch(long since, FetchOptions options) {
61+
public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {
6062

6163
long start = System.currentTimeMillis();
64+
for (int i=0; i<2; i++) {
65+
try {
66+
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SPEC, "" + SPEC_VERSION);
67+
uriBuilder.addParameter(SINCE, "" + since);
68+
if (SPEC_VERSION.equals(Spec.SPEC_1_3)) {
69+
uriBuilder.addParameter(RB_SINCE, "" + sinceRBS);
70+
}
71+
if (!options.flagSetsFilter().isEmpty()) {
72+
uriBuilder.addParameter(SETS, "" + options.flagSetsFilter());
73+
}
74+
if (options.hasCustomCN()) {
75+
uriBuilder.addParameter(TILL, "" + options.targetCN());
76+
}
77+
URI uri = uriBuilder.build();
78+
SplitHttpResponse response = _client.get(uri, options, null);
6279

63-
try {
64-
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SPEC, "" + SPEC_VERSION);
65-
uriBuilder.addParameter(SINCE, "" + since);
66-
if (!options.flagSetsFilter().isEmpty()) {
67-
uriBuilder.addParameter(SETS, "" + options.flagSetsFilter());
68-
}
69-
if (options.hasCustomCN()) {
70-
uriBuilder.addParameter(TILL, "" + options.targetCN());
71-
}
72-
URI uri = uriBuilder.build();
73-
SplitHttpResponse response = _client.get(uri, options, null);
74-
75-
if (response.statusCode() < HttpStatus.SC_OK || response.statusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
76-
if (response.statusCode() == HttpStatus.SC_REQUEST_URI_TOO_LONG) {
77-
_log.error("The amount of flag sets provided are big causing uri length error.");
78-
throw new UriTooLongException(String.format("Status code: %s. Message: %s", response.statusCode(), response.statusMessage()));
80+
if (response.statusCode() < HttpStatus.SC_OK || response.statusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
81+
if (response.statusCode() == HttpStatus.SC_REQUEST_URI_TOO_LONG) {
82+
_log.error("The amount of flag sets provided are big causing uri length error.");
83+
throw new UriTooLongException(String.format("Status code: %s. Message: %s", response.statusCode(), response.statusMessage()));
84+
}
85+
if (response.statusCode() == HttpStatus.SC_BAD_REQUEST && response.statusMessage().equals("unknown spec")) {
86+
_log.warn(String.format("Detected old spec response, falling back to spec 1.1"));
87+
SPEC_VERSION = Spec.SPEC_1_1;
88+
continue;
89+
}
90+
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.SPLIT_SYNC, response.statusCode());
91+
throw new IllegalStateException(
92+
String.format("Could not retrieve splitChanges since %s; http return code %s", since, response.statusCode())
93+
);
7994
}
80-
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.SPLIT_SYNC, response.statusCode());
81-
throw new IllegalStateException(
82-
String.format("Could not retrieve splitChanges since %s; http return code %s", since, response.statusCode())
83-
);
95+
return Json.fromJson(response.body(), SplitChange.class);
96+
} catch (Exception e) {
97+
throw new IllegalStateException(String.format("Problem fetching splitChanges since %s: %s", since, e), e);
98+
} finally {
99+
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.SPLITS, System.currentTimeMillis() - start);
84100
}
85-
return Json.fromJson(response.body(), SplitChange.class);
86-
} catch (Exception e) {
87-
throw new IllegalStateException(String.format("Problem fetching splitChanges since %s: %s", since, e), e);
88-
} finally {
89-
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.SPLITS, System.currentTimeMillis()-start);
90101
}
102+
return null;
91103
}
92104

93105
@VisibleForTesting

client/src/main/java/io/split/client/JsonLocalhostSplitChangeFetcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public JsonLocalhostSplitChangeFetcher(InputStreamProvider inputStreamProvider)
2929
}
3030

3131
@Override
32-
public SplitChange fetch(long since, FetchOptions options) {
32+
public SplitChange fetch(long since, long RBsince, FetchOptions options) {
3333
try {
3434
JsonReader jsonReader = new JsonReader(new BufferedReader(new InputStreamReader(_inputStreamProvider.get(), StandardCharsets.UTF_8)));
3535
SplitChange splitChange = Json.fromJson(jsonReader, SplitChange.class);

client/src/main/java/io/split/client/LegacyLocalhostSplitChangeFetcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public LegacyLocalhostSplitChangeFetcher(String directory) {
3434
}
3535

3636
@Override
37-
public SplitChange fetch(long since, FetchOptions options) {
37+
public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {
3838

3939
try (BufferedReader reader = new BufferedReader(new FileReader(_splitFile))) {
4040
SplitChange splitChange = new SplitChange();

client/src/main/java/io/split/client/SplitFactoryImpl.java

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
import io.split.engine.experiments.SplitFetcher;
5454
import io.split.engine.experiments.SplitFetcherImp;
5555
import io.split.engine.experiments.SplitParser;
56+
import io.split.engine.experiments.RuleBasedSegmentParser;
5657
import io.split.engine.experiments.SplitSynchronizationTask;
5758
import io.split.engine.segments.SegmentChangeFetcher;
5859
import io.split.engine.segments.SegmentSynchronizationTaskImp;
@@ -66,8 +67,11 @@
6667
import io.split.storages.SplitCache;
6768
import io.split.storages.SplitCacheConsumer;
6869
import io.split.storages.SplitCacheProducer;
70+
import io.split.storages.RuleBasedSegmentCacheConsumer;
71+
import io.split.storages.RuleBasedSegmentCache;
6972
import io.split.storages.enums.OperationMode;
7073
import io.split.storages.memory.InMemoryCacheImp;
74+
import io.split.storages.memory.RuleBasedSegmentCacheInMemoryImp;
7175
import io.split.storages.memory.SegmentCacheInMemoryImpl;
7276
import io.split.storages.pluggable.adapters.UserCustomEventAdapterProducer;
7377
import io.split.storages.pluggable.adapters.UserCustomImpressionAdapterConsumer;
@@ -123,8 +127,7 @@
123127
public class SplitFactoryImpl implements SplitFactory {
124128
private static final org.slf4j.Logger _log = LoggerFactory.getLogger(SplitFactoryImpl.class);
125129
private static final String LEGACY_LOG_MESSAGE = "The sdk initialize in localhost mode using Legacy file. The splitFile or "
126-
+
127-
"inputStream doesn't add it to the config.";
130+
+ "inputStream were not added to the config.";
128131
private final static long SSE_CONNECT_TIMEOUT = 30000;
129132
private final static long SSE_SOCKET_TIMEOUT = 70000;
130133

@@ -204,6 +207,7 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
204207
SegmentCache segmentCache = new SegmentCacheInMemoryImpl();
205208
FlagSetsFilter flagSetsFilter = new FlagSetsFilterImpl(config.getSetsFilter());
206209
SplitCache splitCache = new InMemoryCacheImp(flagSetsFilter);
210+
RuleBasedSegmentCache ruleBasedSegmentCache = new RuleBasedSegmentCacheInMemoryImp();
207211
ImpressionsStorage impressionsStorage = new InMemoryImpressionsStorage(config.impressionsQueueSize());
208212
_splitCache = splitCache;
209213
_segmentCache = segmentCache;
@@ -215,8 +219,11 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
215219
_segmentSynchronizationTaskImp = buildSegments(config, segmentCache, splitCache);
216220

217221
SplitParser splitParser = new SplitParser();
222+
RuleBasedSegmentParser ruleBasedSegmentParser = new RuleBasedSegmentParser();
223+
218224
// SplitFetcher
219-
_splitFetcher = buildSplitFetcher(splitCache, splitParser, flagSetsFilter);
225+
_splitFetcher = buildSplitFetcher(splitCache, splitParser, flagSetsFilter, ruleBasedSegmentParser, ruleBasedSegmentCache);
226+
220227

221228
// SplitSynchronizationTask
222229
_splitSynchronizationTask = new SplitSynchronizationTask(_splitFetcher,
@@ -244,7 +251,7 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
244251
config.getThreadFactory());
245252

246253
// Evaluator
247-
_evaluator = new EvaluatorImp(splitCache, segmentCache);
254+
_evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache);
248255

249256
// SplitClient
250257
_client = new SplitClientImpl(this,
@@ -301,6 +308,9 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor
301308
customStorageWrapper);
302309
UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(
303310
customStorageWrapper);
311+
// TODO Update the instance to UserCustomRuleBasedSegmentAdapterConsumer
312+
RuleBasedSegmentCacheConsumer userCustomRuleBasedSegmentAdapterConsumer = new RuleBasedSegmentCacheInMemoryImp();
313+
304314
// TODO migrate impressions sender to Task instead manager and not instantiate
305315
// Producer here.
306316
UserCustomImpressionAdapterConsumer userCustomImpressionAdapterConsumer = new UserCustomImpressionAdapterConsumer();
@@ -333,7 +343,7 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor
333343
_gates = new SDKReadinessGates();
334344

335345
_telemetrySynchronizer = new TelemetryConsumerSubmitter(customStorageWrapper, _sdkMetadata);
336-
_evaluator = new EvaluatorImp(userCustomSplitAdapterConsumer, userCustomSegmentAdapterConsumer);
346+
_evaluator = new EvaluatorImp(userCustomSplitAdapterConsumer, userCustomSegmentAdapterConsumer, userCustomRuleBasedSegmentAdapterConsumer);
337347
_impressionsSender = PluggableImpressionSender.create(customStorageWrapper);
338348
_uniqueKeysTracker = createUniqueKeysTracker(config);
339349
_impressionsManager = buildImpressionsManager(config, userCustomImpressionAdapterConsumer,
@@ -391,6 +401,7 @@ protected SplitFactoryImpl(SplitClientConfig config) {
391401

392402
SegmentCache segmentCache = new SegmentCacheInMemoryImpl();
393403
FlagSetsFilter flagSetsFilter = new FlagSetsFilterImpl(config.getSetsFilter());
404+
RuleBasedSegmentCache ruleBasedSegmentCache = new RuleBasedSegmentCacheInMemoryImp();
394405
SplitCache splitCache = new InMemoryCacheImp(flagSetsFilter);
395406
_splitCache = splitCache;
396407
_gates = new SDKReadinessGates();
@@ -413,10 +424,11 @@ protected SplitFactoryImpl(SplitClientConfig config) {
413424

414425
// SplitFetcher
415426
SplitChangeFetcher splitChangeFetcher = createSplitChangeFetcher(config);
427+
RuleBasedSegmentParser ruleBasedSegmentParser = new RuleBasedSegmentParser();
416428
SplitParser splitParser = new SplitParser();
417429

418430
_splitFetcher = new SplitFetcherImp(splitChangeFetcher, splitParser, splitCache, _telemetryStorageProducer,
419-
flagSetsFilter);
431+
flagSetsFilter, ruleBasedSegmentParser, ruleBasedSegmentCache);
420432

421433
// SplitSynchronizationTask
422434
_splitSynchronizationTask = new SplitSynchronizationTask(_splitFetcher, splitCache,
@@ -428,7 +440,7 @@ protected SplitFactoryImpl(SplitClientConfig config) {
428440
_impressionsManager, null, null, null);
429441

430442
// Evaluator
431-
_evaluator = new EvaluatorImp(splitCache, segmentCache);
443+
_evaluator = new EvaluatorImp(splitCache, segmentCache, ruleBasedSegmentCache);
432444

433445
EventsStorage eventsStorage = new NoopEventsStorageImp();
434446

@@ -609,11 +621,12 @@ private SegmentSynchronizationTaskImp buildSegments(SplitClientConfig config,
609621
}
610622

611623
private SplitFetcher buildSplitFetcher(SplitCacheProducer splitCacheProducer, SplitParser splitParser,
612-
FlagSetsFilter flagSetsFilter) throws URISyntaxException {
624+
FlagSetsFilter flagSetsFilter, RuleBasedSegmentParser ruleBasedSegmentParser,
625+
RuleBasedSegmentCache ruleBasedSegmentCache) throws URISyntaxException {
613626
SplitChangeFetcher splitChangeFetcher = HttpSplitChangeFetcher.create(_splitHttpClient, _rootTarget,
614627
_telemetryStorageProducer);
615628
return new SplitFetcherImp(splitChangeFetcher, splitParser, splitCacheProducer, _telemetryStorageProducer,
616-
flagSetsFilter);
629+
flagSetsFilter,ruleBasedSegmentParser, ruleBasedSegmentCache);
617630
}
618631

619632
private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config,

client/src/main/java/io/split/client/YamlLocalhostSplitChangeFetcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ public YamlLocalhostSplitChangeFetcher(InputStreamProvider inputStreamProvider)
3232
}
3333

3434
@Override
35-
public SplitChange fetch(long since, FetchOptions options) {
35+
public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {
3636
try {
3737
Yaml yaml = new Yaml();
3838
List<Map<String, Map<String, Object>>> yamlSplits = yaml.load(_inputStreamProvider.get());
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package io.split.client.dtos;
2+
3+
import java.util.List;
4+
5+
public class Excluded {
6+
public List<String> keys;
7+
public List<String> segments;
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package io.split.client.dtos;
2+
3+
import java.util.List;
4+
5+
public class RuleBasedSegment {
6+
public String name;
7+
public Status status;
8+
public String trafficTypeName;
9+
public long changeNumber;
10+
public List<Condition> conditions;
11+
public Excluded excluded;
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package io.split.client.dtos;
2+
3+
import java.util.List;
4+
5+
public class RuleBasedSegmentChange {
6+
public List<RuleBasedSegment> ruleBasedSegments;
7+
public long since;
8+
public long till;
9+
}

client/src/main/java/io/split/client/dtos/SplitChange.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,7 @@ public class SplitChange {
66
public List<Split> splits;
77
public long since;
88
public long till;
9+
public List<RuleBasedSegment> ruleBasedSegments;
10+
public long sinceRBS;
11+
public long tillRBS;
912
}

0 commit comments

Comments
 (0)