Skip to content

Commit 65958cb

Browse files
authored
Merge pull request #549 from splitio/rbs-oldspec-fetcher
Added old spec support in splitfetcher
2 parents 577addc + de79368 commit 65958cb

File tree

6 files changed

+171
-27
lines changed

6 files changed

+171
-27
lines changed

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

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,13 @@
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;
8+
import io.split.client.dtos.RuleBasedSegment;
9+
import io.split.client.dtos.SplitChangesOldPayloadDto;
10+
import io.split.client.dtos.ChangeDto;
11+
import io.split.client.dtos.Split;
712
import io.split.client.exceptions.UriTooLongException;
813
import io.split.client.utils.Json;
914
import io.split.client.utils.Utils;
@@ -20,36 +25,44 @@
2025

2126
import java.net.URI;
2227
import java.net.URISyntaxException;
28+
import java.util.ArrayList;
2329

2430
import static com.google.common.base.Preconditions.checkNotNull;
2531
import static io.split.Spec.SPEC_1_3;
32+
import static io.split.Spec.SPEC_1_1;
2633

2734
/**
2835
* Created by adilaijaz on 5/30/15.
2936
*/
3037
public final class HttpSplitChangeFetcher implements SplitChangeFetcher {
3138
private static final Logger _log = LoggerFactory.getLogger(HttpSplitChangeFetcher.class);
3239

40+
private final Object _lock = new Object();
3341
private static final String SINCE = "since";
3442
private static final String RB_SINCE = "rbSince";
3543
private static final String TILL = "till";
3644
private static final String SETS = "sets";
3745
private static final String SPEC = "s";
3846
private String specVersion = SPEC_1_3;
47+
private int PROXY_CHECK_INTERVAL_MILLISECONDS_SS = 24 * 60 * 60 * 1000;
48+
private Long _lastProxyCheckTimestamp = 0L;
3949
private final SplitHttpClient _client;
4050
private final URI _target;
4151
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;
52+
private final boolean _rootURIOverriden;
4253

43-
public static HttpSplitChangeFetcher create(SplitHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer)
54+
public static HttpSplitChangeFetcher create(SplitHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer,
55+
boolean rootURIOverriden)
4456
throws URISyntaxException {
45-
return new HttpSplitChangeFetcher(client, Utils.appendPath(root, "api/splitChanges"), telemetryRuntimeProducer);
57+
return new HttpSplitChangeFetcher(client, Utils.appendPath(root, "api/splitChanges"), telemetryRuntimeProducer, rootURIOverriden);
4658
}
4759

48-
private HttpSplitChangeFetcher(SplitHttpClient client, URI uri, TelemetryRuntimeProducer telemetryRuntimeProducer) {
60+
private HttpSplitChangeFetcher(SplitHttpClient client, URI uri, TelemetryRuntimeProducer telemetryRuntimeProducer, boolean rootURIOverriden) {
4961
_client = client;
5062
_target = uri;
5163
checkNotNull(_target);
5264
_telemetryRuntimeProducer = checkNotNull(telemetryRuntimeProducer);
65+
_rootURIOverriden = rootURIOverriden;
5366
}
5467

5568
long makeRandomTill() {
@@ -61,32 +74,63 @@ long makeRandomTill() {
6174
public SplitChange fetch(long since, long sinceRBS, FetchOptions options) {
6275
long start = System.currentTimeMillis();
6376
try {
77+
if (specVersion.equals(SPEC_1_1) && (System.currentTimeMillis() - _lastProxyCheckTimestamp >= PROXY_CHECK_INTERVAL_MILLISECONDS_SS)) {
78+
_log.info("Switching to new Feature flag spec ({}) and fetching.", SPEC_1_3);
79+
specVersion = SPEC_1_3;
80+
}
6481
URI uri = buildURL(options, since, sinceRBS);
6582
SplitHttpResponse response = _client.get(uri, options, null);
66-
6783
if (response.statusCode() < HttpStatus.SC_OK || response.statusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
6884
if (response.statusCode() == HttpStatus.SC_REQUEST_URI_TOO_LONG) {
6985
_log.error("The amount of flag sets provided are big causing uri length error.");
7086
throw new UriTooLongException(String.format("Status code: %s. Message: %s", response.statusCode(), response.statusMessage()));
7187
}
7288

89+
if (response.statusCode() == HttpStatus.SC_BAD_REQUEST && specVersion.equals(Spec.SPEC_1_3) && _rootURIOverriden) {
90+
specVersion = Spec.SPEC_1_1;
91+
_log.warn("Detected proxy without support for Feature flags spec {} version, will switch to spec version {}",
92+
SPEC_1_3, SPEC_1_1);
93+
_lastProxyCheckTimestamp = System.currentTimeMillis();
94+
return fetch(since, 0, options);
95+
}
96+
7397
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.SPLIT_SYNC, response.statusCode());
7498
throw new IllegalStateException(
7599
String.format("Could not retrieve splitChanges since %s; http return code %s", since, response.statusCode())
76100
);
77101
}
78-
return Json.fromJson(response.body(), SplitChange.class);
102+
103+
String body = response.body();
104+
if (specVersion.equals(Spec.SPEC_1_1)) {
105+
return Json.fromJson(body, SplitChangesOldPayloadDto.class).toSplitChange();
106+
}
107+
108+
return Json.fromJson(body, SplitChange.class);
109+
79110
} catch (Exception e) {
80111
throw new IllegalStateException(String.format("Problem fetching splitChanges since %s: %s", since, e), e);
81112
} finally {
82113
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.SPLITS, System.currentTimeMillis() - start);
83114
}
84115
}
85116

117+
public Long getLastProxyCheckTimestamp() {
118+
return _lastProxyCheckTimestamp;
119+
}
120+
121+
public void setLastProxyCheckTimestamp(long lastProxyCheckTimestamp) {
122+
synchronized (_lock) {
123+
_lastProxyCheckTimestamp = lastProxyCheckTimestamp;
124+
}
125+
}
126+
127+
86128
private URI buildURL(FetchOptions options, long since, long sinceRBS) throws URISyntaxException {
87129
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SPEC, "" + specVersion);
88130
uriBuilder.addParameter(SINCE, "" + since);
89-
uriBuilder.addParameter(RB_SINCE, "" + sinceRBS);
131+
if (specVersion.equals(SPEC_1_3)) {
132+
uriBuilder.addParameter(RB_SINCE, "" + sinceRBS);
133+
}
90134
if (!options.flagSetsFilter().isEmpty()) {
91135
uriBuilder.addParameter(SETS, "" + options.flagSetsFilter());
92136
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,10 @@ public CustomHeaderDecorator customHeaderDecorator() {
412412
return _customHeaderDecorator;
413413
}
414414

415+
public boolean isSdkEndpointOverridden() {
416+
return !_endpoint.equals(SDK_ENDPOINT);
417+
}
418+
415419
public CustomHttpModule alternativeHTTPModule() { return _alternativeHTTPModule; }
416420
public static final class Builder {
417421

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
224224
RuleBasedSegmentParser ruleBasedSegmentParser = new RuleBasedSegmentParser();
225225
// SplitFetcher
226226
_splitFetcher = buildSplitFetcher(splitCache, splitParser, flagSetsFilter,
227-
ruleBasedSegmentParser, ruleBasedSegmentCache);
227+
ruleBasedSegmentParser, ruleBasedSegmentCache, config.isSdkEndpointOverridden());
228228

229229
// SplitSynchronizationTask
230230
_splitSynchronizationTask = new SplitSynchronizationTask(_splitFetcher,
@@ -622,9 +622,9 @@ private SegmentSynchronizationTaskImp buildSegments(SplitClientConfig config,
622622

623623
private SplitFetcher buildSplitFetcher(SplitCacheProducer splitCacheProducer, SplitParser splitParser,
624624
FlagSetsFilter flagSetsFilter, RuleBasedSegmentParser ruleBasedSegmentParser,
625-
RuleBasedSegmentCacheProducer ruleBasedSegmentCache) throws URISyntaxException {
625+
RuleBasedSegmentCacheProducer ruleBasedSegmentCache, boolean isRootURIOverriden) throws URISyntaxException {
626626
SplitChangeFetcher splitChangeFetcher = HttpSplitChangeFetcher.create(_splitHttpClient, _rootTarget,
627-
_telemetryStorageProducer);
627+
_telemetryStorageProducer, isRootURIOverriden);
628628
return new SplitFetcherImp(splitChangeFetcher, splitParser, splitCacheProducer, _telemetryStorageProducer,
629629
flagSetsFilter, ruleBasedSegmentParser, ruleBasedSegmentCache);
630630
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package io.split.client.dtos;
2+
3+
import com.google.gson.annotations.SerializedName;
4+
5+
import java.util.ArrayList;
6+
import java.util.List;
7+
8+
public class SplitChangesOldPayloadDto {
9+
@SerializedName("since")
10+
public long s;
11+
12+
@SerializedName("till")
13+
public long t;
14+
15+
@SerializedName("splits")
16+
public List<Split> d;
17+
18+
public SplitChange toSplitChange() {
19+
SplitChange splitChange = new SplitChange();
20+
ChangeDto<Split> ff = new ChangeDto<>();
21+
ff.s = this.s;
22+
ff.t = this.t;
23+
ff.d = this.d;
24+
ChangeDto<RuleBasedSegment> rbs = new ChangeDto<>();
25+
rbs.d = new ArrayList<>();
26+
rbs.t = -1;
27+
rbs.s = -1;
28+
29+
splitChange.featureFlags = ff;
30+
splitChange.ruleBasedSegments = rbs;
31+
32+
return splitChange;
33+
}
34+
}

0 commit comments

Comments
 (0)