Skip to content

Release 4.16.0 #571

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

Merged
merged 148 commits into from
May 29, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
148 commits
Select commit Hold shift + click to select a range
2ff316f
Added models and updated spec
chillaq Apr 4, 2025
a93c858
updated spec
chillaq Apr 4, 2025
6fdf0b7
Merge pull request #539 from splitio/rbs-models
chillaq Apr 4, 2025
df6bc39
Added inmemory storage classes
chillaq Apr 5, 2025
f0d8819
Merge branch 'feature/rule-based-segment' into rbs-memory-storage
chillaq Apr 5, 2025
380bcc3
Updated Evaluator
chillaq Apr 7, 2025
d0b6f45
Updated Splitfetcher classes
chillaq Apr 10, 2025
f7bea94
Update client/src/main/java/io/split/client/SplitFactoryImpl.java
chillaq Apr 10, 2025
a9982a9
Added unit test for RBS matcher
chillaq Apr 10, 2025
b607793
Merge branch 'rbs-evaluator' of https://github.com/splitio/java-clien…
chillaq Apr 10, 2025
901761a
polish
chillaq Apr 10, 2025
062774c
Merge branch 'rbs-memory-storage' of https://github.com/splitio/java-…
chillaq Apr 10, 2025
cc9aaa1
Polish
chillaq Apr 10, 2025
d248562
Merge pull request #540 from splitio/rbs-memory-storage
chillaq Apr 10, 2025
22b8519
Added consumer classes
chillaq Apr 11, 2025
f7d6bee
Merge pull request #541 from splitio/rbs-evaluator
chillaq Apr 11, 2025
42e03ce
polish
chillaq Apr 11, 2025
038aa7c
polishing and updating tests
chillaq Apr 14, 2025
459ff37
polish
chillaq Apr 14, 2025
c6727a3
polish
chillaq Apr 15, 2025
7c68dfd
polish
chillaq Apr 15, 2025
9e82c38
Update client/src/main/java/io/split/engine/experiments/RuleBasedSegm…
chillaq Apr 15, 2025
75ef28f
Update client/src/main/java/io/split/engine/experiments/SplitFetcherI…
chillaq Apr 15, 2025
2d22426
Update client/src/main/java/io/split/engine/experiments/SplitFetcherI…
chillaq Apr 15, 2025
3d5b439
Update client/src/main/java/io/split/engine/experiments/SplitFetcherI…
chillaq Apr 15, 2025
efd2605
Update client/src/main/java/io/split/engine/experiments/SplitFetcherI…
chillaq Apr 15, 2025
368830a
Update client/src/main/java/io/split/engine/experiments/SplitFetcherI…
chillaq Apr 15, 2025
06d47e4
polish
chillaq Apr 15, 2025
da05139
Merge branch 'rbs-fetchers' into rbs-consumer
chillaq Apr 15, 2025
fa6c2af
polish
chillaq Apr 16, 2025
1d7e585
polish
chillaq Apr 16, 2025
f9abc5d
deleted RBS storage producer
chillaq Apr 16, 2025
815c9f3
Merge branch 'rbs-consumer' of https://github.com/splitio/java-client…
chillaq Apr 16, 2025
c0b49d1
Merge pull request #543 from splitio/rbs-fetchers
chillaq Apr 16, 2025
6f82e89
fix build
chillaq Apr 17, 2025
a68e2f6
Added RBS support for SSE classes
chillaq Apr 17, 2025
6aca626
Added RBS support to localhost
chillaq Apr 18, 2025
daa9e4a
added integration tests
chillaq Apr 22, 2025
fc0005d
Merge pull request #544 from splitio/rbs-consumer
chillaq Apr 22, 2025
eb88ecd
Merge branch 'feature/rule-based-segment' into rbs-sse
chillaq Apr 22, 2025
3ad6db9
Added old spec support in splitfetcher
chillaq Apr 22, 2025
9f835ab
Update client/src/main/java/io/split/engine/common/SynchronizerImp.java
chillaq Apr 23, 2025
73f1679
Update client/src/main/java/io/split/engine/common/SynchronizerImp.java
chillaq Apr 23, 2025
8a2e2f4
Update client/src/main/java/io/split/engine/sse/workers/FeatureFlagWo…
chillaq Apr 23, 2025
57777ab
Polish
chillaq Apr 23, 2025
652ea96
polish
chillaq Apr 23, 2025
56082ef
polish
chillaq Apr 23, 2025
f9dd3d5
polish
chillaq Apr 23, 2025
d6860b4
polish
chillaq Apr 23, 2025
bcf8014
polish
chillaq Apr 23, 2025
8cccfa6
polish
chillaq Apr 24, 2025
cfd6feb
updated storage, localhost and tests
chillaq Apr 24, 2025
5ab09fb
polish
chillaq Apr 25, 2025
5db3340
polish
chillaq Apr 25, 2025
f4c18eb
Merge pull request #547 from splitio/rbs-sse
chillaq Apr 25, 2025
b8029e2
Merge branch 'feature/rule-based-segment' into rbs-localhost
chillaq Apr 25, 2025
682ba45
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 25, 2025
fabf787
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 25, 2025
0b14464
Update client/src/main/java/io/split/client/dtos/SplitChangesOldPaylo…
chillaq Apr 25, 2025
b86ac75
Update client/src/main/java/io/split/client/SplitClientConfig.java
chillaq Apr 25, 2025
904ec28
polish
chillaq Apr 25, 2025
c8f8533
polish
chillaq Apr 25, 2025
94ac3ed
removed spec_version global var
chillaq Apr 25, 2025
9117c38
polish
chillaq Apr 25, 2025
f63699d
polish
chillaq Apr 25, 2025
6e12ff2
Merge branch 'rbs-localhost' into rbs-oldspec-fetcher
chillaq Apr 25, 2025
37a7f98
moved block
chillaq Apr 25, 2025
19e1b79
fixed tests
chillaq Apr 26, 2025
577addc
Merge pull request #548 from splitio/rbs-localhost
chillaq Apr 26, 2025
6d5ccb2
fix tests
chillaq Apr 26, 2025
06bf4b6
Merge branch 'rbs-oldspec-fetcher' of https://github.com/splitio/java…
chillaq Apr 26, 2025
4a07bc6
fix build error
chillaq Apr 26, 2025
0c9e297
Merge remote-tracking branch 'origin/rbs-oldspec-fetcher' into rbs-ol…
chillaq Apr 26, 2025
00402eb
resolve conflicts
chillaq Apr 26, 2025
fe83f0d
polish
chillaq Apr 27, 2025
8a6cdf1
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 28, 2025
0669fa1
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 28, 2025
de79368
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 28, 2025
65958cb
Merge pull request #549 from splitio/rbs-oldspec-fetcher
chillaq Apr 28, 2025
d96a62d
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 28, 2025
efa44fa
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 28, 2025
0af690d
polish
chillaq Apr 28, 2025
0cfee56
Merge branch 'feature/rule-based-segment' into rbs-oldspec-storage
chillaq Apr 28, 2025
c17372b
polish
chillaq Apr 28, 2025
39325f8
Update client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
chillaq Apr 28, 2025
67e770a
Merge pull request #551 from splitio/rbs-oldspec-storage
chillaq Apr 28, 2025
f49898d
bump version
sanzmauro Apr 28, 2025
4d54312
Merge pull request #552 from splitio/httpclient-vuln
sanzmauro Apr 28, 2025
2175dbe
fixing http client
sanzmauro Apr 28, 2025
5383a48
polish
sanzmauro Apr 28, 2025
2ff9552
polish
sanzmauro Apr 28, 2025
2dc5150
update log
sanzmauro Apr 28, 2025
ae9c911
Merge pull request #553 from splitio/fix/http-client-bad-request
sanzmauro Apr 28, 2025
df822cd
Fixed excluded null issue
chillaq Apr 29, 2025
d633f0a
Fixed segment sync
chillaq Apr 30, 2025
6b51bcb
Update client/src/main/java/io/split/engine/segments/SegmentSynchroni…
chillaq Apr 30, 2025
9c8d44a
Update client/src/test/java/io/split/engine/experiments/ParsedRuleBas…
chillaq Apr 30, 2025
1765280
Merge pull request #554 from splitio/rbs-fix-excludes
chillaq Apr 30, 2025
58a5be5
added getSegmentNames method
chillaq Apr 30, 2025
721fc2d
Merge pull request #555 from splitio/rbs-fix-segment-sync
chillaq Apr 30, 2025
bca3958
polish
chillaq Apr 30, 2025
1ffe622
fix empty arrays in excluded
chillaq Apr 30, 2025
0b2813d
added tests
chillaq Apr 30, 2025
1fae45f
Merge pull request #558 from splitio/rbs-fix-exlcuded-arrays
chillaq Apr 30, 2025
c966192
fixing excluded segments
sanzmauro Apr 30, 2025
281d406
Merge branch 'feature/rule-based-segment' into rbs-excluded-segments
sanzmauro Apr 30, 2025
1f9197b
fix tests
chillaq Apr 30, 2025
8431b8d
Merge pull request #559 from splitio/rbs-excluded-segments
chillaq Apr 30, 2025
af65cdc
fixing excluded segments
sanzmauro Apr 30, 2025
b043ffb
added tests
chillaq Apr 30, 2025
11978f6
Merge pull request #560 from splitio/excluded-rbs-segments
chillaq May 1, 2025
7a199f0
Added RBS tests
chillaq May 1, 2025
785dca5
fixing excluded rbs
sanzmauro May 2, 2025
c9ec506
fixing build
sanzmauro May 2, 2025
8277a14
Merge pull request #561 from splitio/fix-rbs-excluded
sanzmauro May 2, 2025
147393c
polish
sanzmauro May 2, 2025
b739b97
fixing segment names
sanzmauro May 16, 2025
c22003e
fix rbs toString
sanzmauro May 16, 2025
1acf543
Merge pull request #562 from splitio/fix-rbs-segment-names
sanzmauro May 16, 2025
e95def2
fix HttpSplitFetcher
sanzmauro May 21, 2025
4ae42b9
undo changes
sanzmauro May 21, 2025
919fc54
Merge pull request #564 from splitio/fix-http-split-fetcher
sanzmauro May 21, 2025
dcaa726
Added and updated DTOs
chillaq May 22, 2025
6e5286b
Added prereq matcher
chillaq May 23, 2025
d843920
polish
chillaq May 23, 2025
3d6800d
Merge pull request #565 from splitio/prereq-dtos
chillaq May 24, 2025
de8d76d
Merge pull request #566 from splitio/prereq-matcher
chillaq May 24, 2025
29a673b
Update Evaluator
chillaq May 27, 2025
c280a3e
updated test
chillaq May 27, 2025
affc36a
Merge branch 'development' into feature/rule-based-segment
chillaq May 27, 2025
32ea00d
polish
chillaq May 27, 2025
91b48ee
Merge pull request #567 from splitio/prereq-evaluator
chillaq May 27, 2025
f99c527
Fixed split view
chillaq May 27, 2025
8d67468
polishing
chillaq May 27, 2025
faedd48
polishing
chillaq May 27, 2025
08ce1f5
update test
chillaq May 27, 2025
6218697
polish
chillaq May 27, 2025
3fe5be3
Added integration test
chillaq May 28, 2025
285d29f
Rule-based Segments Implementation
sanzmauro May 28, 2025
553c1f0
update httpclient version
sanzmauro May 28, 2025
0da2e36
Merge pull request #568 from splitio/prereq-integration-test
chillaq May 28, 2025
aacfd86
Merge branch 'development' into feature/prerequisites
chillaq May 28, 2025
dca8fde
polish
chillaq May 28, 2025
ba2df25
polish
chillaq May 28, 2025
b5f0838
Merge pull request #569 from splitio/feature/prerequisites
chillaq May 28, 2025
6fcf192
updated versions for 4.16.0 release
chillaq May 28, 2025
88f74d5
updated changes
chillaq May 28, 2025
5b9b93c
Merge pull request #570 from splitio/updated-version
chillaq May 29, 2025
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
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
4.16.0 (May 28, 2025)
- Added support for rule-based segments. These segments determine membership at runtime by evaluating their configured rules against the user attributes provided to the SDK.
- Added support for feature flag prerequisites. This allows customers to define dependency conditions between flags, which are evaluated before any allowlists or targeting rules.

4.15.0 (Apr 18, 2025)
- Prevent polling threads from starting when the SDK calls destroy method.
- Added a new optional argument to the client `getTreatment` methods to allow passing additional evaluation options, such as a map of properties to append to the generated impressions sent to Split backend. Read more in our docs.
Expand Down
6 changes: 3 additions & 3 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<parent>
<groupId>io.split.client</groupId>
<artifactId>java-client-parent</artifactId>
<version>4.15.0</version>
<version>4.16.0</version>
</parent>
<version>4.15.0</version>
<version>4.16.0</version>
<artifactId>java-client</artifactId>
<packaging>jar</packaging>
<name>Java Client</name>
Expand Down Expand Up @@ -168,7 +168,7 @@
<dependency>
<groupId>org.apache.httpcomponents.client5</groupId>
<artifactId>httpclient5</artifactId>
<version>5.4.1</version>
<version>5.4.4</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
Expand Down
3 changes: 2 additions & 1 deletion client/src/main/java/io/split/Spec.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ private Spec() {
// restrict instantiation
}

public static final String SPEC_VERSION = "1.1";
public static final String SPEC_1_3 = "1.3";
public static final String SPEC_1_1 = "1.1";
}

Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import io.split.engine.matchers.CombiningMatcher;
import io.split.engine.matchers.strings.WhitelistMatcher;
import io.split.grammar.Treatments;
import io.split.storages.SplitCacheConsumer;
import io.split.storages.SplitCacheProducer;

import java.util.ArrayList;
Expand Down Expand Up @@ -52,7 +51,7 @@ public void updateCache(Map<SplitAndKey, LocalhostSplit> map) {
String treatment = conditions.size() > 0 ? Treatments.CONTROL : localhostSplit.treatment;
configurations.put(localhostSplit.treatment, localhostSplit.config);

split = new ParsedSplit(splitName, 0, false, treatment,conditions, LOCALHOST, 0, 100, 0, 0, configurations, new HashSet<>(), true);
split = new ParsedSplit(splitName, 0, false, treatment,conditions, LOCALHOST, 0, 100, 0, 0, configurations, new HashSet<>(), true, null);
parsedSplits.removeIf(parsedSplit -> parsedSplit.feature().equals(splitName));
parsedSplits.add(split);
}
Expand Down
74 changes: 56 additions & 18 deletions client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

import com.google.common.annotations.VisibleForTesting;

import io.split.Spec;
import io.split.client.dtos.SplitChange;
import io.split.client.dtos.SplitHttpResponse;
import io.split.client.dtos.SplitChangesOldPayloadDto;
import io.split.client.exceptions.UriTooLongException;
import io.split.client.utils.Json;
import io.split.client.utils.Utils;
Expand All @@ -22,7 +24,8 @@
import java.net.URISyntaxException;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.split.Spec.SPEC_VERSION;
import static io.split.Spec.SPEC_1_3;
import static io.split.Spec.SPEC_1_1;

/**
* Created by adilaijaz on 5/30/15.
Expand All @@ -31,23 +34,30 @@ public final class HttpSplitChangeFetcher implements SplitChangeFetcher {
private static final Logger _log = LoggerFactory.getLogger(HttpSplitChangeFetcher.class);

private static final String SINCE = "since";
private static final String RB_SINCE = "rbSince";
private static final String TILL = "till";
private static final String SETS = "sets";
private static final String SPEC = "s";
private String specVersion = SPEC_1_3;
private int PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 24 * 60 * 60 * 1000;
private Long _lastProxyCheckTimestamp = 0L;
private final SplitHttpClient _client;
private final URI _target;
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;
private final boolean _rootURIOverriden;

public static HttpSplitChangeFetcher create(SplitHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer)
public static HttpSplitChangeFetcher create(SplitHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer,
boolean rootURIOverriden)
throws URISyntaxException {
return new HttpSplitChangeFetcher(client, Utils.appendPath(root, "api/splitChanges"), telemetryRuntimeProducer);
return new HttpSplitChangeFetcher(client, Utils.appendPath(root, "api/splitChanges"), telemetryRuntimeProducer, rootURIOverriden);
}

private HttpSplitChangeFetcher(SplitHttpClient client, URI uri, TelemetryRuntimeProducer telemetryRuntimeProducer) {
private HttpSplitChangeFetcher(SplitHttpClient client, URI uri, TelemetryRuntimeProducer telemetryRuntimeProducer, boolean rootURIOverriden) {
_client = client;
_target = uri;
checkNotNull(_target);
_telemetryRuntimeProducer = checkNotNull(telemetryRuntimeProducer);
_rootURIOverriden = rootURIOverriden;
}

long makeRandomTill() {
Expand All @@ -56,38 +66,66 @@ long makeRandomTill() {
}

@Override
public SplitChange fetch(long since, FetchOptions options) {

public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {
long start = System.currentTimeMillis();

try {
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SPEC, "" + SPEC_VERSION);
uriBuilder.addParameter(SINCE, "" + since);
if (!options.flagSetsFilter().isEmpty()) {
uriBuilder.addParameter(SETS, "" + options.flagSetsFilter());
}
if (options.hasCustomCN()) {
uriBuilder.addParameter(TILL, "" + options.targetCN());
URI uri = buildURL(options, since, sinceRBS);
if (specVersion.equals(SPEC_1_1) && (System.currentTimeMillis() - _lastProxyCheckTimestamp >= PROXY_CHECK_INTERVAL_MILLISECONDS_SS)) {
_log.info("Switching to new Feature flag spec ({}) and fetching.", SPEC_1_3);
specVersion = SPEC_1_3;
uri = buildURL(options, -1,-1);
}
URI uri = uriBuilder.build();
SplitHttpResponse response = _client.get(uri, options, null);

SplitHttpResponse response = _client.get(uri, options, null);
if (response.statusCode() < HttpStatus.SC_OK || response.statusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
if (response.statusCode() == HttpStatus.SC_REQUEST_URI_TOO_LONG) {
_log.error("The amount of flag sets provided are big causing uri length error.");
throw new UriTooLongException(String.format("Status code: %s. Message: %s", response.statusCode(), response.statusMessage()));
}

if (response.statusCode() == HttpStatus.SC_BAD_REQUEST && specVersion.equals(Spec.SPEC_1_3) && _rootURIOverriden) {
specVersion = Spec.SPEC_1_1;
_log.warn("Detected proxy without support for Feature flags spec {} version, will switch to spec version {}",
SPEC_1_3, SPEC_1_1);
_lastProxyCheckTimestamp = System.currentTimeMillis();
return fetch(since, sinceRBS, options);
}

_telemetryRuntimeProducer.recordSyncError(ResourceEnum.SPLIT_SYNC, response.statusCode());
throw new IllegalStateException(
String.format("Could not retrieve splitChanges since %s; http return code %s", since, response.statusCode())
);
}
return Json.fromJson(response.body(), SplitChange.class);

if (specVersion.equals(Spec.SPEC_1_1)) {
return Json.fromJson(response.body(), SplitChangesOldPayloadDto.class).toSplitChange();
}

SplitChange splitChange = Json.fromJson(response.body(), SplitChange.class);
splitChange.clearCache = _lastProxyCheckTimestamp != 0;
_lastProxyCheckTimestamp = 0L;
return splitChange;
} catch (Exception e) {
throw new IllegalStateException(String.format("Problem fetching splitChanges since %s: %s", since, e), e);
} finally {
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.SPLITS, System.currentTimeMillis()-start);
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.SPLITS, System.currentTimeMillis() - start);
}
}


private URI buildURL(FetchOptions options, long since, long sinceRBS) throws URISyntaxException {
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SPEC, "" + specVersion);
uriBuilder.addParameter(SINCE, "" + since);
if (specVersion.equals(SPEC_1_3)) {
uriBuilder.addParameter(RB_SINCE, "" + sinceRBS);
}
if (!options.flagSetsFilter().isEmpty()) {
uriBuilder.addParameter(SETS, "" + options.flagSetsFilter());
}
if (options.hasCustomCN()) {
uriBuilder.addParameter(TILL, "" + options.targetCN());
}
return uriBuilder.build();
}

@VisibleForTesting
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.split.client;

import com.google.gson.JsonObject;
import com.google.gson.stream.JsonReader;
import io.split.client.dtos.SplitChange;
import io.split.client.dtos.SplitChangesOldPayloadDto;
import io.split.client.utils.InputStreamProvider;
import io.split.client.utils.Json;
import io.split.client.utils.LocalhostSanitizer;
import io.split.engine.common.FetchOptions;
import io.split.engine.experiments.SplitChangeFetcher;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand All @@ -17,47 +20,71 @@
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import static io.split.client.utils.Utils.checkExitConditions;

public class JsonLocalhostSplitChangeFetcher implements SplitChangeFetcher {

private static final Logger _log = LoggerFactory.getLogger(JsonLocalhostSplitChangeFetcher.class);
private final InputStreamProvider _inputStreamProvider;
private byte [] lastHash;
private byte [] lastHashFeatureFlags;
private byte [] lastHashRuleBasedSegments;

public JsonLocalhostSplitChangeFetcher(InputStreamProvider inputStreamProvider) {
_inputStreamProvider = inputStreamProvider;
lastHash = new byte[0];
lastHashFeatureFlags = new byte[0];
lastHashRuleBasedSegments = new byte[0];
}

@Override
public SplitChange fetch(long since, FetchOptions options) {
public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {
try {
JsonReader jsonReader = new JsonReader(new BufferedReader(new InputStreamReader(_inputStreamProvider.get(), StandardCharsets.UTF_8)));
if (checkOldSpec(new JsonReader(new BufferedReader(new InputStreamReader(_inputStreamProvider.get(), StandardCharsets.UTF_8))))) {
return Json.fromJson(jsonReader, SplitChangesOldPayloadDto.class).toSplitChange();
}
SplitChange splitChange = Json.fromJson(jsonReader, SplitChange.class);
return processSplitChange(splitChange, since);
return processSplitChange(splitChange, since, sinceRBS);
} catch (Exception e) {
throw new IllegalStateException("Problem fetching splitChanges: " + e.getMessage(), e);
}
}

private SplitChange processSplitChange(SplitChange splitChange, long changeNumber) throws NoSuchAlgorithmException {
private boolean checkOldSpec(JsonReader jsonReader) {
return Json.fromJson(jsonReader, JsonObject.class).has("splits");
}

private SplitChange processSplitChange(SplitChange splitChange, long changeNumber, long changeNumberRBS) throws NoSuchAlgorithmException {
SplitChange splitChangeToProcess = LocalhostSanitizer.sanitization(splitChange);
// if the till is less than storage CN and different from the default till ignore the change
if (splitChangeToProcess.till < changeNumber && splitChangeToProcess.till != -1) {
if (checkExitConditions(splitChangeToProcess.featureFlags, changeNumber) ||
checkExitConditions(splitChangeToProcess.ruleBasedSegments, changeNumberRBS)) {
_log.warn("The till is lower than the change number or different to -1");
return null;
}
String splitJson = splitChange.splits.toString();
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(splitJson.getBytes());
// calculate the json sha
byte [] currHash = digest.digest();

byte [] currHashFeatureFlags = getStringDigest(splitChange.featureFlags.d.toString());
byte [] currHashRuleBasedSegments = getStringDigest(splitChange.ruleBasedSegments.d.toString());
//if sha exist and is equal to before sha, or if till is equal to default till returns the same segmentChange with till equals to storage CN
if (java.security.MessageDigest.isEqual(lastHash, currHash) || splitChangeToProcess.till == -1) {
splitChangeToProcess.till = changeNumber;
if (Arrays.equals(lastHashFeatureFlags, currHashFeatureFlags) || splitChangeToProcess.featureFlags.t == -1) {
splitChangeToProcess.featureFlags.t = changeNumber;
}
if (Arrays.equals(lastHashRuleBasedSegments, currHashRuleBasedSegments) || splitChangeToProcess.ruleBasedSegments.t == -1) {
splitChangeToProcess.ruleBasedSegments.t = changeNumberRBS;
}
lastHash = currHash;
splitChangeToProcess.since = changeNumber;

lastHashFeatureFlags = currHashFeatureFlags;
lastHashRuleBasedSegments = currHashRuleBasedSegments;
splitChangeToProcess.featureFlags.s = changeNumber;
splitChangeToProcess.ruleBasedSegments.s = changeNumberRBS;

return splitChangeToProcess;
}

private byte[] getStringDigest(String json) throws NoSuchAlgorithmException {
MessageDigest digest = MessageDigest.getInstance("SHA-1");
digest.reset();
digest.update(json.getBytes());
// calculate the json sha
return digest.digest();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.split.client.dtos.Split;
import io.split.client.dtos.SplitChange;
import io.split.client.dtos.Status;
import io.split.client.dtos.ChangeDto;
import io.split.client.utils.LocalhostConstants;
import io.split.client.utils.LocalhostSanitizer;
import io.split.engine.common.FetchOptions;
Expand Down Expand Up @@ -34,11 +35,12 @@ public LegacyLocalhostSplitChangeFetcher(String directory) {
}

@Override
public SplitChange fetch(long since, FetchOptions options) {
public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {

try (BufferedReader reader = new BufferedReader(new FileReader(_splitFile))) {
SplitChange splitChange = new SplitChange();
splitChange.splits = new ArrayList<>();
splitChange.featureFlags = new ChangeDto<>();
splitChange.featureFlags.d = new ArrayList<>();
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
String lineTrim = line.trim();
if (lineTrim.isEmpty() || lineTrim.startsWith("#")) {
Expand All @@ -51,37 +53,37 @@ public SplitChange fetch(long since, FetchOptions options) {
_log.info("Ignoring line since it does not have 2 or 3 columns: " + lineTrim);
continue;
}
Optional<Split> splitOptional = splitChange.splits.stream().filter(split -> split.name.equals(featureTreatment[0])).findFirst();
Optional<Split> splitOptional = splitChange.featureFlags.d.stream().
filter(split -> split.name.equals(featureTreatment[0])).findFirst();
Split split = splitOptional.orElse(null);
if(split == null) {
split = new Split();
split.name = featureTreatment[0];
split.configurations = new HashMap<>();
split.conditions = new ArrayList<>();
} else {
splitChange.splits.remove(split);
splitChange.featureFlags.d.remove(split);
}
split.status = Status.ACTIVE;
split.defaultTreatment = featureTreatment[1];
split.trafficTypeName = LocalhostConstants.USER;
split.trafficAllocation = LocalhostConstants.SIZE_100;
split.trafficAllocationSeed = LocalhostConstants.SIZE_1;

Condition condition;
if (featureTreatment.length == 2) {
condition = LocalhostSanitizer.createCondition(null, featureTreatment[1]);
} else {
condition = LocalhostSanitizer.createCondition(featureTreatment[2], featureTreatment[1]);
}
Condition condition = checkCondition(featureTreatment);
if(condition.conditionType != ConditionType.ROLLOUT){
split.conditions.add(0, condition);
} else {
split.conditions.add(condition);
}
splitChange.splits.add(split);
splitChange.featureFlags.d.add(split);
}
splitChange.till = since;
splitChange.since = since;
splitChange.featureFlags.t = since;
splitChange.featureFlags.s = since;
splitChange.ruleBasedSegments = new ChangeDto<>();
splitChange.ruleBasedSegments.s = -1;
splitChange.ruleBasedSegments.t = -1;
splitChange.ruleBasedSegments.d = new ArrayList<>();
return splitChange;
} catch (FileNotFoundException f) {
_log.warn("There was no file named " + _splitFile.getPath() + " found. " +
Expand All @@ -96,4 +98,14 @@ public SplitChange fetch(long since, FetchOptions options) {
throw new IllegalStateException("Problem fetching splitChanges: " + e.getMessage(), e);
}
}

private Condition checkCondition(String[] featureTreatment) {
Condition condition;
if (featureTreatment.length == 2) {
condition = LocalhostSanitizer.createCondition(null, featureTreatment[1]);
} else {
condition = LocalhostSanitizer.createCondition(featureTreatment[2], featureTreatment[1]);
}
return condition;
}
}
4 changes: 4 additions & 0 deletions client/src/main/java/io/split/client/SplitClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,10 @@ public CustomHeaderDecorator customHeaderDecorator() {
return _customHeaderDecorator;
}

public boolean isSdkEndpointOverridden() {
return !_endpoint.equals(SDK_ENDPOINT);
}

public CustomHttpModule alternativeHTTPModule() { return _alternativeHTTPModule; }
public static final class Builder {

Expand Down
Loading