diff --git a/README.md b/README.md
index 6efc253..a03295c 100644
--- a/README.md
+++ b/README.md
@@ -135,28 +135,29 @@ switcher.poolsize=2
### Configuration Properties Reference
-| Property | Required | Default | Description |
-|-------------------------------------|----------|---------|--------------------------------------------------------------------------------------|
-| `switcher.context` | ✅ | - | Fully qualified class name extending SwitcherContext |
-| `switcher.url` | ✅ | - | Switcher API endpoint URL |
-| `switcher.apikey` | ✅ | - | API key for authentication |
-| `switcher.component` | ✅ | - | Your application/component identifier |
-| `switcher.domain` | ✅ | - | Domain name in Switcher API |
-| `switcher.environment` | ❌ | default | Environment name (dev, staging, default) |
-| `switcher.local` | ❌ | false | Enable local-only mode |
-| `switcher.check` | ❌ | false | Validate switcher keys on startup |
-| `switcher.relay.restrict` | ❌ | true | Defines if client will trigger local snapshot relay verification |
-| `switcher.snapshot.location` | ❌ | - | Directory for snapshot files |
-| `switcher.snapshot.auto` | ❌ | false | Auto-load snapshots on startup |
-| `switcher.snapshot.skipvalidation` | ❌ | false | Skip snapshot validation on load |
-| `switcher.snapshot.updateinterval` | ❌ | - | Interval for automatic snapshot updates (e.g., "5s", "2m") |
-| `switcher.snapshot.watcher` | ❌ | false | Monitor snapshot files for changes |
-| `switcher.silent` | ❌ | - | Enable silent mode (e.g., "5s", "2m") |
-| `switcher.timeout` | ❌ | 3000 | API timeout in milliseconds |
-| `switcher.poolsize` | ❌ | 2 | Thread pool size for API calls |
-| `switcher.regextimeout` (v1-only) | ❌ | 3000 | Time in ms given to Timed Match Worker used for local Regex (ReDoS safety mechanism) |
-| `switcher.truststore.path` | ❌ | - | Path to custom truststore file |
-| `switcher.truststore.password` | ❌ | - | Password for custom truststore |
+| Property | Required | Default | Description |
+|------------------------------------|----------|---------|--------------------------------------------------------------------------------------|
+| `switcher.context` | ✅ | - | Fully qualified class name extending SwitcherContext |
+| `switcher.url` | ✅ | - | Switcher API endpoint URL |
+| `switcher.apikey` | ✅ | - | API key for authentication |
+| `switcher.component` | ✅ | - | Your application/component identifier |
+| `switcher.domain` | ✅ | - | Domain name in Switcher API |
+| `switcher.environment` | ❌ | default | Environment name (dev, staging, default) |
+| `switcher.local` | ❌ | false | Enable local-only mode |
+| `switcher.check` | ❌ | false | Validate switcher keys on startup |
+| `switcher.autorefreshtoken` | ❌ | false | Automatically refresh API token before expiration |
+| `switcher.relay.restrict` | ❌ | true | Defines if client will trigger local snapshot relay verification |
+| `switcher.snapshot.location` | ❌ | - | Directory for snapshot files |
+| `switcher.snapshot.auto` | ❌ | false | Auto-load snapshots on startup |
+| `switcher.snapshot.skipvalidation` | ❌ | false | Skip snapshot validation on load |
+| `switcher.snapshot.updateinterval` | ❌ | - | Interval for automatic snapshot updates (e.g., "5s", "2m") |
+| `switcher.snapshot.watcher` | ❌ | false | Monitor snapshot files for changes |
+| `switcher.silent` | ❌ | - | Enable silent mode (e.g., "5s", "2m") |
+| `switcher.timeout` | ❌ | 3000 | API timeout in milliseconds |
+| `switcher.poolsize` | ❌ | 2 | Thread pool size for API calls |
+| `switcher.regextimeout` (v1-only) | ❌ | 3000 | Time in ms given to Timed Match Worker used for local Regex (ReDoS safety mechanism) |
+| `switcher.truststore.path` | ❌ | - | Path to custom truststore file |
+| `switcher.truststore.password` | ❌ | - | Password for custom truststore |
> 💡 **Environment Variables**: Use `${ENV_VAR:default_value}` syntax for environment variable substitution.
diff --git a/pom.xml b/pom.xml
index addeb1e..ef77451 100644
--- a/pom.xml
+++ b/pom.xml
@@ -8,7 +8,7 @@
com.switcherapi
switcher-client
jar
- 2.5.3-SNAPSHOT
+ 2.6.0-SNAPSHOT
Switcher Client
Switcher Client SDK for working with Switcher API
diff --git a/src/main/java/com/switcherapi/client/ContextBuilder.java b/src/main/java/com/switcherapi/client/ContextBuilder.java
index f483ba0..6f49290 100644
--- a/src/main/java/com/switcherapi/client/ContextBuilder.java
+++ b/src/main/java/com/switcherapi/client/ContextBuilder.java
@@ -234,4 +234,9 @@ public ContextBuilder poolConnectionSize(Integer poolSize) {
Optional.ofNullable(poolSize).orElse(DEFAULT_POOL_SIZE));
return this;
}
+
+ public ContextBuilder autoRefreshToken(boolean autoRefreshToken) {
+ switcherProperties.setValue(ContextKey.AUTO_REFRESH_TOKEN, autoRefreshToken);
+ return this;
+ }
}
diff --git a/src/main/java/com/switcherapi/client/SwitcherConfig.java b/src/main/java/com/switcherapi/client/SwitcherConfig.java
index 0658c64..98b7b3c 100644
--- a/src/main/java/com/switcherapi/client/SwitcherConfig.java
+++ b/src/main/java/com/switcherapi/client/SwitcherConfig.java
@@ -12,6 +12,7 @@ abstract class SwitcherConfig {
protected boolean local;
protected boolean check;
+ protected boolean autoRefreshToken;
protected String silent;
protected Integer timeout;
protected Integer poolSize;
@@ -38,6 +39,7 @@ protected void updateSwitcherConfig(SwitcherProperties properties) {
setEnvironment(properties.getValue(ContextKey.ENVIRONMENT));
setLocal(properties.getBoolean(ContextKey.LOCAL_MODE));
setCheck(properties.getBoolean(ContextKey.CHECK_SWITCHERS));
+ setAutoRefreshToken(properties.getBoolean(ContextKey.AUTO_REFRESH_TOKEN));
setSilent(properties.getValue(ContextKey.SILENT_MODE));
setTimeout(properties.getInt(ContextKey.TIMEOUT_MS));
setPoolSize(properties.getInt(ContextKey.POOL_CONNECTION_SIZE));
@@ -105,6 +107,10 @@ public void setCheck(boolean check) {
this.check = check;
}
+ public void setAutoRefreshToken(boolean autoRefreshToken) {
+ this.autoRefreshToken = autoRefreshToken;
+ }
+
public void setSilent(String silent) {
this.silent = silent;
}
diff --git a/src/main/java/com/switcherapi/client/SwitcherContextBase.java b/src/main/java/com/switcherapi/client/SwitcherContextBase.java
index d4ae7f8..50e9f23 100644
--- a/src/main/java/com/switcherapi/client/SwitcherContextBase.java
+++ b/src/main/java/com/switcherapi/client/SwitcherContextBase.java
@@ -87,7 +87,8 @@ public abstract class SwitcherContextBase extends SwitcherConfig {
protected static Set switcherKeys;
protected static Map switchers;
protected static SwitcherExecutor switcherExecutor;
- private static ScheduledExecutorService scheduledExecutorService;
+ private static ScheduledExecutorService scheduledSnapshotExecutorService;
+ private static ScheduledExecutorService scheduledTokenExecutorService;
private static ExecutorService watcherExecutorService;
private static SnapshotWatcher watcherSnapshot;
protected static SwitcherContextBase contextBase;
@@ -111,6 +112,7 @@ protected void configureClient() {
.restrictRelay(relay.isRestrict())
.silentMode(silent)
.timeoutMs(timeout)
+ .autoRefreshToken(autoRefreshToken)
.poolConnectionSize(poolSize)
.snapshotLocation(snapshot.getLocation())
.snapshotAutoLoad(snapshot.isAuto())
@@ -197,9 +199,12 @@ public static void initializeClient() {
* @return SwitcherExecutor instance
*/
private static SwitcherExecutor buildInstance() {
+ initTokenExecutorService();
+
final ClientWS clientWS = initRemotePoolExecutorService();
final SwitcherValidator validatorService = new ValidatorService();
- final ClientRemote clientRemote = new ClientRemoteService(clientWS, switcherProperties);
+ final ClientRemote clientRemote = new ClientRemoteService(
+ clientWS, switcherProperties, scheduledTokenExecutorService);
final ClientLocal clientLocal = new ClientLocalService(validatorService);
if (contextBol(ContextKey.LOCAL_MODE)) {
@@ -306,7 +311,7 @@ public static ScheduledFuture> scheduleSnapshotAutoUpdate(String intervalValue
return null;
}
- if (Objects.nonNull(scheduledExecutorService)) {
+ if (Objects.nonNull(scheduledSnapshotExecutorService)) {
terminateSnapshotAutoUpdateWorker();
}
@@ -324,7 +329,7 @@ public static ScheduledFuture> scheduleSnapshotAutoUpdate(String intervalValue
};
initSnapshotExecutorService();
- return scheduledExecutorService.scheduleAtFixedRate(runnableSnapshotValidate, 0, interval, TimeUnit.MILLISECONDS);
+ return scheduledSnapshotExecutorService.scheduleAtFixedRate(runnableSnapshotValidate, 0, interval, TimeUnit.MILLISECONDS);
}
/**
@@ -339,10 +344,10 @@ public static ScheduledFuture> scheduleSnapshotAutoUpdate(String intervalValue
}
/**
- * Configure Executor Service for Snapshot Update Worker
+ * Configure Scheduled Executor Service for Snapshot Update Worker
*/
private static void initSnapshotExecutorService() {
- scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(r -> {
+ scheduledSnapshotExecutorService = Executors.newSingleThreadScheduledExecutor(r -> {
Thread thread = new Thread(r);
thread.setName(WorkerName.SNAPSHOT_UPDATE_WORKER.toString());
thread.setDaemon(true);
@@ -350,6 +355,18 @@ private static void initSnapshotExecutorService() {
});
}
+ /**
+ * Configure Scheduled Executor Service for Token Refresh Worker
+ */
+ private static void initTokenExecutorService() {
+ scheduledTokenExecutorService = Executors.newSingleThreadScheduledExecutor(r -> {
+ Thread thread = new Thread(r);
+ thread.setName(WorkerName.SWITCHER_TOKEN_WORKER.toString());
+ thread.setDaemon(true);
+ return thread;
+ });
+ }
+
/**
* Configure Executor Service for Snapshot Watch Worker
*/
@@ -538,9 +555,19 @@ public static void configure(ContextBuilder builder) {
* Cancel existing scheduled task for updating local Snapshot
*/
public static void terminateSnapshotAutoUpdateWorker() {
- if (Objects.nonNull(scheduledExecutorService)) {
- scheduledExecutorService.shutdownNow();
- scheduledExecutorService = null;
+ if (Objects.nonNull(scheduledSnapshotExecutorService)) {
+ scheduledSnapshotExecutorService.shutdownNow();
+ scheduledSnapshotExecutorService = null;
+ }
+ }
+
+ /**
+ * Cancel existing scheduled task for token refresh
+ */
+ public static void terminateTokenRefreshWorker() {
+ if (Objects.nonNull(scheduledTokenExecutorService)) {
+ scheduledTokenExecutorService.shutdownNow();
+ scheduledTokenExecutorService = null;
}
}
diff --git a/src/main/java/com/switcherapi/client/SwitcherPropertiesImpl.java b/src/main/java/com/switcherapi/client/SwitcherPropertiesImpl.java
index d6d74e7..8d18b06 100644
--- a/src/main/java/com/switcherapi/client/SwitcherPropertiesImpl.java
+++ b/src/main/java/com/switcherapi/client/SwitcherPropertiesImpl.java
@@ -30,6 +30,7 @@ private void initDefaults() {
setValue(ContextKey.LOCAL_MODE, false);
setValue(ContextKey.CHECK_SWITCHERS, false);
setValue(ContextKey.RESTRICT_RELAY, true);
+ setValue(ContextKey.AUTO_REFRESH_TOKEN, false);
}
@Override
@@ -49,6 +50,7 @@ public void loadFromProperties(Properties prop) {
setValue(ContextKey.LOCAL_MODE, getBoolDefault(resolveProperties(ContextKey.LOCAL_MODE.getParam(), prop), false));
setValue(ContextKey.CHECK_SWITCHERS, getBoolDefault(resolveProperties(ContextKey.CHECK_SWITCHERS.getParam(), prop), false));
setValue(ContextKey.RESTRICT_RELAY, getBoolDefault(resolveProperties(ContextKey.RESTRICT_RELAY.getParam(), prop), true));
+ setValue(ContextKey.AUTO_REFRESH_TOKEN, getBoolDefault(resolveProperties(ContextKey.AUTO_REFRESH_TOKEN.getParam(), prop), false));
setValue(ContextKey.REGEX_TIMEOUT, getIntDefault(resolveProperties(ContextKey.REGEX_TIMEOUT.getParam(), prop), DEFAULT_REGEX_TIMEOUT));
setValue(ContextKey.TRUSTSTORE_PATH, resolveProperties(ContextKey.TRUSTSTORE_PATH.getParam(), prop));
setValue(ContextKey.TRUSTSTORE_PASSWORD, resolveProperties(ContextKey.TRUSTSTORE_PASSWORD.getParam(), prop));
diff --git a/src/main/java/com/switcherapi/client/model/ContextKey.java b/src/main/java/com/switcherapi/client/model/ContextKey.java
index 1d1b3c1..e89d67e 100644
--- a/src/main/java/com/switcherapi/client/model/ContextKey.java
+++ b/src/main/java/com/switcherapi/client/model/ContextKey.java
@@ -109,8 +109,13 @@ public enum ContextKey {
/**
* (Number) Defines a fixed number of threads for the pool connection (default is 2).
*/
- POOL_CONNECTION_SIZE("switcher.poolsize");
-
+ POOL_CONNECTION_SIZE("switcher.poolsize"),
+
+ /**
+ * (boolean) Enables automatic refresh of authentication token (default is false)
+ */
+ AUTO_REFRESH_TOKEN("switcher.autorefreshtoken");
+
private final String param;
ContextKey(String param) {
diff --git a/src/main/java/com/switcherapi/client/remote/dto/AuthResponse.java b/src/main/java/com/switcherapi/client/remote/dto/AuthResponse.java
index 1ed8f6e..2196941 100644
--- a/src/main/java/com/switcherapi/client/remote/dto/AuthResponse.java
+++ b/src/main/java/com/switcherapi/client/remote/dto/AuthResponse.java
@@ -26,6 +26,10 @@ public boolean isExpired() {
return (this.exp * 1000) < System.currentTimeMillis();
}
+ public long getExp() {
+ return this.exp;
+ }
+
@Override
public String toString() {
return "AuthResponse{" +
diff --git a/src/main/java/com/switcherapi/client/service/WorkerName.java b/src/main/java/com/switcherapi/client/service/WorkerName.java
index 83f0720..8b75d6c 100644
--- a/src/main/java/com/switcherapi/client/service/WorkerName.java
+++ b/src/main/java/com/switcherapi/client/service/WorkerName.java
@@ -5,7 +5,8 @@ public enum WorkerName {
SNAPSHOT_WATCH_WORKER("switcherapi-snapshot-watcher"),
SNAPSHOT_UPDATE_WORKER("switcherapi-snapshot-update"),
SWITCHER_REMOTE_WORKER("switcherapi-remote-pool"),
- SWITCHER_ASYNC_WORKER("switcherapi-async");
+ SWITCHER_ASYNC_WORKER("switcherapi-async"),
+ SWITCHER_TOKEN_WORKER("switcherapi-token-refresh");
private final String name;
diff --git a/src/main/java/com/switcherapi/client/service/remote/ClientRemoteService.java b/src/main/java/com/switcherapi/client/service/remote/ClientRemoteService.java
index d094622..5e798dd 100644
--- a/src/main/java/com/switcherapi/client/service/remote/ClientRemoteService.java
+++ b/src/main/java/com/switcherapi/client/service/remote/ClientRemoteService.java
@@ -6,14 +6,24 @@
import com.switcherapi.client.exception.SwitcherRemoteException;
import com.switcherapi.client.model.ContextKey;
import com.switcherapi.client.model.criteria.Snapshot;
-import com.switcherapi.client.remote.dto.*;
import com.switcherapi.client.remote.ClientWS;
+import com.switcherapi.client.remote.dto.AuthResponse;
+import com.switcherapi.client.remote.dto.CriteriaRequest;
+import com.switcherapi.client.remote.dto.CriteriaResponse;
+import com.switcherapi.client.remote.dto.SnapshotVersionResponse;
+import com.switcherapi.client.remote.dto.SwitchersCheck;
import com.switcherapi.client.utils.SwitcherUtils;
import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import java.util.Date;
+import java.util.Objects;
import java.util.Optional;
import java.util.Set;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
/**
* @author Roger Floriano (petruki)
@@ -21,19 +31,27 @@
*/
public class ClientRemoteService implements ClientRemote {
+ private static final Logger log = LoggerFactory.getLogger(ClientRemoteService.class);
+
+ private final ScheduledExecutorService scheduledExecutorService;
+
private final SwitcherProperties switcherProperties;
-
+
private final ClientWS clientWs;
private AuthResponse authResponse;
+ private ScheduledFuture> refreshFuture;
+
private enum TokenStatus {
VALID, INVALID, SILENT
}
- public ClientRemoteService(ClientWS clientWs, SwitcherProperties switcherProperties) {
+ public ClientRemoteService(ClientWS clientWs, SwitcherProperties switcherProperties,
+ ScheduledExecutorService scheduledExecutorService) {
this.clientWs = clientWs;
this.switcherProperties = switcherProperties;
+ this.scheduledExecutorService = scheduledExecutorService;
}
@Override
@@ -92,7 +110,12 @@ public SwitchersCheck checkSwitchers(final Set switchers) {
private void auth(TokenStatus tokenStatus) {
if (tokenStatus == TokenStatus.INVALID) {
+ log.debug("Auth token is invalid or expired. Attempting to authenticate...");
this.authResponse = this.clientWs.auth().orElseGet(AuthResponse::new);
+
+ if (isAutoRefreshable()) {
+ scheduleNextAuth();
+ }
}
if (tokenStatus == TokenStatus.SILENT) {
@@ -109,7 +132,7 @@ private TokenStatus isTokenValid() throws SwitcherRemoteException,
return TokenStatus.INVALID;
}
- if (optAuthResponse.get().getToken().equals(ContextKey.SILENT_MODE.getParam())
+ if (ContextKey.SILENT_MODE.getParam().equals(optAuthResponse.get().getToken())
&& !optAuthResponse.get().isExpired()) {
return TokenStatus.SILENT;
}
@@ -129,4 +152,35 @@ private void setSilentModeExpiration() throws SwitcherInvalidDateTimeArgumentExc
}
}
+ private void scheduleNextAuth() {
+ long msUntilExpiry = (authResponse.getExp() * 1000L) - (System.currentTimeMillis());
+ long refreshAt = Math.max(msUntilExpiry - 5000, 0); // 5s before expiry
+
+ terminateAutoRefresh();
+ refreshFuture = scheduledExecutorService.schedule(() -> {
+ try {
+ log.debug("Auto-refreshing auth token...");
+ this.authResponse = this.clientWs.auth().orElseGet(AuthResponse::new);
+ scheduleNextAuth();
+ } catch (Exception e) {
+ log.error("Failed to auto-refresh auth token: {}", e.getMessage());
+ terminateAutoRefresh();
+ }
+ }, refreshAt, TimeUnit.MILLISECONDS);
+ }
+
+ private boolean isAutoRefreshable() {
+ return switcherProperties.getBoolean(ContextKey.AUTO_REFRESH_TOKEN) &&
+ (Objects.isNull(refreshFuture) || refreshFuture.isDone());
+ }
+
+ private void terminateAutoRefresh() {
+ if (Objects.nonNull(refreshFuture)) {
+ refreshFuture.cancel(true);
+ refreshFuture = null;
+ log.debug("Terminated existing auto-refresh task.");
+ }
+ }
}
+
+
diff --git a/src/test/java/com/switcherapi/client/SwitcherBasicCriteriaResponseTest.java b/src/test/java/com/switcherapi/client/SwitcherBasicCriteriaResponseTest.java
index bce8261..9ea0adf 100644
--- a/src/test/java/com/switcherapi/client/SwitcherBasicCriteriaResponseTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherBasicCriteriaResponseTest.java
@@ -24,7 +24,7 @@ class SwitcherBasicCriteriaResponseTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties(); // Load default properties from resources
Switchers.configure(ContextBuilder.builder() // Override default properties
@@ -40,7 +40,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@BeforeEach
diff --git a/src/test/java/com/switcherapi/client/SwitcherBasicTest.java b/src/test/java/com/switcherapi/client/SwitcherBasicTest.java
index ec6dba0..300166e 100644
--- a/src/test/java/com/switcherapi/client/SwitcherBasicTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherBasicTest.java
@@ -21,7 +21,7 @@ class SwitcherBasicTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties(); // Load default properties from resources
Switchers.configure(ContextBuilder.builder() // Override default properties
@@ -37,7 +37,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@BeforeEach
diff --git a/src/test/java/com/switcherapi/client/SwitcherConfigNativeTest.java b/src/test/java/com/switcherapi/client/SwitcherConfigNativeTest.java
index 1b696fa..f86277c 100644
--- a/src/test/java/com/switcherapi/client/SwitcherConfigNativeTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherConfigNativeTest.java
@@ -16,12 +16,12 @@ class SwitcherConfigNativeTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
}
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@Test
diff --git a/src/test/java/com/switcherapi/client/SwitcherContextRemoteExecutorTest.java b/src/test/java/com/switcherapi/client/SwitcherContextRemoteExecutorTest.java
index 66dfb78..6f85bd6 100644
--- a/src/test/java/com/switcherapi/client/SwitcherContextRemoteExecutorTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherContextRemoteExecutorTest.java
@@ -19,12 +19,12 @@ class SwitcherContextRemoteExecutorTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
}
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@Test
diff --git a/src/test/java/com/switcherapi/client/SwitcherFail1Test.java b/src/test/java/com/switcherapi/client/SwitcherFail1Test.java
index 77e2a37..1e197ab 100644
--- a/src/test/java/com/switcherapi/client/SwitcherFail1Test.java
+++ b/src/test/java/com/switcherapi/client/SwitcherFail1Test.java
@@ -21,7 +21,7 @@ class SwitcherFail1Test extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -30,7 +30,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
//clean generated outputs
SwitcherContext.stopWatchingSnapshot();
diff --git a/src/test/java/com/switcherapi/client/SwitcherFail2Test.java b/src/test/java/com/switcherapi/client/SwitcherFail2Test.java
index f8cbe96..217c369 100644
--- a/src/test/java/com/switcherapi/client/SwitcherFail2Test.java
+++ b/src/test/java/com/switcherapi/client/SwitcherFail2Test.java
@@ -21,7 +21,7 @@ class SwitcherFail2Test extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -30,7 +30,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@BeforeEach
diff --git a/src/test/java/com/switcherapi/client/SwitcherForceResolveTest.java b/src/test/java/com/switcherapi/client/SwitcherForceResolveTest.java
index d3629cf..f78c32d 100644
--- a/src/test/java/com/switcherapi/client/SwitcherForceResolveTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherForceResolveTest.java
@@ -1,6 +1,6 @@
package com.switcherapi.client;
-import com.switcherapi.Switchers;
+import com.switcherapi.SwitchersBase;
import com.switcherapi.client.model.SwitcherRequest;
import com.switcherapi.fixture.MockWebServerHelper;
import mockwebserver3.QueueDispatcher;
@@ -19,10 +19,13 @@ class SwitcherForceResolveTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
- Switchers.loadProperties(); // Load default properties from resources
- Switchers.configure(ContextBuilder.builder() // Override default properties
+ SwitchersBase.configure(ContextBuilder.builder(true) // Override default properties
+ .context(SwitchersBase.class.getName())
+ .domain("domain")
+ .apiKey("apiKey")
+ .component("component")
.url(String.format("http://localhost:%s", mockBackEnd.getPort()))
.local(true)
.snapshotLocation(SNAPSHOTS_LOCAL)
@@ -31,12 +34,12 @@ static void setup() throws IOException {
.snapshotAutoUpdateInterval(null)
.environment("fixture1"));
- Switchers.initializeClient();
+ SwitchersBase.initializeClient();
}
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@BeforeEach
@@ -46,7 +49,7 @@ void restoreStubs() {
@Test
void shouldResolveLocally() {
- SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE11);
+ SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11);
assertTrue(switcher.remote(false).isItOn());
}
@@ -59,7 +62,7 @@ void shouldForceResolveRemotely() {
givenResponse(generateCriteriaResponse("false", false));
//test
- SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE11);
+ SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11);
assertFalse(switcher.remote(true).isItOn());
}
diff --git a/src/test/java/com/switcherapi/client/SwitcherLocal3Test.java b/src/test/java/com/switcherapi/client/SwitcherLocal3Test.java
index 52a23a1..347ea4f 100644
--- a/src/test/java/com/switcherapi/client/SwitcherLocal3Test.java
+++ b/src/test/java/com/switcherapi/client/SwitcherLocal3Test.java
@@ -5,6 +5,7 @@
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.stream.Stream;
import com.switcherapi.client.remote.ClientWS;
@@ -40,10 +41,13 @@ class SwitcherLocal3Test {
private static final String SNAPSHOTS_LOCAL = Paths.get(StringUtils.EMPTY).toAbsolutePath() + "/src/test/resources/snapshot";
private static ExecutorService executorService;
+
+ private static ScheduledExecutorService scheduledExecutorService;
@BeforeAll
static void setupContext() {
executorService = Executors.newSingleThreadExecutor();
+ scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
SwitcherContext.loadProperties();
SwitcherContext.configure(ContextBuilder.builder()
.snapshotLocation(SNAPSHOTS_LOCAL)
@@ -56,6 +60,7 @@ static void setupContext() {
@AfterAll
static void tearDown() {
executorService.shutdown();
+ scheduledExecutorService.shutdownNow();
}
static Stream failTestArguments() {
@@ -96,7 +101,7 @@ void localShouldCheckSwitchers() {
ClientWS clientWS = ClientWSImpl.build(switcherProperties, executorService, DEFAULT_TIMEOUT);
SwitcherValidator validatorService = new ValidatorService();
SwitcherLocalService switcherLocal = new SwitcherLocalService(
- new ClientRemoteService(clientWS, switcherProperties),
+ new ClientRemoteService(clientWS, switcherProperties, scheduledExecutorService),
new ClientLocalService(validatorService), switcherProperties);
switcherLocal.init();
@@ -114,7 +119,7 @@ void localShouldCheckSwitchers_notFound() {
ClientWS clientWS = ClientWSImpl.build(switcherProperties, executorService, DEFAULT_TIMEOUT);
SwitcherValidator validatorService = new ValidatorService();
SwitcherLocalService switcherLocal = new SwitcherLocalService(
- new ClientRemoteService(clientWS, switcherProperties),
+ new ClientRemoteService(clientWS, switcherProperties, scheduledExecutorService),
new ClientLocalService(validatorService), switcherProperties);
switcherLocal.init();
diff --git a/src/test/java/com/switcherapi/client/SwitcherRemoteAutoRefreshTokenTest.java b/src/test/java/com/switcherapi/client/SwitcherRemoteAutoRefreshTokenTest.java
new file mode 100644
index 0000000..948a954
--- /dev/null
+++ b/src/test/java/com/switcherapi/client/SwitcherRemoteAutoRefreshTokenTest.java
@@ -0,0 +1,98 @@
+package com.switcherapi.client;
+
+import com.switcherapi.SwitchersBase;
+import com.switcherapi.client.exception.SwitcherRemoteException;
+import com.switcherapi.client.model.SwitcherRequest;
+import com.switcherapi.fixture.CountDownHelper;
+import com.switcherapi.fixture.MockWebServerHelper;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import java.io.IOException;
+
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class SwitcherRemoteAutoRefreshTokenTest extends MockWebServerHelper {
+
+ @BeforeEach
+ void setup() throws IOException {
+ setupMockServer();
+ }
+
+ @AfterEach
+ void tearDown() {
+ tearDownMockServer();
+ SwitchersBase.terminateTokenRefreshWorker();
+ }
+
+ /**
+ * The scheduled refresh worker operates using a 5s buffer to trigger the refresh before the token expires,
+ * so we need to set the token expiration time accordingly to test the auto-refresh behavior.
+ */
+ @Test
+ void shouldAutoRefreshAuthToken() {
+ //auth - 1st (regular auth) - 2nd (scheduled refresh)
+ givenResponse(generateMockAuth(7)); // 5s buffer - 7s exp = 2s for async refresh
+ givenResponse(generateCriteriaResponse("true", false));
+ givenResponse(generateMockAuth(60));
+ givenResponse(generateCriteriaResponse("true", false));
+
+ //when
+ givenAutoRefreshToken(true);
+
+ //test
+ SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11);
+ assertTrue(switcher.isItOn());
+ CountDownHelper.wait(2);
+ assertTrue(switcher.isItOn());
+ }
+
+ @Test
+ void shouldNotAutoRefreshAuthTokenWhenDisabled() {
+ //auth - 1st (regular auth) - 2nd (regular auth)
+ givenResponse(generateMockAuth(1));
+ givenResponse(generateCriteriaResponse("true", false));
+ givenResponse(generateMockAuth(60));
+ givenResponse(generateCriteriaResponse("true", false));
+
+ //when
+ givenAutoRefreshToken(false);
+
+ //test
+ SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11);
+ assertTrue(switcher.isItOn());
+ CountDownHelper.wait(1);
+ assertTrue(switcher.isItOn());
+ }
+
+ @Test
+ void shouldNotAutoRefreshAuthTokenWhenAuthFails() {
+ //auth - 1st (regular auth) - 2nd (scheduled refresh)
+ givenResponse(generateMockAuth(7)); // 5s buffer - 6s exp = 1s for async refresh
+ givenResponse(generateCriteriaResponse("true", false));
+ givenResponse(generateStatusResponse("500"));
+
+ //when
+ givenAutoRefreshToken(true);
+
+ //test
+ SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11);
+ assertTrue(switcher.isItOn());
+ CountDownHelper.wait(2);
+ assertThrows(SwitcherRemoteException.class, switcher::isItOn);
+ }
+
+ private void givenAutoRefreshToken(boolean enabled) {
+ SwitchersBase.configure(ContextBuilder.builder(true)
+ .context(SwitchersBase.class.getName())
+ .url(String.format("http://localhost:%s", mockBackEnd.getPort()))
+ .domain("domain")
+ .apiKey("apiKey")
+ .component("component")
+ .autoRefreshToken(enabled));
+
+ SwitchersBase.initializeClient();
+ }
+}
diff --git a/src/test/java/com/switcherapi/client/SwitcherSilentModeTest.java b/src/test/java/com/switcherapi/client/SwitcherSilentModeTest.java
index 1b7d2a1..870695a 100644
--- a/src/test/java/com/switcherapi/client/SwitcherSilentModeTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherSilentModeTest.java
@@ -23,7 +23,7 @@ class SwitcherSilentModeTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -31,7 +31,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@BeforeEach
diff --git a/src/test/java/com/switcherapi/client/SwitcherSnapshotLookupTest.java b/src/test/java/com/switcherapi/client/SwitcherSnapshotLookupTest.java
index 07241d4..bd6694e 100644
--- a/src/test/java/com/switcherapi/client/SwitcherSnapshotLookupTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherSnapshotLookupTest.java
@@ -28,7 +28,7 @@ static void setup() throws IOException {
Files.deleteIfExists(Paths.get(RESOURCES_PATH + "/new_folder"));
Files.deleteIfExists(Paths.get(RESOURCES_PATH + "/generated_mock_default.json"));
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -36,7 +36,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() throws IOException {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
//clean generated outputs
SwitcherContext.stopWatchingSnapshot();
diff --git a/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationFailTest.java b/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationFailTest.java
index 42e6b8c..e72379b 100644
--- a/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationFailTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationFailTest.java
@@ -25,7 +25,7 @@ class SwitcherSnapshotValidationFailTest extends MockWebServerHelper {
static void setup() throws IOException {
Files.deleteIfExists(Paths.get(RESOURCES_PATH + "/not_accessible"));
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -33,7 +33,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
//clean generated outputs
SwitcherContext.stopWatchingSnapshot();
diff --git a/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationTest.java b/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationTest.java
index 5900e94..dcd4597 100644
--- a/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherSnapshotValidationTest.java
@@ -22,7 +22,7 @@ class SwitcherSnapshotValidationTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -30,7 +30,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
//clean generated outputs
SwitcherContext.stopWatchingSnapshot();
diff --git a/src/test/java/com/switcherapi/client/SwitcherThrottle1Test.java b/src/test/java/com/switcherapi/client/SwitcherThrottle1Test.java
index 75eb1de..7378d19 100644
--- a/src/test/java/com/switcherapi/client/SwitcherThrottle1Test.java
+++ b/src/test/java/com/switcherapi/client/SwitcherThrottle1Test.java
@@ -18,7 +18,7 @@ class SwitcherThrottle1Test extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getName())
@@ -33,7 +33,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@Test
@@ -54,7 +54,7 @@ void shouldReturnTrue_withThrottle() {
.checkValue("value")
.throttle(1000);
- for (int i = 0; i < 100; i++) {
+ for (int i = 0; i < 50; i++) {
assertTrue(switcher.isItOn());
}
diff --git a/src/test/java/com/switcherapi/client/SwitcherThrottle2Test.java b/src/test/java/com/switcherapi/client/SwitcherThrottle2Test.java
index 33d2783..c61804d 100644
--- a/src/test/java/com/switcherapi/client/SwitcherThrottle2Test.java
+++ b/src/test/java/com/switcherapi/client/SwitcherThrottle2Test.java
@@ -17,7 +17,7 @@ class SwitcherThrottle2Test extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
SwitchersBase.configure(ContextBuilder.builder(true)
.context(SwitchersBase.class.getName())
@@ -32,7 +32,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
}
@Test
diff --git a/src/test/java/com/switcherapi/client/SwitcherValidateTest.java b/src/test/java/com/switcherapi/client/SwitcherValidateTest.java
index eac35c3..e8dcb70 100644
--- a/src/test/java/com/switcherapi/client/SwitcherValidateTest.java
+++ b/src/test/java/com/switcherapi/client/SwitcherValidateTest.java
@@ -20,7 +20,7 @@ class SwitcherValidateTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -29,7 +29,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
//clean generated outputs
SwitcherContext.stopWatchingSnapshot();
diff --git a/src/test/java/com/switcherapi/client/remote/ClientRemoteTest.java b/src/test/java/com/switcherapi/client/remote/ClientRemoteTest.java
index c833481..7ac6436 100644
--- a/src/test/java/com/switcherapi/client/remote/ClientRemoteTest.java
+++ b/src/test/java/com/switcherapi/client/remote/ClientRemoteTest.java
@@ -29,6 +29,7 @@
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
import static com.switcherapi.client.remote.Constants.DEFAULT_TIMEOUT;
import static org.junit.jupiter.api.Assertions.*;
@@ -37,12 +38,15 @@ class ClientRemoteTest extends MockWebServerHelper {
private static ExecutorService executorService;
+ private static ScheduledExecutorService scheduledExecutorService;
+
private ClientRemote clientRemote;
@BeforeAll
static void setup() throws IOException {
executorService = Executors.newSingleThreadExecutor();
- MockWebServerHelper.setupMockServer();
+ scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -51,14 +55,16 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
executorService.shutdown();
+ scheduledExecutorService.shutdownNow();
}
@BeforeEach
void resetSwitcherContextState() {
SwitcherProperties switcherProperties = Switchers.getSwitcherProperties();
- clientRemote = new ClientRemoteService(ClientWSImpl.build(switcherProperties, executorService, DEFAULT_TIMEOUT), switcherProperties);
+ clientRemote = new ClientRemoteService(ClientWSImpl.build(switcherProperties, executorService, DEFAULT_TIMEOUT),
+ switcherProperties, scheduledExecutorService);
((QueueDispatcher) mockBackEnd.getDispatcher()).clear();
Switchers.configure(ContextBuilder.builder().checkSwitchers(false));
diff --git a/src/test/java/com/switcherapi/client/remote/ClientWSBuilderTest.java b/src/test/java/com/switcherapi/client/remote/ClientWSBuilderTest.java
index 96e2e00..2b05b9b 100644
--- a/src/test/java/com/switcherapi/client/remote/ClientWSBuilderTest.java
+++ b/src/test/java/com/switcherapi/client/remote/ClientWSBuilderTest.java
@@ -32,14 +32,14 @@ static void tearDown() {
@Test
void shouldCreateClientBuilder() {
- // given
+ //given
SwitcherContextBase.configure(ContextBuilder.builder()
.truststorePath("")
.truststorePassword(""));
SwitcherProperties properties = SwitcherContextBase.getSwitcherProperties();
- // test
+ //test
HttpClient.Builder clientBuilder = ClientWSBuilder.builder(executorService, properties);
assertNotNull(clientBuilder);
@@ -50,7 +50,7 @@ void shouldCreateClientBuilder() {
@Test
void shouldCreateClientBuilderSSL() {
- // given
+ //given
String truststorePath = Objects.requireNonNull(getClass().getClassLoader()
.getResource("keystore.jks")).getPath();
@@ -60,7 +60,7 @@ void shouldCreateClientBuilderSSL() {
SwitcherProperties properties = SwitcherContextBase.getSwitcherProperties();
- // test
+ //test
HttpClient.Builder clientBuilder = ClientWSBuilder.builder(executorService, properties);
assertNotNull(clientBuilder);
@@ -71,7 +71,7 @@ void shouldCreateClientBuilderSSL() {
@Test
void shouldNotCreateClientBuilderSSL_invalidKeystorePassword() {
- // given
+ //given
String truststorePath = Objects.requireNonNull(getClass().getClassLoader()
.getResource("keystore.jks")).getPath();
@@ -81,20 +81,20 @@ void shouldNotCreateClientBuilderSSL_invalidKeystorePassword() {
SwitcherProperties properties = SwitcherContextBase.getSwitcherProperties();
- // test
+ //test
assertThrows(SwitcherException.class, () -> ClientWSBuilder.builder(executorService, properties));
}
@Test
void shouldNotCreateClientBuilderSSL_invalidKeystorePath() {
- // given
+ //given
SwitcherContextBase.configure(ContextBuilder.builder()
.truststorePath("INVALID")
.truststorePassword("changeit"));
SwitcherProperties properties = SwitcherContextBase.getSwitcherProperties();
- // test
+ //test
assertThrows(SwitcherException.class, () -> ClientWSBuilder.builder(executorService, properties));
}
}
diff --git a/src/test/java/com/switcherapi/client/remote/ClientWSTest.java b/src/test/java/com/switcherapi/client/remote/ClientWSTest.java
index f0fdc9f..8653937 100644
--- a/src/test/java/com/switcherapi/client/remote/ClientWSTest.java
+++ b/src/test/java/com/switcherapi/client/remote/ClientWSTest.java
@@ -24,7 +24,7 @@ class ClientWSTest extends MockWebServerHelper {
@BeforeAll
static void setup() throws IOException {
executorService = Executors.newSingleThreadExecutor();
- MockWebServerHelper.setupMockServer();
+ setupMockServer();
Switchers.loadProperties();
Switchers.configure(ContextBuilder.builder().url(String.format("http://localhost:%s", mockBackEnd.getPort())));
@@ -33,7 +33,7 @@ static void setup() throws IOException {
@AfterAll
static void tearDown() {
- MockWebServerHelper.tearDownMockServer();
+ tearDownMockServer();
executorService.shutdown();
}
@@ -47,22 +47,22 @@ void resetSwitcherContextState() {
@Test
void shouldBeAlive() {
- // given
+ //given
ClientWS clientWS = ClientWSImpl.build(Switchers.getSwitcherProperties(), executorService, DEFAULT_TIMEOUT);
givenResponse(generateTimeOut(100));
- // test
+ //test
boolean response = clientWS.isAlive();
assertTrue(response);
}
@Test
void shouldTimeOut() {
- // given
+ //given
ClientWS clientWS = ClientWSImpl.build(Switchers.getSwitcherProperties(), executorService, DEFAULT_TIMEOUT);
givenResponse(generateTimeOut(3500));
- // test
+ //test
boolean response = clientWS.isAlive();
assertFalse(response);
}
@@ -72,7 +72,7 @@ void shouldExtendTimeOut() {
ClientWS clientWS = ClientWSImpl.build(Switchers.getSwitcherProperties(), executorService, 4000);
givenResponse(generateTimeOut(3500));
- // test
+ //test
boolean response = clientWS.isAlive();
assertTrue(response);
}
diff --git a/src/test/java/com/switcherapi/client/service/local/SwitcherLocalServiceTest.java b/src/test/java/com/switcherapi/client/service/local/SwitcherLocalServiceTest.java
index 4fc8307..d6ef92f 100644
--- a/src/test/java/com/switcherapi/client/service/local/SwitcherLocalServiceTest.java
+++ b/src/test/java/com/switcherapi/client/service/local/SwitcherLocalServiceTest.java
@@ -8,6 +8,7 @@
import java.nio.file.Paths;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.atomic.AtomicBoolean;
import com.switcherapi.client.SwitcherProperties;
@@ -31,12 +32,15 @@ class SwitcherLocalServiceTest {
private static final String SNAPSHOTS_LOCAL = Paths.get(StringUtils.EMPTY).toAbsolutePath() + "/src/test/resources";
private static ExecutorService executorService;
+
+ private static ScheduledExecutorService scheduledExecutorService;
private static SwitcherLocalService service;
@BeforeAll
static void init() {
executorService = Executors.newSingleThreadExecutor();
+ scheduledExecutorService = Executors.newSingleThreadScheduledExecutor();
SwitchersBase.configure(ContextBuilder.builder()
.context(SwitchersBase.class.getName())
.snapshotLocation(SNAPSHOTS_LOCAL)
@@ -47,13 +51,14 @@ static void init() {
ClientWS clientWS = ClientWSImpl.build(properties, executorService, DEFAULT_TIMEOUT);
SwitcherValidator validatorService = new ValidatorService();
service = new SwitcherLocalService(
- new ClientRemoteService(clientWS, properties),
+ new ClientRemoteService(clientWS, properties, scheduledExecutorService),
new ClientLocalService(validatorService), properties);
}
@AfterAll
static void tearDown() {
executorService.shutdown();
+ scheduledExecutorService.shutdownNow();
}
@Test
diff --git a/src/test/java/com/switcherapi/playground/ClientPlayground.java b/src/test/java/com/switcherapi/playground/ClientPlayground.java
index 0277ddd..3c797b7 100644
--- a/src/test/java/com/switcherapi/playground/ClientPlayground.java
+++ b/src/test/java/com/switcherapi/playground/ClientPlayground.java
@@ -19,18 +19,16 @@ public class ClientPlayground {
public static void test() {
new Features().configureClient();
- Switcher switcher = getSwitcher(CLIENT_JAVA_FEATURE)
- .bypassMetrics();
+ Switcher switcher = getSwitcher(CLIENT_JAVA_FEATURE).bypassMetrics();
scheduler.scheduleAtFixedRate(() -> {
try {
long time = System.currentTimeMillis();
- logger.info("Switcher is on: {}", switcher.isItOn());
- logger.info("Time elapsed: {}", System.currentTimeMillis() - time);
+ logger.info("Switcher is on: {} - {} ms", switcher.isItOn(), System.currentTimeMillis() - time);
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
- }, 0, 5, TimeUnit.SECONDS);
+ }, 0, 500, TimeUnit.MILLISECONDS);
}
public static void main(String[] args) {
diff --git a/src/test/java/com/switcherapi/playground/Features.java b/src/test/java/com/switcherapi/playground/Features.java
index 6d8a728..e7a4299 100644
--- a/src/test/java/com/switcherapi/playground/Features.java
+++ b/src/test/java/com/switcherapi/playground/Features.java
@@ -13,12 +13,11 @@ public class Features extends SwitcherContextBase {
protected void configureClient() {
configure(ContextBuilder.builder()
.context(Features.class.getName())
- .url("https://api.switcherapi.com")
+ .url("http://localhost:3001")
.apiKey(System.getenv("switcher.api.key"))
.component(System.getenv("switcher.component"))
.domain(System.getenv("switcher.domain"))
- .local(true)
- .snapshotLocation("./src/test/resources/snapshot/playground"));
+ .autoRefreshToken(true));
initializeClient();
}