io.split.client.SplitClientConfig Maven / Gradle / Ivy
package io.split.client;
import java.io.IOException;
import java.util.Properties;
/**
* Configurations for the SplitClient.
*
* @author adil
*/
public class SplitClientConfig {
private final String _endpoint;
private final String _eventsEndpoint;
private final int _featuresRefreshRate;
private final int _segmentsRefreshRate;
private final int _impressionsRefreshRate;
private final int _metricsRefreshRate;
private final int _connectionTimeout;
private final int _readTimeout;
private final int _numThreadsForSegmentFetch;
private final boolean _debugEnabled;
private final int _ready;
// To be set during startup
public static String splitSdkVersion;
public static Builder builder() {
return new Builder();
}
private SplitClientConfig(String endpoint,
String eventsEndpoint,
int pollForFeatureChangesEveryNSeconds,
int segmentsRefreshRate,
int impressionsRefreshRate,
int metricsRefreshRate,
int connectionTimeout,
int readTimeout,
int numThreadsForSegmentFetch,
int ready,
boolean debugEnabled) {
_endpoint = endpoint;
_eventsEndpoint = eventsEndpoint;
_featuresRefreshRate = pollForFeatureChangesEveryNSeconds;
_segmentsRefreshRate = segmentsRefreshRate;
_impressionsRefreshRate = impressionsRefreshRate;
_metricsRefreshRate = metricsRefreshRate;
_connectionTimeout = connectionTimeout;
_readTimeout = readTimeout;
_numThreadsForSegmentFetch = numThreadsForSegmentFetch;
_ready = ready;
_debugEnabled = debugEnabled;
Properties props = new Properties();
try {
props.load(this.getClass().getClassLoader().getResourceAsStream("version.properties"));
} catch (IOException e) {
throw new RuntimeException("cannot find client version in classpath");
}
splitSdkVersion = "java-"+ (String) props.getOrDefault("sdk.version", "undefined");
}
public String endpoint() {
return _endpoint;
}
public String eventsEndpoint() {
return _eventsEndpoint;
}
public int featuresRefreshRate() {
return _featuresRefreshRate;
}
public int segmentsRefreshRate() {
return _segmentsRefreshRate;
}
public int numThreadsForSegmentFetch() {return _numThreadsForSegmentFetch;}
public int impressionsRefreshRate() {
return _impressionsRefreshRate;
}
public int metricsRefreshRate() {return _metricsRefreshRate;}
public int connectionTimeout() {
return _connectionTimeout;
}
public int readTimeout() {
return _readTimeout;
}
public boolean debugEnabled() { return _debugEnabled; }
public int blockUntilReady() { return _ready; }
public static final class Builder {
private String _endpoint = "https://sdk.split.io/api";
private boolean _endpointSet = false;
private String _eventsEndpoint = "https://events.split.io/api";
private boolean _eventsEndpointSet = false;
private int _featuresRefreshRate = 60;
private int _segmentsRefreshRate = 60;
private int _impressionsRefreshRate = 60;
private int _connectionTimeout = 15000;
private int _readTimeout = 15000;
private int _numThreadsForSegmentFetch = 2;
private boolean _debugEnabled = false;
private int _ready = -1; // -1 means no blocking
private int _metricsRefreshRate = 60;
public Builder() {}
/**
* The rest endpoint that sdk will hit for latest features and segments.
*
* @param endpoint MUST NOT be null
*
* @return
*/
public Builder endpoint(String endpoint) {
_endpoint = endpoint;
_endpointSet = true;
return this;
}
/**
* The rest endpoint that sdk will hit for impressions and metrics.
*
* @param eventsEndpoint MUST NOT be null
*
* @return
*/
public Builder eventsEndpoint(String eventsEndpoint) {
_eventsEndpoint = eventsEndpoint;
_eventsEndpointSet = true;
return this;
}
/**
* The SDK will poll the endpoint for changes to features at this period.
*
* Implementation Note: The SDK actually polls at a random interval
* chosen between (0.5 * n, n). This is to ensure that
* SDKs that are deployed simultaneously on different machines do not
* inundate the backend with requests at the same interval.
*
*
* @param n MUST be greater than 0. Default value is 60.
* @return
*
* @Deprecated use featuresRefreshRate(sec) instead
*/
@Deprecated
public Builder pollForFeatureChangesEveryNSeconds(int n) {
return featuresRefreshRate(n);
}
/**
* The SDK will poll the endpoint for changes to features at this period.
*
* Implementation Note: The SDK actually polls at a random interval
* chosen between (0.5 * n, n). This is to ensure that
* SDKs that are deployed simultaneously on different machines do not
* inundate the backend with requests at the same interval.
*
*
* @param seconds MUST be greater than 0. Default value is 60.
* @return
*
* @Deprecated use featuresRefreshRate(sec) instead
*/
public Builder featuresRefreshRate(int seconds) {
_featuresRefreshRate = seconds;
return this;
}
/**
* The SDK will poll the endpoint for changes to segments at this period in seconds.
*
* Implementation Note: The SDK actually polls at a random interval
* chosen between (0.5 * n, n). This is to ensure that
* SDKs that are deployed simultaneously on different machines do not
* inundate the backend with requests at the same interval.
*
*
* @param n MUST be greater than 0. Default value is 60.
* @return
*
* @Deprecated use segmentsRefreshRate(seconds) instead
*/
@Deprecated
public Builder pollForSegmentChangesEveryNSeconds(int n) {
return segmentsRefreshRate(n);
}
/**
* The SDK will poll the endpoint for changes to segments at this period in seconds.
*
* Implementation Note: The SDK actually polls at a random interval
* chosen between (0.5 * n, n). This is to ensure that
* SDKs that are deployed simultaneously on different machines do not
* inundate the backend with requests at the same interval.
*
*
* @param seconds MUST be greater than 0. Default value is 60.
* @return
*/
public Builder segmentsRefreshRate(int seconds) {
_segmentsRefreshRate = seconds;
return this;
}
/**
* The treatment log captures the which key saw what treatment ("on", "off", etc)
* at what time. This log is periodically pushed back to split endpoint.
* This parameter controls how quickly does the cache expire after a write.
*
* This is an ADVANCED parameter
*
* @param n MUST be > 0.
*
* @return
*
* @Deprecated use impressionsRefreshRate(seconds) instead
*/
@Deprecated public Builder treatmentLogCacheExpireNSecondsAfterWrite(int n) {
return impressionsRefreshRate(n);
}
/**
* The treatment log captures the which key saw what treatment ("on", "off", etc)
* at what time. This log is periodically pushed back to split endpoint.
* This parameter controls how quickly does the cache expire after a write.
*
* This is an ADVANCED parameter
*
* @param seconds MUST be > 0.
*
* @return
*/
public Builder impressionsRefreshRate(int seconds) {
_impressionsRefreshRate = seconds;
return this;
}
/**
* The diagnostic metrics collected by the SDK are pushed back to split endpoint
* at this period.
*
* This is an ADVANCED parameter
*
* @param seconds MUST be > 0.
*
* @return
*/
public Builder metricsRefreshRate(int seconds) {
_metricsRefreshRate = seconds;
return this;
}
/**
* Http client connection timeout. Default value is 15000ms.
* @param ms MUST be greater than 0.
*
* @return Builder
*
* @Deprecated use connectionTimeout(long) instead
*/
@Deprecated
public Builder connectionTimeoutInMs(int ms) {
return connectionTimeout(ms);
}
public Builder connectionTimeout(int ms) {
_connectionTimeout = ms;
return this;
}
/**
* Http client read timeout. Default value is 15000ms.
* @param ms MUST be greater than 0.
*
* @return this Builder instance
*
* @Deprecated use readTimeout instead
*/
@Deprecated
public Builder readTimeoutInMs(int ms) {
return readTimeout(ms);
}
public Builder readTimeout(int ms) {
_readTimeout = ms;
return this;
}
public Builder enableDebug() {
_debugEnabled = true;
return this;
}
/**
* The SDK fetches segment memberships on a schedule in an
* asynchrnonous manner. This parameter controls the number of
* threads in that thread pool.
*
* @param numThreads MUST BE greater than 0;
*
* @return this Builder instance
*
* @Deprecated this config will not be supported in future releases
*/
@Deprecated
public Builder numThreadsForSegmentFetch(int numThreads) {
_numThreadsForSegmentFetch = numThreads;
return this;
}
/**
* The SDK kicks off background threads to download data necessary
* for using the SDK. You can choose to block until the SDK has
* downloaded split definitions so that you will not get
* the 'control' treatment.
*
*
* If this parameter is set to a non-negative value, the SDK
* will block for that number of milliseconds for the data to be downloaded.
*
*
* If the download is not successful in this time period, a TimeOutException
* will be thrown.
*
*
* A negative value implies that the SDK building MUST NOT block. In this
* scenario, the SDK might return the 'control' treatment until the
* desired data has been downloaded.
*
* @param milliseconds MUST BE greater than or equal to 0;
*
* @return
*/
public Builder ready(int milliseconds) {
_ready = milliseconds;
return this;
}
public SplitClientConfig build() {
if (_featuresRefreshRate <= 0) {
throw new IllegalArgumentException("featuresRefreshRate must be > 0: " + _featuresRefreshRate);
}
if (_segmentsRefreshRate <= 0) {
throw new IllegalArgumentException("segmentsRefreshRate must be > 0: " + _segmentsRefreshRate);
}
if (_impressionsRefreshRate <= 0) {
throw new IllegalArgumentException("impressionsRefreshRate must be > 0: " + _impressionsRefreshRate);
}
if (_connectionTimeout <= 0) {
throw new IllegalArgumentException("connectionTimeOutInMs must be > 0: " + _connectionTimeout);
}
if (_readTimeout <= 0) {
throw new IllegalArgumentException("readTimeout must be > 0: " + _readTimeout);
}
if (_endpoint == null) {
throw new IllegalArgumentException("endpoint must not be null");
}
if (_eventsEndpoint == null) {
throw new IllegalArgumentException("events endpoint must not be null");
}
if (_endpointSet && !_eventsEndpointSet) {
throw new IllegalArgumentException("If endpoint is set, you must also set the events endpoint");
}
if (_numThreadsForSegmentFetch <= 0) {
throw new IllegalArgumentException("Number of threads for fetching segments MUST be greater than zero");
}
return new SplitClientConfig(
_endpoint,
_eventsEndpoint,
_featuresRefreshRate,
_segmentsRefreshRate,
_impressionsRefreshRate,
_metricsRefreshRate,
_connectionTimeout,
_readTimeout,
_numThreadsForSegmentFetch,
_ready,
_debugEnabled);
}
}
}