Skip to content

Commit 99cf461

Browse files
authored
Merge pull request #225 from splitio/feat/cdn_bypass
Feat/cdn bypass
2 parents e0bf264 + 80e720c commit 99cf461

20 files changed

+374
-153
lines changed

client/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<parent>
66
<groupId>io.split.client</groupId>
77
<artifactId>java-client-parent</artifactId>
8-
<version>4.1.7-rc4</version>
8+
<version>4.1.7</version>
99
</parent>
1010
<artifactId>java-client</artifactId>
1111
<packaging>jar</packaging>

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

+29-6
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
import io.split.client.dtos.SegmentChange;
55
import io.split.client.utils.Json;
66
import io.split.client.utils.Utils;
7+
import io.split.engine.common.FetchOptions;
78
import io.split.engine.metrics.Metrics;
89
import io.split.engine.segments.SegmentChangeFetcher;
910
import org.apache.hc.client5.http.classic.methods.HttpGet;
1011
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
1112
import org.apache.hc.client5.http.impl.classic.CloseableHttpResponse;
13+
import org.apache.hc.core5.http.Header;
1214
import org.apache.hc.core5.http.io.entity.EntityUtils;
1315
import org.apache.hc.core5.net.URIBuilder;
1416
import org.slf4j.Logger;
@@ -17,6 +19,8 @@
1719
import java.net.URI;
1820
import java.net.URISyntaxException;
1921
import java.nio.charset.StandardCharsets;
22+
import java.util.Arrays;
23+
import java.util.stream.Collectors;
2024

2125
import static com.google.common.base.Preconditions.checkNotNull;
2226

@@ -27,9 +31,13 @@ public final class HttpSegmentChangeFetcher implements SegmentChangeFetcher {
2731
private static final Logger _log = LoggerFactory.getLogger(HttpSegmentChangeFetcher.class);
2832

2933
private static final String SINCE = "since";
34+
private static final String TILL = "till";
3035
private static final String PREFIX = "segmentChangeFetcher";
31-
private static final String NAME_CACHE = "Cache-Control";
32-
private static final String VALUE_CACHE = "no-cache";
36+
private static final String CACHE_CONTROL_HEADER_NAME = "Cache-Control";
37+
private static final String CACHE_CONTROL_HEADER_VALUE = "no-cache";
38+
39+
private static final String HEADER_FASTLY_DEBUG_NAME = "Fastly-Debug";
40+
private static final String HEADER_FASTLY_DEBUG_VALUE = "1";
3341

3442
private final CloseableHttpClient _client;
3543
private final URI _target;
@@ -51,19 +59,34 @@ private HttpSegmentChangeFetcher(CloseableHttpClient client, URI uri, Metrics me
5159
}
5260

5361
@Override
54-
public SegmentChange fetch(String segmentName, long since, boolean addCacheHeader) {
62+
public SegmentChange fetch(String segmentName, long since, FetchOptions options) {
5563
long start = System.currentTimeMillis();
5664

5765
CloseableHttpResponse response = null;
5866

5967
try {
6068
String path = _target.getPath() + "/" + segmentName;
61-
URI uri = new URIBuilder(_target).setPath(path).addParameter(SINCE, "" + since).build();
69+
URIBuilder uriBuilder = new URIBuilder(_target)
70+
.setPath(path)
71+
.addParameter(SINCE, "" + since);
72+
if (options.hasCustomCN()) {
73+
uriBuilder.addParameter(TILL, "" + options.targetCN());
74+
}
75+
76+
URI uri = uriBuilder.build();
6277
HttpGet request = new HttpGet(uri);
63-
if(addCacheHeader) {
64-
request.setHeader(NAME_CACHE, VALUE_CACHE);
78+
79+
if(options.cacheControlHeadersEnabled()) {
80+
request.setHeader(CACHE_CONTROL_HEADER_NAME, CACHE_CONTROL_HEADER_VALUE);
6581
}
82+
83+
if (options.fastlyDebugHeaderEnabled()) {
84+
request.addHeader(HEADER_FASTLY_DEBUG_NAME, HEADER_FASTLY_DEBUG_VALUE);
85+
}
86+
6687
response = _client.execute(request);
88+
options.handleResponseHeaders(Arrays.stream(response.getHeaders())
89+
.collect(Collectors.toMap(Header::getName, Header::getValue)));
6790

6891
int statusCode = response.getCode();
6992

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

+4-3
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ private HttpSplitChangeFetcher(CloseableHttpClient client, URI uri, Metrics metr
6060
}
6161

6262
long makeRandomTill() {
63-
return (-1)*(int)Math.floor(Math.random()*(Math.pow(2, 63)));
63+
64+
return (-1)*(long)Math.floor(Math.random()*(Math.pow(2, 63)));
6465
}
6566

6667
@Override
@@ -72,8 +73,8 @@ public SplitChange fetch(long since, FetchOptions options) {
7273

7374
try {
7475
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SINCE, "" + since);
75-
if (options.cdnBypass()) {
76-
uriBuilder.addParameter(TILL, "" + makeRandomTill());
76+
if (options.hasCustomCN()) {
77+
uriBuilder.addParameter(TILL, "" + options.targetCN());
7778
}
7879
URI uri = uriBuilder.build();
7980

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

+4-38
Original file line numberDiff line numberDiff line change
@@ -304,10 +304,10 @@ public static final class Builder {
304304
private int _streamingReconnectBackoffBase = 1;
305305
private String _authServiceURL = "https://auth.split.io/api/auth";
306306
private String _streamingServiceURL = "https://streaming.split.io/sse";
307-
private int _onDemandFetchRetryDelayMs = 50;
308-
private int _onDemandFetchMaxRetries = 10;
309-
private int _failedAttemptsBeforeLogging = -1;
310-
private boolean _cdnDebugLogging = true;
307+
private final int _onDemandFetchRetryDelayMs = 50;
308+
private final int _onDemandFetchMaxRetries = 10;
309+
private final int _failedAttemptsBeforeLogging = 10;
310+
private final boolean _cdnDebugLogging = true;
311311

312312
public Builder() {
313313
}
@@ -699,36 +699,6 @@ public Builder streamingServiceURL(String streamingServiceURL) {
699699
return this;
700700
}
701701

702-
/**
703-
* Set Streaming retry delay.
704-
* @param onDemandFetchRetryDelayMs
705-
* @return
706-
*/
707-
public Builder streamingRetryDelay(int onDemandFetchRetryDelayMs) {
708-
_onDemandFetchRetryDelayMs = onDemandFetchRetryDelayMs;
709-
return this;
710-
}
711-
712-
public Builder streamingFetchMaxRetries(int maxRetries) {
713-
_onDemandFetchMaxRetries = maxRetries;
714-
return this;
715-
}
716-
717-
public Builder failedAttemptsBeforeLoggingCDNInfo(int failedAttemptsBeforeLogging) {
718-
_failedAttemptsBeforeLogging = failedAttemptsBeforeLogging;
719-
return this;
720-
}
721-
722-
/**
723-
* Enable logging response headers for requests made to our CDN.
724-
* @param cdnDebugLogging
725-
* @return
726-
*/
727-
public Builder cdnDebugLogging(boolean cdnDebugLogging) {
728-
_cdnDebugLogging = cdnDebugLogging;
729-
return this;
730-
}
731-
732702
public SplitClientConfig build() {
733703
if (_featuresRefreshRate < 5 ) {
734704
throw new IllegalArgumentException("featuresRefreshRate must be >= 5: " + _featuresRefreshRate);
@@ -806,10 +776,6 @@ public SplitClientConfig build() {
806776
throw new IllegalStateException("_onDemandFetchMaxRetries must be > 0");
807777
}
808778

809-
if (_failedAttemptsBeforeLogging < 0) {
810-
_failedAttemptsBeforeLogging = _onDemandFetchMaxRetries / 2;
811-
}
812-
813779
return new SplitClientConfig(
814780
_endpoint,
815781
_eventsEndpoint,

client/src/main/java/io/split/client/jmx/SplitJmxMonitor.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public boolean forceSyncFeatures() {
4444
public boolean forceSyncSegment(String segmentName) {
4545
SegmentFetcher fetcher = _segmentSynchronizationTask.getFetcher(segmentName);
4646
try{
47-
fetcher.fetch(true);
47+
fetcher.fetch(new FetchOptions.Builder().build());
4848
}
4949
//We are sure this will never happen because getFetcher firts initiate the segment. This try/catch is for safe only.
5050
catch (NullPointerException np){

client/src/main/java/io/split/engine/common/FetchOptions.java

+17-12
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
import java.util.function.Function;
66

77
public class FetchOptions {
8-
8+
9+
public static final Long DEFAULT_TARGET_CHANGENUMBER = -1L;
10+
911
public static class Builder {
1012

1113
public Builder() {}
1214

1315
public Builder(FetchOptions opts) {
14-
_cdnBypass = opts._cdnBypass;
16+
_targetCN = opts._targetCN;
1517
_cacheControlHeaders = opts._cacheControlHeaders;
1618
_fastlyDebugHeader = opts._fastlyDebugHeader;
1719
_responseHeadersCallback = opts._responseHeadersCallback;
@@ -32,16 +34,16 @@ public Builder responseHeadersCallback(Function<Map<String, String>, Void> callb
3234
return this;
3335
}
3436

35-
public Builder cdnBypass(boolean bypass) {
36-
_cdnBypass = bypass;
37+
public Builder targetChangeNumber(long targetCN) {
38+
_targetCN = targetCN;
3739
return this;
3840
}
3941

4042
public FetchOptions build() {
41-
return new FetchOptions(_cacheControlHeaders, _cdnBypass, _responseHeadersCallback, _fastlyDebugHeader);
43+
return new FetchOptions(_cacheControlHeaders, _targetCN, _responseHeadersCallback, _fastlyDebugHeader);
4244
}
4345

44-
private boolean _cdnBypass = false;
46+
private long _targetCN = DEFAULT_TARGET_CHANGENUMBER;
4547
private boolean _cacheControlHeaders = false;
4648
private boolean _fastlyDebugHeader = false;
4749
private Function<Map<String, String>, Void> _responseHeadersCallback = null;
@@ -55,7 +57,9 @@ public boolean fastlyDebugHeaderEnabled() {
5557
return _fastlyDebugHeader;
5658
}
5759

58-
public boolean cdnBypass() { return _cdnBypass; }
60+
public long targetCN() { return _targetCN; }
61+
62+
public boolean hasCustomCN() { return _targetCN != DEFAULT_TARGET_CHANGENUMBER; }
5963

6064
public void handleResponseHeaders(Map<String, String> headers) {
6165
if (Objects.isNull(_responseHeadersCallback) || Objects.isNull(headers)) {
@@ -65,11 +69,11 @@ public void handleResponseHeaders(Map<String, String> headers) {
6569
}
6670

6771
private FetchOptions(boolean cacheControlHeaders,
68-
boolean cdnBypass,
72+
long targetCN,
6973
Function<Map<String, String>, Void> responseHeadersCallback,
7074
boolean fastlyDebugHeader) {
7175
_cacheControlHeaders = cacheControlHeaders;
72-
_cdnBypass = cdnBypass;
76+
_targetCN = targetCN;
7377
_responseHeadersCallback = responseHeadersCallback;
7478
_fastlyDebugHeader = fastlyDebugHeader;
7579
}
@@ -84,16 +88,17 @@ public boolean equals(Object obj) {
8488

8589
return Objects.equals(_cacheControlHeaders, other._cacheControlHeaders)
8690
&& Objects.equals(_fastlyDebugHeader, other._fastlyDebugHeader)
87-
&& Objects.equals(_responseHeadersCallback, other._responseHeadersCallback);
91+
&& Objects.equals(_responseHeadersCallback, other._responseHeadersCallback)
92+
&& Objects.equals(_targetCN, other._targetCN);
8893
}
8994

9095
@Override
9196
public int hashCode() {
92-
return com.google.common.base.Objects.hashCode(_cacheControlHeaders, _fastlyDebugHeader, _responseHeadersCallback);
97+
return com.google.common.base.Objects.hashCode(_cacheControlHeaders, _fastlyDebugHeader, _responseHeadersCallback, _targetCN);
9398
}
9499

95100
private final boolean _cacheControlHeaders;
96101
private final boolean _fastlyDebugHeader;
97-
private final boolean _cdnBypass;
102+
private final long _targetCN;
98103
private final Function<Map<String, String>, Void> _responseHeadersCallback;
99104
}

0 commit comments

Comments
 (0)