Skip to content

Commit 13b3c55

Browse files
authored
Merge pull request #149 from splitio/development
[4.0.0] Development into master
2 parents 8b6aac1 + 3c492b3 commit 13b3c55

File tree

81 files changed

+4491
-39
lines changed

Some content is hidden

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

81 files changed

+4491
-39
lines changed

client/CHANGES.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
CHANGES
22

3+
4.0.0 (Aug 19, 2020)
4+
- Added support for the new Split streaming architecture. When enabled (default), the SDK will not poll for updates but instead receive notifications every time there's a change in your environments, allowing to process those much quicker. If disabled or in the event of an issue, the SDK will fallback to the known polling mechanism to provide a seamless experience.
5+
- Updated the default of featuresRefreshRate to 60 seconds.
6+
7+
3.3.4 (Jul 15, 2020)
8+
- Added Impression observer.
9+
310
3.3.3 (Apr 7, 2020)
411
- Fix issue regarding special characters come from split/segments fetchers.
512

client/pom.xml

Lines changed: 66 additions & 6 deletions
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>3.3.4</version>
8+
<version>4.0.0</version>
99
</parent>
1010
<artifactId>java-client</artifactId>
1111
<packaging>jar</packaging>
@@ -19,15 +19,15 @@
1919
<version>3.3</version>
2020
<inherited>false</inherited>
2121
<configuration>
22-
<source>1.7</source>
23-
<target>1.7</target>
22+
<source>8</source>
23+
<target>8</target>
2424
</configuration>
2525
</plugin>
2626
<!-- Shade dependencies to avoid conflicts with other customer's libs -->
2727
<plugin>
2828
<groupId>org.apache.maven.plugins</groupId>
2929
<artifactId>maven-shade-plugin</artifactId>
30-
<version>2.4.3</version>
30+
<version>3.2.4</version>
3131
<executions>
3232
<execution>
3333
<phase>package</phase>
@@ -47,9 +47,18 @@
4747
<include>org.apache.httpcomponents:httpcore</include>
4848
<include>com.google.code.gson:gson</include>
4949
<include>com.google.guava:guava</include>
50-
<include>org.yaml.snakeyaml</include>
50+
<include>org.yaml.snakeyaml.*</include>
51+
<include>org.glassfish.*</include>
52+
<include>jakarta.*</include>
53+
<include>org.javassist:javassist</include>
54+
<include>com.sun.activation:jakarta.activation</include>
55+
<include>org.jvnet.*</include>
5156
</includes>
5257
</artifactSet>
58+
<transformers>
59+
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer" />
60+
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer" />
61+
</transformers>
5362
<relocations>
5463
<relocation>
5564
<pattern>org.apache.http</pattern>
@@ -59,6 +68,26 @@
5968
<pattern>com.google</pattern>
6069
<shadedPattern>split.com.google</shadedPattern>
6170
</relocation>
71+
<relocation>
72+
<pattern>org.glassfish</pattern>
73+
<shadedPattern>split.org.glassfish</shadedPattern>
74+
</relocation>
75+
<relocation>
76+
<pattern>jakarta</pattern>
77+
<shadedPattern>split.jakarta</shadedPattern>
78+
</relocation>
79+
<relocation>
80+
<pattern>org.javassist</pattern>
81+
<shadedPattern>split.org.javassist</shadedPattern>
82+
</relocation>
83+
<relocation>
84+
<pattern>com.sun.activation</pattern>
85+
<shadedPattern>split.com.sun.activation</shadedPattern>
86+
</relocation>
87+
<relocation>
88+
<pattern>org.jvnet</pattern>
89+
<shadedPattern>split.org.jvnet</shadedPattern>
90+
</relocation>
6291
</relocations>
6392
<filters>
6493
<filter>
@@ -67,7 +96,9 @@
6796
<exclude>META-INF/license/**</exclude>
6897
<exclude>META-INF/*</exclude>
6998
<exclude>META-INF/maven/**</exclude>
70-
<exclude>META-INF/services/**</exclude>
99+
<!-- Disabled to allow Jersey implementation mappings/injector to work
100+
<exclude>META-INF/services/**</exclude>
101+
-->
71102
<exclude>LICENSE</exclude>
72103
<exclude>NOTICE</exclude>
73104
<exclude>/*.txt</exclude>
@@ -139,6 +170,17 @@
139170
<artifactId>snakeyaml</artifactId>
140171
<version>1.21</version>
141172
</dependency>
173+
<dependency>
174+
<groupId>org.glassfish.jersey.media</groupId>
175+
<artifactId>jersey-media-sse</artifactId>
176+
<version>2.31</version>
177+
</dependency>
178+
<dependency>
179+
<groupId>org.glassfish.jersey.inject</groupId>
180+
<artifactId>jersey-hk2</artifactId>
181+
<version>2.31</version>
182+
</dependency>
183+
142184
<!-- Test deps -->
143185
<dependency>
144186
<groupId>org.apache.commons</groupId>
@@ -169,5 +211,23 @@
169211
<version>1.7.21</version>
170212
<scope>test</scope>
171213
</dependency>
214+
<dependency>
215+
<groupId>org.glassfish.jersey.containers</groupId>
216+
<artifactId>jersey-container-grizzly2-http</artifactId>
217+
<version>2.26</version>
218+
<scope>test</scope>
219+
</dependency>
220+
<dependency>
221+
<groupId>com.squareup.okhttp3</groupId>
222+
<artifactId>mockwebserver</artifactId>
223+
<version>4.8.0</version>
224+
<scope>test</scope>
225+
</dependency>
226+
<dependency>
227+
<groupId>org.awaitility</groupId>
228+
<artifactId>awaitility</artifactId>
229+
<version>4.0.3</version>
230+
<scope>test</scope>
231+
</dependency>
172232
</dependencies>
173233
</project>

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

Lines changed: 113 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@ public class SplitClientConfig {
3939
private final boolean _destroyOnShutDown;
4040
private final String _splitFile;
4141
private final IntegrationsConfig _integrationsConfig;
42+
private final boolean _streamingEnabled;
43+
private final int _authRetryBackoffBase;
44+
private final int _streamingReconnectBackoffBase;
45+
private final String _authServiceURL;
46+
private final String _streamingServiceURL;
4247

4348
// Proxy configs
4449
private final HttpHost _proxy;
@@ -76,7 +81,12 @@ private SplitClientConfig(String endpoint,
7681
int maxStringLength,
7782
boolean destroyOnShutDown,
7883
String splitFile,
79-
IntegrationsConfig integrationsConfig) {
84+
IntegrationsConfig integrationsConfig,
85+
boolean streamingEnabled,
86+
int authRetryBackoffBase,
87+
int streamingReconnectBackoffBase,
88+
String authServiceURL,
89+
String streamingServiceURL) {
8090
_endpoint = endpoint;
8191
_eventsEndpoint = eventsEndpoint;
8292
_featuresRefreshRate = pollForFeatureChangesEveryNSeconds;
@@ -101,6 +111,11 @@ private SplitClientConfig(String endpoint,
101111
_destroyOnShutDown = destroyOnShutDown;
102112
_splitFile = splitFile;
103113
_integrationsConfig = integrationsConfig;
114+
_streamingEnabled = streamingEnabled;
115+
_authRetryBackoffBase = authRetryBackoffBase;
116+
_streamingReconnectBackoffBase = streamingReconnectBackoffBase;
117+
_authServiceURL = authServiceURL;
118+
_streamingServiceURL = streamingServiceURL;
104119

105120
Properties props = new Properties();
106121
try {
@@ -207,13 +222,33 @@ public IntegrationsConfig integrationsConfig() {
207222
return _integrationsConfig;
208223
}
209224

225+
public boolean streamingEnabled() {
226+
return _streamingEnabled;
227+
}
228+
229+
public int authRetryBackoffBase() {
230+
return _authRetryBackoffBase;
231+
}
232+
233+
public int streamingReconnectBackoffBase() {
234+
return _streamingReconnectBackoffBase;
235+
}
236+
237+
public String authServiceURL() {
238+
return _authServiceURL;
239+
}
240+
241+
public String streamingServiceURL() {
242+
return _streamingServiceURL;
243+
}
244+
210245
public static final class Builder {
211246

212247
private String _endpoint = "https://sdk.split.io";
213248
private boolean _endpointSet = false;
214249
private String _eventsEndpoint = "https://events.split.io";
215250
private boolean _eventsEndpointSet = false;
216-
private int _featuresRefreshRate = 5;
251+
private int _featuresRefreshRate = 60;
217252
private int _segmentsRefreshRate = 60;
218253
private int _impressionsRefreshRate = 30;
219254
private int _impressionsQueueSize = 30000;
@@ -236,6 +271,11 @@ public static final class Builder {
236271
private boolean _destroyOnShutDown = true;
237272
private String _splitFile = null;
238273
private IntegrationsConfig _integrationsConfig = null;
274+
private boolean _streamingEnabled = true;
275+
private int _authRetryBackoffBase = 1;
276+
private int _streamingReconnectBackoffBase = 1;
277+
private String _authServiceURL = "https://auth.split.io/api/auth";
278+
private String _streamingServiceURL = "https://streaming.split.io/event-stream";
239279

240280
public Builder() {
241281
}
@@ -572,6 +612,55 @@ public Builder integrations(IntegrationsConfig config) {
572612
return this;
573613
}
574614

615+
/**
616+
* Set if streaming is enabled or not. Default is true.
617+
* @param streamingEnabled
618+
* @return
619+
*/
620+
public Builder streamingEnabled(boolean streamingEnabled) {
621+
_streamingEnabled = streamingEnabled;
622+
return this;
623+
}
624+
625+
/**
626+
* Set how many seconds to wait before re attempting to authenticate for push notifications. Default 1 second. Minimum 1 second.
627+
* @param authRetryBackoffBase
628+
* @return
629+
*/
630+
public Builder authRetryBackoffBase(int authRetryBackoffBase) {
631+
_authRetryBackoffBase = authRetryBackoffBase;
632+
return this;
633+
}
634+
635+
/**
636+
* Set how many seconds to wait before re attempting to connect to streaming. Default 1 second. Minimum 1 second.
637+
* @param streamingReconnectBackoffBase
638+
* @return
639+
*/
640+
public Builder streamingReconnectBackoffBase(int streamingReconnectBackoffBase) {
641+
_streamingReconnectBackoffBase = streamingReconnectBackoffBase;
642+
return this;
643+
}
644+
645+
/**
646+
* Set Authentication service URL.
647+
* @param authServiceURL
648+
* @return
649+
*/
650+
public Builder authServiceURL(String authServiceURL) {
651+
_authServiceURL = authServiceURL;
652+
return this;
653+
}
654+
655+
/**
656+
* Set Streaming service URL.
657+
* @param streamingServiceURL
658+
* @return
659+
*/
660+
public Builder streamingServiceURL(String streamingServiceURL) {
661+
_streamingServiceURL = streamingServiceURL;
662+
return this;
663+
}
575664

576665
public SplitClientConfig build() {
577666
if (_featuresRefreshRate < 5 ) {
@@ -622,6 +711,22 @@ public SplitClientConfig build() {
622711
throw new IllegalArgumentException("Number of threads for fetching segments MUST be greater than zero");
623712
}
624713

714+
if (_authRetryBackoffBase <= 0) {
715+
throw new IllegalArgumentException("authRetryBackoffBase: must be >= 1");
716+
}
717+
718+
if (_streamingReconnectBackoffBase <= 0) {
719+
throw new IllegalArgumentException("streamingReconnectBackoffBase: must be >= 1");
720+
}
721+
722+
if (_authServiceURL == null) {
723+
throw new IllegalArgumentException("authServiceURL must not be null");
724+
}
725+
726+
if (_streamingServiceURL == null) {
727+
throw new IllegalArgumentException("streamingServiceURL must not be null");
728+
}
729+
625730
return new SplitClientConfig(
626731
_endpoint,
627732
_eventsEndpoint,
@@ -646,10 +751,12 @@ public SplitClientConfig build() {
646751
_maxStringLength,
647752
_destroyOnShutDown,
648753
_splitFile,
649-
_integrationsConfig);
754+
_integrationsConfig,
755+
_streamingEnabled,
756+
_authRetryBackoffBase,
757+
_streamingReconnectBackoffBase,
758+
_authServiceURL,
759+
_streamingServiceURL);
650760
}
651-
652761
}
653-
654-
655762
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import io.split.client.metrics.FireAndForgetMetrics;
1313
import io.split.client.metrics.HttpMetrics;
1414
import io.split.engine.SDKReadinessGates;
15+
import io.split.engine.common.SyncManager;
16+
import io.split.engine.common.SyncManagerImp;
1517
import io.split.engine.experiments.RefreshableSplitFetcherProvider;
1618
import io.split.engine.experiments.SplitChangeFetcher;
1719
import io.split.engine.experiments.SplitParser;
@@ -209,6 +211,10 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
209211

210212
final EventClient eventClient = EventClientImpl.create(httpclient, eventsRootTarget, config.eventsQueueSize(), config.eventFlushIntervalInMillis(), config.waitBeforeShutdown());
211213

214+
// SyncManager
215+
final SyncManager syncManager = SyncManagerImp.build(config.streamingEnabled(), splitFetcherProvider, segmentFetcher, config.authServiceURL(), httpclient, config.streamingServiceURL(), config.authRetryBackoffBase());
216+
syncManager.start();
217+
212218
destroyer = new Runnable() {
213219
public void run() {
214220
_log.info("Shutdown called for split");
@@ -227,6 +233,8 @@ public void run() {
227233
_log.info("Successful shutdown of httpclient");
228234
eventClient.close();
229235
_log.info("Successful shutdown of httpclient");
236+
new Thread(syncManager::shutdown).start();
237+
_log.info("Successful shutdown of syncManager");
230238
} catch (IOException e) {
231239
_log.error("We could not shutdown split", e);
232240
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.split.engine.common;
2+
3+
import java.util.concurrent.atomic.AtomicInteger;
4+
5+
import static com.google.common.base.Preconditions.checkNotNull;
6+
7+
public class Backoff {
8+
private static final long BACKOFF_MAX_SECONDS_ALLOWED = 1800;
9+
10+
private final long _backoffBase;
11+
private AtomicInteger _attempt;
12+
13+
public Backoff(long backoffBase) {
14+
_backoffBase = checkNotNull(backoffBase);
15+
_attempt = new AtomicInteger(0);
16+
}
17+
18+
public long interval() {
19+
long interval = _backoffBase * (long) Math.pow(2, _attempt.getAndIncrement());
20+
21+
return interval >= BACKOFF_MAX_SECONDS_ALLOWED ? BACKOFF_MAX_SECONDS_ALLOWED : interval;
22+
}
23+
24+
public synchronized void reset() {
25+
_attempt.set(0);
26+
}
27+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package io.split.engine.common;
2+
3+
public interface PushManager {
4+
5+
enum Status {
6+
STREAMING_READY,
7+
STREAMING_BACKOFF,
8+
STREAMING_DOWN,
9+
STREAMING_OFF
10+
}
11+
12+
void start();
13+
void stop();
14+
void startWorkers();
15+
void stopWorkers();
16+
}

0 commit comments

Comments
 (0)