diff --git a/pom.xml b/pom.xml
index 4ec8cbf..c3fd395 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,7 +6,7 @@
com.featureprobe
server-sdk-java
- 1.2.0
+ 1.2.1
server-sdk-java
https://github.com/FeatureProbe/server-sdk-java
FeatureProbe Server Side SDK for Java
diff --git a/src/main/java/com/featureprobe/sdk/server/DefaultEventProcessor.java b/src/main/java/com/featureprobe/sdk/server/DefaultEventProcessor.java
index b3b17f8..0ab9d77 100644
--- a/src/main/java/com/featureprobe/sdk/server/DefaultEventProcessor.java
+++ b/src/main/java/com/featureprobe/sdk/server/DefaultEventProcessor.java
@@ -29,8 +29,6 @@ public class DefaultEventProcessor implements EventProcessor {
private static final Logger logger = Loggers.EVENT;
- private static final String GET_SDK_KEY_HEADER = "Authorization";
-
private static final int EVENT_BATCH_HANDLE_SIZE = 50;
private final AtomicBoolean closed = new AtomicBoolean(false);
@@ -159,7 +157,6 @@ private static final class SendEventsTask implements Runnable {
SendEventsTask(FPContext context, List repositories) {
this.apiUrl = context.getEventUrl();
- Headers.Builder headerBuilder = new Headers.Builder();
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.connectionPool(context.getHttpConfiguration().connectionPool)
.connectTimeout(context.getHttpConfiguration().connectTimeout)
@@ -167,7 +164,7 @@ private static final class SendEventsTask implements Runnable {
.writeTimeout(context.getHttpConfiguration().writeTimeout)
.retryOnConnectionFailure(false);
httpClient = builder.build();
- headers = headerBuilder.add(GET_SDK_KEY_HEADER, context.getServerSdkKey()).build();
+ headers = context.getHeaders();
this.repositories = repositories;
}
diff --git a/src/main/java/com/featureprobe/sdk/server/FPContext.java b/src/main/java/com/featureprobe/sdk/server/FPContext.java
index b1e7463..e15e878 100644
--- a/src/main/java/com/featureprobe/sdk/server/FPContext.java
+++ b/src/main/java/com/featureprobe/sdk/server/FPContext.java
@@ -1,7 +1,9 @@
package com.featureprobe.sdk.server;
+import okhttp3.Headers;
import org.slf4j.Logger;
+import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.time.Duration;
@@ -11,6 +13,14 @@ final class FPContext {
private static final Logger logger = Loggers.MAIN;
+ private static final String GET_SDK_KEY_HEADER = "Authorization";
+
+ private static final String USER_AGENT_HEADER = "user-agent";
+
+ private static final String DEFAULT_SDK_VERSION = "unknown";
+
+ private static final String SDK_FLAG_PREFIX = "Java/";
+
private static final String GET_REPOSITORY_DATA_API = "/api/server-sdk/toggles";
private static final String POST_EVENTS_DATA_API = "/api/events";
@@ -27,6 +37,8 @@ final class FPContext {
private final HttpConfiguration httpConfiguration;
+ private final Headers headers;
+
FPContext(String serverSdkKey, FPConfig config) {
try {
if (Objects.isNull(config.synchronizerUrl)) {
@@ -46,6 +58,16 @@ final class FPContext {
this.refreshInterval = config.refreshInterval;
this.location = config.location;
this.httpConfiguration = config.httpConfiguration;
+ String sdkVersion = DEFAULT_SDK_VERSION;
+ try {
+ sdkVersion = Utils.readSdkVersion();
+ } catch (IOException e) {
+ logger.error("read sdk version error", e);
+ }
+ this.headers = config.httpConfiguration.headers.newBuilder()
+ .add(GET_SDK_KEY_HEADER, serverSdkKey)
+ .add(USER_AGENT_HEADER, SDK_FLAG_PREFIX + sdkVersion)
+ .build();
}
public URL getSynchronizerUrl() {
@@ -71,4 +93,8 @@ public String getLocation() {
public HttpConfiguration getHttpConfiguration() {
return httpConfiguration;
}
+
+ public Headers getHeaders() {
+ return headers;
+ }
}
diff --git a/src/main/java/com/featureprobe/sdk/server/HttpConfiguration.java b/src/main/java/com/featureprobe/sdk/server/HttpConfiguration.java
index 962d9af..2f5be0b 100644
--- a/src/main/java/com/featureprobe/sdk/server/HttpConfiguration.java
+++ b/src/main/java/com/featureprobe/sdk/server/HttpConfiguration.java
@@ -1,6 +1,7 @@
package com.featureprobe.sdk.server;
import okhttp3.ConnectionPool;
+import okhttp3.Headers;
import java.time.Duration;
import java.util.concurrent.TimeUnit;
@@ -26,11 +27,14 @@ public final class HttpConfiguration {
final Duration writeTimeout;
+ final Headers headers;
+
protected HttpConfiguration(Builder builder) {
this.connectionPool = Builder.connectionPool;
this.connectTimeout = Builder.connectTimeout;
this.readTimeout = Builder.readTimeout;
this.writeTimeout = Builder.writeTimeout;
+ this.headers = Builder.headers;
}
public static Builder builder() {
@@ -47,9 +51,16 @@ public static class Builder {
private static Duration writeTimeout = DEFAULT_WRITE_TIMEOUT;
+ private static Headers headers = new Headers.Builder().build();
+
public Builder() {
}
+ public Builder headers(Headers headers) {
+ Builder.headers = headers == null ? new Headers.Builder().build() : headers;
+ return this;
+ }
+
public Builder connectionPool(ConnectionPool connectionPool) {
Builder.connectionPool = connectionPool == null ? DEFAULT_CONNECTION_POOL : connectionPool;
return this;
diff --git a/src/main/java/com/featureprobe/sdk/server/PollingSynchronizer.java b/src/main/java/com/featureprobe/sdk/server/PollingSynchronizer.java
index 93f8eee..d1810ad 100644
--- a/src/main/java/com/featureprobe/sdk/server/PollingSynchronizer.java
+++ b/src/main/java/com/featureprobe/sdk/server/PollingSynchronizer.java
@@ -47,8 +47,7 @@ final class PollingSynchronizer implements Synchronizer {
.readTimeout(context.getHttpConfiguration().readTimeout)
.writeTimeout(context.getHttpConfiguration().writeTimeout)
.retryOnConnectionFailure(false);
- Headers.Builder headerBuilder = new Headers.Builder();
- headers = headerBuilder.add(GET_SDK_KEY_HEADER, context.getServerSdkKey()).build();
+ headers = context.getHeaders();
httpClient = builder.build();
}
diff --git a/src/main/java/com/featureprobe/sdk/server/Utils.java b/src/main/java/com/featureprobe/sdk/server/Utils.java
new file mode 100644
index 0000000..578f905
--- /dev/null
+++ b/src/main/java/com/featureprobe/sdk/server/Utils.java
@@ -0,0 +1,16 @@
+package com.featureprobe.sdk.server;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Properties;
+
+public class Utils {
+
+ public static String readSdkVersion() throws IOException {
+ InputStream in = Utils.class.getClassLoader().getResourceAsStream("main.properties");
+ Properties properties = new Properties();
+ properties.load(in);
+ return properties.getProperty("version");
+ }
+
+}
diff --git a/src/main/resources/main.properties b/src/main/resources/main.properties
new file mode 100644
index 0000000..1ffae3f
--- /dev/null
+++ b/src/main/resources/main.properties
@@ -0,0 +1 @@
+version='@project.version@'
\ No newline at end of file
diff --git a/src/test/groovy/com/featureprobe/sdk/server/FeatureProbeSpec.groovy b/src/test/groovy/com/featureprobe/sdk/server/FeatureProbeSpec.groovy
index e4ee7e7..649d948 100644
--- a/src/test/groovy/com/featureprobe/sdk/server/FeatureProbeSpec.groovy
+++ b/src/test/groovy/com/featureprobe/sdk/server/FeatureProbeSpec.groovy
@@ -41,7 +41,7 @@ class FeatureProbeSpec extends Specification {
try {
featureProbe = new FeatureProbe("foo")
} catch (Exception ignored) {
- fail("ctor should not fail with not empty sdk key")
+ fail("should not fail with not empty sdk key")
}
}