diff --git a/README.md b/README.md
index d84e927dd..bcae8eed8 100644
--- a/README.md
+++ b/README.md
@@ -464,7 +464,7 @@ The `UnleashConfig$Builder` class (created via `UnleashConfig.builder()`) expose
| `enableProxyAuthenticationByJvmProperties` | Enable support for [using JVM properties for HTTP proxy authentication](#http-proxy-with-authentication). | No | `false` |
| `environment` | The value to set for the Unleash context's `environment` property. **Not** the same as [Unleash's environments](https://docs.getunleash.io/reference/environments).| No | `null` |
| `fallbackStrategy` | A strategy implementation that the client can use if it doesn't recognize the strategy type returned from the server. | No | `null` |
-| `fetchTogglesInterval` | How often (in seconds) the client should check for toggle updates. Set to `0` if you want to only check once. | No | `10` |
+| `fetchTogglesInterval` | How often (in seconds) the client should check for toggle updates. Set to `0` if you want to only check once. | No | `15` |
| `instanceId` | A unique(-ish) identifier for your instance. Typically a hostname, pod id or something similar. Unleash uses this to separate metrics from the client SDKs with the same `appName`. | Yes | `null` |
| `namePrefix` | If provided, the client will only fetch toggles whose name starts with the provided value. | No | `null` |
| `projectName` | If provided, the client will only fetch toggles from the specified project. (This can also be achieved with an API token). | No | `null` |
diff --git a/examples/cli-example/build.gradle.kts b/examples/cli-example/build.gradle.kts
index 8b56b34da..48de7314e 100644
--- a/examples/cli-example/build.gradle.kts
+++ b/examples/cli-example/build.gradle.kts
@@ -13,6 +13,6 @@ repositories {
}
dependencies {
- implementation("io.getunleash:unleash-client-java:7.1.0")
- implementation("ch.qos.logback:logback-classic:1.4.6")
+ implementation("io.getunleash:unleash-client-java:10.0.2")
+ implementation("ch.qos.logback:logback-classic:1.4.12")
}
diff --git a/examples/cli-example/gradle/wrapper/gradle-wrapper.properties b/examples/cli-example/gradle/wrapper/gradle-wrapper.properties
index 00e33edef..d6e308a63 100644
--- a/examples/cli-example/gradle/wrapper/gradle-wrapper.properties
+++ b/examples/cli-example/gradle/wrapper/gradle-wrapper.properties
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.1-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/examples/cli-example/src/main/java/io/getunleash/example/AdvancedConstraints.java b/examples/cli-example/src/main/java/io/getunleash/example/AdvancedConstraints.java
index 0faa50f83..4f5163cd2 100644
--- a/examples/cli-example/src/main/java/io/getunleash/example/AdvancedConstraints.java
+++ b/examples/cli-example/src/main/java/io/getunleash/example/AdvancedConstraints.java
@@ -3,8 +3,6 @@
import io.getunleash.DefaultUnleash;
import io.getunleash.Unleash;
import io.getunleash.UnleashContext;
-import io.getunleash.event.UnleashSubscriber;
-import io.getunleash.repository.FeatureToggleResponse;
import io.getunleash.util.UnleashConfig;
public class AdvancedConstraints {
@@ -15,38 +13,22 @@ public static void main(String[] args) throws InterruptedException {
.customHttpHeader(
"Authorization",
getOrElse("UNLEASH_API_TOKEN",
- "default:default.a45fede67f99b17f67312c93e00f448340e7af4ace2b0de2650f5a99"))
- .unleashAPI(getOrElse("UNLEASH_API_URL", "http://localhost:3063/api"))
+ "*:development.25a06b75248528f8ca93ce179dcdd141aedfb632231e0d21fd8ff349"))
+ .unleashAPI(getOrElse("UNLEASH_API_URL", "https://app.unleash-hosted.com/demo/api"))
.instanceId("java-example")
.synchronousFetchOnInitialisation(true)
- .sendMetricsInterval(30)
- .subscriber(
- new UnleashSubscriber() {
- @Override
- public void togglesFetched(
- FeatureToggleResponse toggleResponse) {
- System.out.println(toggleResponse);
- System.out.println(
- toggleResponse
- .getToggleCollection()
- .getFeatures()
- .size());
- }
- })
- .build();
+ .sendMetricsInterval(30).build();
+
Unleash unleash = new DefaultUnleash(config);
+ UnleashContext context = UnleashContext.builder()
+ .addProperty("semver", "1.5.2")
+ .build();
+ UnleashContext smallerSemver = UnleashContext.builder()
+ .addProperty("semver", "1.1.0")
+ .build();
while (true) {
- Thread.sleep(2000);
- UnleashContext context = UnleashContext.builder()
- .addProperty("semver", "1.5.2")
- .build();
- System.out.println(
- unleash.isEnabled("advanced.constraints", context)); // expect this to be true
- UnleashContext smallerSemver = UnleashContext.builder()
- .addProperty("semver", "1.1.0")
- .build();
- System.out.println(
- unleash.isEnabled("advanced.constraints", smallerSemver)); // expect this to be false
+ unleash.isEnabled("advanced.constraints", context); // expect this to be true
+ unleash.isEnabled("advanced.constraints", smallerSemver); // expect this to be false
}
}
diff --git a/pom.xml b/pom.xml
index e6ad8e57f..73e47892c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -3,7 +3,7 @@
4.0.0
io.getunleash
unleash-client-java
- 10.0.2
+ 10.1.0
2.0.13
diff --git a/src/main/java/io/getunleash/metric/ClientMetrics.java b/src/main/java/io/getunleash/metric/ClientMetrics.java
index 8b6bfdf85..cbc371f5c 100644
--- a/src/main/java/io/getunleash/metric/ClientMetrics.java
+++ b/src/main/java/io/getunleash/metric/ClientMetrics.java
@@ -11,6 +11,7 @@ public class ClientMetrics implements UnleashEvent {
private final String appName;
private final String instanceId;
+ private final String connectionId;
private final MetricsBucket bucket;
private final String environment;
private final String specVersion;
@@ -22,6 +23,7 @@ public class ClientMetrics implements UnleashEvent {
this.environment = config.getEnvironment();
this.appName = config.getAppName();
this.instanceId = config.getInstanceId();
+ this.connectionId = config.getConnectionId();
this.bucket = bucket;
this.specVersion = config.getClientSpecificationVersion();
this.platformName = System.getProperty("java.vm.name");
@@ -37,6 +39,10 @@ public String getInstanceId() {
return instanceId;
}
+ public String getConnectionId() {
+ return connectionId;
+ }
+
public MetricsBucket getBucket() {
return bucket;
}
@@ -71,6 +77,12 @@ public void publishTo(UnleashSubscriber unleashSubscriber) {
@Override
public String toString() {
- return "metrics:" + " appName=" + appName + " instanceId=" + instanceId;
+ return "metrics:"
+ + " appName="
+ + appName
+ + " instanceId="
+ + instanceId
+ + " connectionId="
+ + connectionId;
}
}
diff --git a/src/main/java/io/getunleash/metric/ClientRegistration.java b/src/main/java/io/getunleash/metric/ClientRegistration.java
index 8af6f0781..accddd5a7 100644
--- a/src/main/java/io/getunleash/metric/ClientRegistration.java
+++ b/src/main/java/io/getunleash/metric/ClientRegistration.java
@@ -11,6 +11,7 @@
public class ClientRegistration implements UnleashEvent {
private final String appName;
private final String instanceId;
+ private final String connectionId;
private final String sdkVersion;
private final Set strategies;
private final LocalDateTime started;
@@ -26,6 +27,7 @@ public class ClientRegistration implements UnleashEvent {
this.appName = config.getAppName();
this.instanceId = config.getInstanceId();
this.sdkVersion = config.getSdkVersion();
+ this.connectionId = config.getConnectionId();
this.started = started;
this.strategies = strategies;
this.interval = config.getSendMetricsInterval();
@@ -43,6 +45,10 @@ public String getInstanceId() {
return instanceId;
}
+ public String getConnectionId() {
+ return connectionId;
+ }
+
public String getSdkVersion() {
return sdkVersion;
}
diff --git a/src/main/java/io/getunleash/metric/DefaultHttpMetricsSender.java b/src/main/java/io/getunleash/metric/DefaultHttpMetricsSender.java
index 4a2ace288..19ce5a045 100644
--- a/src/main/java/io/getunleash/metric/DefaultHttpMetricsSender.java
+++ b/src/main/java/io/getunleash/metric/DefaultHttpMetricsSender.java
@@ -15,6 +15,7 @@
import java.time.Instant;
import java.time.LocalDateTime;
import java.util.concurrent.atomic.AtomicLong;
+import static io.getunleash.util.UnleashConfig.UNLEASH_INTERVAL;
public class DefaultHttpMetricsSender implements MetricSender {
@@ -82,6 +83,7 @@ private int post(URL url, Object o) throws UnleashException {
connection.setRequestMethod("POST");
connection.setRequestProperty("Accept", "application/json");
connection.setRequestProperty("Content-Type", "application/json");
+ connection.setRequestProperty(UNLEASH_INTERVAL, this.unleashConfig.getSendMetricsIntervalMillis());
UnleashConfig.setRequestProperties(connection, this.unleashConfig);
connection.setUseCaches(false);
connection.setDoInput(true);
diff --git a/src/main/java/io/getunleash/metric/OkHttpMetricsSender.java b/src/main/java/io/getunleash/metric/OkHttpMetricsSender.java
index ba4bd3399..1a1cbb414 100644
--- a/src/main/java/io/getunleash/metric/OkHttpMetricsSender.java
+++ b/src/main/java/io/getunleash/metric/OkHttpMetricsSender.java
@@ -19,6 +19,8 @@
import okhttp3.RequestBody;
import okhttp3.Response;
+import static io.getunleash.util.UnleashConfig.UNLEASH_INTERVAL;
+
public class OkHttpMetricsSender implements MetricSender {
private final UnleashConfig config;
private final MediaType JSON =
@@ -88,7 +90,9 @@ public int sendMetrics(ClientMetrics metrics) {
private int post(HttpUrl url, Object o) {
RequestBody body = RequestBody.create(gson.toJson(o), JSON);
- Request request = new Request.Builder().url(url).post(body).build();
+ Request request = new Request.Builder().url(url).post(body)
+ .addHeader(UNLEASH_INTERVAL, config.getSendMetricsIntervalMillis())
+ .build();
try (Response response = this.client.newCall(request).execute()) {
return response.code();
} catch (IOException ioEx) {
diff --git a/src/main/java/io/getunleash/repository/HttpFeatureFetcher.java b/src/main/java/io/getunleash/repository/HttpFeatureFetcher.java
index ea3bd61ac..ab3a0fbc1 100644
--- a/src/main/java/io/getunleash/repository/HttpFeatureFetcher.java
+++ b/src/main/java/io/getunleash/repository/HttpFeatureFetcher.java
@@ -15,6 +15,8 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import static io.getunleash.util.UnleashConfig.UNLEASH_INTERVAL;
+
public class HttpFeatureFetcher implements FeatureFetcher {
private static final Logger LOG = LoggerFactory.getLogger(HttpFeatureFetcher.class);
private Optional etag = Optional.empty();
@@ -35,6 +37,7 @@ public ClientFeaturesResponse fetchFeatures() throws UnleashException {
HttpURLConnection connection = null;
try {
connection = openConnection(this.toggleUrl);
+ connection.setRequestProperty(UNLEASH_INTERVAL, this.config.getFetchTogglesIntervalMillis());
connection.connect();
return getFeatureResponse(connection, true);
diff --git a/src/main/java/io/getunleash/repository/OkHttpFeatureFetcher.java b/src/main/java/io/getunleash/repository/OkHttpFeatureFetcher.java
index 281fd7bbe..d4f0d73e8 100644
--- a/src/main/java/io/getunleash/repository/OkHttpFeatureFetcher.java
+++ b/src/main/java/io/getunleash/repository/OkHttpFeatureFetcher.java
@@ -16,11 +16,15 @@
import okhttp3.Request;
import okhttp3.Response;
+import static io.getunleash.util.UnleashConfig.UNLEASH_INTERVAL;
+
public class OkHttpFeatureFetcher implements FeatureFetcher {
private final HttpUrl toggleUrl;
private final OkHttpClient client;
+ private final String interval;
public OkHttpFeatureFetcher(UnleashConfig unleashConfig) {
+ this.interval = unleashConfig.getFetchTogglesIntervalMillis();
File tempDir = null;
try {
tempDir = Files.createTempDirectory("http_cache").toFile();
@@ -50,6 +54,7 @@ public OkHttpFeatureFetcher(UnleashConfig unleashConfig) {
}
public OkHttpFeatureFetcher(UnleashConfig unleashConfig, OkHttpClient client) {
+ this.interval = unleashConfig.getFetchTogglesIntervalMillis();
this.client = OkHttpClientConfigurer.configureInterceptor(unleashConfig, client);
this.toggleUrl =
Objects.requireNonNull(
@@ -63,7 +68,9 @@ public OkHttpFeatureFetcher(UnleashConfig unleashConfig, OkHttpClient client) {
@Override
public ClientFeaturesResponse fetchFeatures() throws UnleashException {
- Request request = new Request.Builder().url(toggleUrl).get().build();
+ Request request = new Request.Builder().url(toggleUrl).get()
+ .addHeader(UNLEASH_INTERVAL, interval)
+ .build();
int code = 200;
try (Response response = client.newCall(request).execute()) {
if (response.isSuccessful()) {
diff --git a/src/main/java/io/getunleash/util/UnleashConfig.java b/src/main/java/io/getunleash/util/UnleashConfig.java
index 83e4d162c..030a5de72 100644
--- a/src/main/java/io/getunleash/util/UnleashConfig.java
+++ b/src/main/java/io/getunleash/util/UnleashConfig.java
@@ -28,6 +28,7 @@ public class UnleashConfig {
public static final String UNLEASH_INSTANCE_ID_HEADER = "UNLEASH-INSTANCEID";
public static final String UNLEASH_CONNECTION_ID_HEADER = "UNLEASH-CONNECTION-ID";
+ public static final String UNLEASH_INTERVAL = "UNLEASH-INTERVAL";
public static final String UNLEASH_APP_NAME_HEADER = "UNLEASH-APPNAME";
public static final String UNLEASH_SDK_HEADER = "UNLEASH-SDK";
@@ -216,7 +217,7 @@ public String getInstanceId() {
return instanceId;
}
- String getConnectionId() {
+ public String getConnectionId() {
return connectionId;
}
@@ -236,6 +237,14 @@ public long getFetchTogglesInterval() {
return fetchTogglesInterval;
}
+ public String getFetchTogglesIntervalMillis() {
+ return String.valueOf(fetchTogglesInterval * 1000);
+ }
+ public String getSendMetricsIntervalMillis() {
+ return String.valueOf(sendMetricsInterval * 1000);
+ }
+
+
public Duration getFetchTogglesConnectTimeout() {
return fetchTogglesConnectTimeout;
}
@@ -416,7 +425,7 @@ public static class Builder {
private @Nullable String backupFile;
private @Nullable String projectName;
private @Nullable String namePrefix;
- private long fetchTogglesInterval = 10;
+ private long fetchTogglesInterval = 15;
private Duration fetchTogglesConnectTimeout = Duration.ofSeconds(10);
diff --git a/src/test/java/io/getunleash/metric/DefaultHttpMetricsSenderTest.java b/src/test/java/io/getunleash/metric/DefaultHttpMetricsSenderTest.java
index 7f8be65e8..2f65c71ed 100644
--- a/src/test/java/io/getunleash/metric/DefaultHttpMetricsSenderTest.java
+++ b/src/test/java/io/getunleash/metric/DefaultHttpMetricsSenderTest.java
@@ -9,6 +9,8 @@
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static com.github.tomakehurst.wiremock.client.WireMock.verify;
import static com.github.tomakehurst.wiremock.core.WireMockConfiguration.wireMockConfig;
+import static io.getunleash.util.UnleashConfig.UNLEASH_CONNECTION_ID_HEADER;
+import static io.getunleash.util.UnleashConfig.UNLEASH_INTERVAL;
import com.github.tomakehurst.wiremock.junit5.WireMockExtension;
import io.getunleash.engine.MetricsBucket;
@@ -41,13 +43,14 @@ public void should_send_client_registration() throws URISyntaxException {
UnleashConfig config = UnleashConfig.builder().appName("test-app").unleashAPI(uri).build();
DefaultHttpMetricsSender sender = new DefaultHttpMetricsSender(config);
- sender.registerClient(
- new ClientRegistration(config, LocalDateTime.now(), new HashSet()));
+ sender.registerClient(new ClientRegistration(config, LocalDateTime.now(), new HashSet<>()));
verify(
postRequestedFor(urlMatching("/client/register"))
.withRequestBody(matching(".*appName.*"))
.withRequestBody(matching(".*strategies.*"))
+ .withHeader(
+ UNLEASH_CONNECTION_ID_HEADER, matching(config.getConnectionId()))
.withHeader("UNLEASH-APPNAME", matching("test-app")));
}
@@ -70,6 +73,10 @@ public void should_send_client_metrics() throws URISyntaxException {
postRequestedFor(urlMatching("/client/metrics"))
.withRequestBody(matching(".*appName.*"))
.withRequestBody(matching(".*bucket.*"))
+ .withHeader(
+ UNLEASH_INTERVAL, matching(config.getSendMetricsIntervalMillis()))
+ .withHeader(
+ UNLEASH_CONNECTION_ID_HEADER, matching(config.getConnectionId()))
.withHeader("UNLEASH-APPNAME", matching("test-app")));
}
@@ -81,7 +88,13 @@ public void should_handle_service_failure_when_sending_metrics() throws URISynta
.willReturn(aResponse().withStatus(500)));
URI uri = new URI("http://localhost:" + serverMock.getPort());
- UnleashConfig config = UnleashConfig.builder().appName("test-app").unleashAPI(uri).build();
+ long metricsInterval = 0;
+ UnleashConfig config =
+ UnleashConfig.builder()
+ .appName("test-app")
+ .unleashAPI(uri)
+ .sendMetricsInterval(metricsInterval)
+ .build();
DefaultHttpMetricsSender sender = new DefaultHttpMetricsSender(config);
MetricsBucket bucket = new MetricsBucket(Instant.now(), Instant.now(), null);
@@ -92,6 +105,7 @@ public void should_handle_service_failure_when_sending_metrics() throws URISynta
postRequestedFor(urlMatching("/client/metrics"))
.withRequestBody(matching(".*appName.*"))
.withRequestBody(matching(".*bucket.*"))
+ .withHeader(UNLEASH_INTERVAL, matching(String.valueOf(metricsInterval)))
.withHeader("UNLEASH-APPNAME", matching("test-app")));
}
}
diff --git a/src/test/java/io/getunleash/metric/UnleashMetricServiceImplTest.java b/src/test/java/io/getunleash/metric/UnleashMetricServiceImplTest.java
index a5e73a9c3..7f89da264 100644
--- a/src/test/java/io/getunleash/metric/UnleashMetricServiceImplTest.java
+++ b/src/test/java/io/getunleash/metric/UnleashMetricServiceImplTest.java
@@ -150,6 +150,7 @@ public void should_record_and_send_metrics() throws YggdrasilError {
assertThat(clientMetrics.getAppName()).isEqualTo(config.getAppName());
assertThat(clientMetrics.getEnvironment()).isEqualTo(config.getEnvironment());
assertThat(clientMetrics.getInstanceId()).isEqualTo(config.getInstanceId());
+ assertThat(clientMetrics.getConnectionId()).isEqualTo(config.getConnectionId());
assertThat(bucket.getStart()).isNotNull();
assertThat(bucket.getStop()).isNotNull();
assertThat(bucket.getToggles()).hasSize(2);
@@ -192,6 +193,7 @@ public void should_record_and_send_variant_metrics() throws YggdrasilError {
assertThat(clientMetrics.getAppName()).isEqualTo(config.getAppName());
assertThat(clientMetrics.getInstanceId()).isEqualTo(config.getInstanceId());
+ assertThat(clientMetrics.getConnectionId()).isEqualTo(config.getConnectionId());
assertThat(bucket.getStart()).isNotNull();
assertThat(bucket.getStop()).isNotNull();
assertThat(bucket.getToggles()).hasSize(1);
diff --git a/src/test/java/io/getunleash/repository/FeatureRepositoryTest.java b/src/test/java/io/getunleash/repository/FeatureRepositoryTest.java
index 828628bd4..52ffcc757 100644
--- a/src/test/java/io/getunleash/repository/FeatureRepositoryTest.java
+++ b/src/test/java/io/getunleash/repository/FeatureRepositoryTest.java
@@ -248,8 +248,8 @@ public void should_increase_to_max_interval_when_code(int code)
runner.assertThatFetchesAndReceives(ClientFeaturesResponse.Status.UNAVAILABLE, code);
assertThat(featureRepository.getFailures()).isEqualTo(1);
- assertThat(featureRepository.getSkips()).isEqualTo(30);
- for (int i = 0; i < 30; i++) {
+ assertThat(featureRepository.getSkips()).isEqualTo(20);
+ for (int i = 0; i < 20; i++) {
runner.assertThatSkipsNextRun();
}
assertThat(featureRepository.getFailures()).isEqualTo(1);
diff --git a/src/test/java/io/getunleash/util/UnleashConfigTest.java b/src/test/java/io/getunleash/util/UnleashConfigTest.java
index e0d08e551..d0aa38417 100644
--- a/src/test/java/io/getunleash/util/UnleashConfigTest.java
+++ b/src/test/java/io/getunleash/util/UnleashConfigTest.java
@@ -148,7 +148,6 @@ public void should_add_client_identification_headers_to_connection() throws IOEx
.appName(appName)
.instanceId(instanceId)
.unleashAPI(unleashAPI)
- .customHttpHeader(UNLEASH_CONNECTION_ID_HEADER, "ignore")
.build();
URL someUrl = new URL(unleashAPI + "/some/arbitrary/path");
@@ -157,7 +156,8 @@ public void should_add_client_identification_headers_to_connection() throws IOEx
UnleashConfig.setRequestProperties(connection, unleashConfig);
assertThat(connection.getRequestProperty(UNLEASH_APP_NAME_HEADER)).isEqualTo(appName);
assertThat(connection.getRequestProperty(UNLEASH_INSTANCE_ID_HEADER)).isEqualTo(instanceId);
- assertThat(connection.getRequestProperty(UNLEASH_CONNECTION_ID_HEADER)).hasSize(36);
+ assertThat(connection.getRequestProperty(UNLEASH_CONNECTION_ID_HEADER))
+ .isEqualTo(unleashConfig.getConnectionId());
assertThat(connection.getRequestProperty(UNLEASH_SDK_HEADER))
.isEqualTo("unleash-client-java:development");
assertThat(connection.getRequestProperty("User-Agent")).isEqualTo(appName);