diff --git a/pom.xml b/pom.xml index 9daa9093..f33872e2 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ com.github.switcherapi switcher-client jar - 2.0.4 + 2.0.5-SNAPSHOT Switcher Client Switcher Client SDK for working with Switcher API diff --git a/src/main/java/com/github/switcherapi/client/SnapshotCallback.java b/src/main/java/com/github/switcherapi/client/SnapshotCallback.java new file mode 100644 index 00000000..f19cf867 --- /dev/null +++ b/src/main/java/com/github/switcherapi/client/SnapshotCallback.java @@ -0,0 +1,31 @@ +package com.github.switcherapi.client; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +public class SnapshotCallback { + + private static final Logger logger = LogManager.getLogger(SnapshotCallback.class); + + /** + * Callback method that will be invoked when the snapshot is updated + * + * @param version of the new snapshot + */ + public void onSnapshotUpdate(long version) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Snapshot updated: %s", version)); + } + } + + /** + * Callback method that will be invoked when the snapshot update fails + * + * @param e Exception + */ + public void onSnapshotUpdateError(Exception e) { + if (logger.isDebugEnabled()) { + logger.debug(String.format("Failed to update snapshot: %s", e.getMessage())); + } + } +} diff --git a/src/main/java/com/github/switcherapi/client/SwitcherContext.java b/src/main/java/com/github/switcherapi/client/SwitcherContext.java index 84d4a35f..1113bbea 100644 --- a/src/main/java/com/github/switcherapi/client/SwitcherContext.java +++ b/src/main/java/com/github/switcherapi/client/SwitcherContext.java @@ -1,7 +1,5 @@ package com.github.switcherapi.client; -import com.github.switcherapi.client.exception.SwitcherKeyNotFoundException; -import com.github.switcherapi.client.exception.SwitchersValidationException; import com.github.switcherapi.client.model.ContextKey; import com.github.switcherapi.client.model.Switcher; @@ -37,20 +35,14 @@ public static void loadProperties() { } /** - * Initialize Switcher Client + * {@link SwitcherContextBase#initializeClient()} */ public static void initializeClient() { SwitcherContextBase.initializeClient(); } /** - * Return a ready-to-use Switcher that will invoke the criteria configured into the Switcher API or Snapshot - * - * @param key name of the key created - * @param keepEntries when true it will return a cached Switcher with all parameters used before - * - * @return a ready to use Switcher - * @throws SwitcherKeyNotFoundException in case the key was not properly loaded + * {@link SwitcherContextBase#getSwitcher(String, boolean)} */ public static Switcher getSwitcher(String key, boolean keepEntries) { return SwitcherContextBase.getSwitcher(key, keepEntries); @@ -67,19 +59,14 @@ public static Switcher getSwitcher(String key) { } /** - * Validate and update local snapshot file.
- * It requires offline mode or SwitcherContextParam.SNAPSHOT_LOCATION configured - * - * @return true if validation was performed + * {@link SwitcherContextBase#validateSnapshot()} */ public static boolean validateSnapshot() { return SwitcherContextBase.validateSnapshot(); } /** - * Executes smoke test against the API to verify if all Switchers are properly configured - * - * @throws SwitchersValidationException when one or more Switcher Key is not found + * {@link SwitcherContextBase#checkSwitchers()} */ public static void checkSwitchers() { SwitcherContextBase.checkSwitchers(); @@ -95,29 +82,21 @@ public static long getSnapshotVersion() { } /** - * Retrieve string context parameter based on contextKey - * - * @param contextKey to be retrieved - * @return Value configured for the context parameter + * {@link SwitcherContextBase#contextStr(ContextKey)} */ public static String contextStr(ContextKey contextKey) { return SwitcherContextBase.contextStr(contextKey); } /** - * Retrieve boolean context parameter based on contextKey - * - * @param contextKey to be retrieved - * @return Value configured for the context parameter + * {@link SwitcherContextBase#contextBol(ContextKey)} */ public static boolean contextBol(ContextKey contextKey) { return SwitcherContextBase.contextBol(contextKey); } /** - * Fluent builder to configure the Switcher Context - * - * @param builder specification to be applied + * {@link SwitcherContextBase#configure(ContextBuilder)} */ public static void configure(ContextBuilder builder) { SwitcherContextBase.configure(builder); diff --git a/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java b/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java index c842638e..88f4a28b 100644 --- a/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java +++ b/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java @@ -116,7 +116,7 @@ public static void initializeClient() { } loadSwitchers(); - scheduleSnapshotAutoUpdate(); + scheduleSnapshotAutoUpdate(switcherProperties.getSnapshotAutoUpdateInterval(), null); ContextBuilder.preConfigure(switcherProperties); } @@ -163,15 +163,28 @@ private static void loadSwitchers() { } /** - * Configure worker for Scheduled Snapshot Auto Update based on the interval provided at - * the configuration "switcher.snapshot.updateinterval" + * Schedule a task to update the snapshot automatically.
+ * The task will be executed in a single thread executor service. + * + * @param intervalValue to be used for the update (e.g. 5s, 1m, 1h, 1d) + * @param callback to be invoked when the snapshot is updated or when an error occurs */ - private static void scheduleSnapshotAutoUpdate() { - if (StringUtils.isBlank(switcherProperties.getSnapshotAutoUpdateInterval())) + public static void scheduleSnapshotAutoUpdate(String intervalValue, SnapshotCallback callback) { + if (StringUtils.isBlank(intervalValue)) return; - final long interval = SwitcherUtils.getMillis(switcherProperties.getSnapshotAutoUpdateInterval()); - final Runnable runnableSnapshotValidate = SwitcherContextBase::validateSnapshot; + final long interval = SwitcherUtils.getMillis(intervalValue); + final SnapshotCallback callbackFinal = Optional.ofNullable(callback).orElse(new SnapshotCallback()); + final Runnable runnableSnapshotValidate = () -> { + try { + if (validateSnapshot()) { + callbackFinal.onSnapshotUpdate(instance.getSnapshotVersion()); + } + } catch (Exception e) { + logger.error(e.getMessage()); + callbackFinal.onSnapshotUpdateError(e); + } + }; initExecutorService(); scheduledExecutorService.scheduleAtFixedRate(runnableSnapshotValidate, 0, interval, TimeUnit.MILLISECONDS); @@ -223,20 +236,17 @@ public static Switcher getSwitcher(String key) { } /** - * Validate and update local snapshot file.
- * It requires offline mode or SwitcherContextParam.SNAPSHOT_LOCATION configured + * Validate if the snapshot version is the same as the one in the API.
+ * If the version is different, it will update the snapshot in memory. * - * @return true if validation was performed + * @return true if snapshot was updated */ public static boolean validateSnapshot() { - if (switcherProperties.isSnapshotSkipValidation()) { + if (switcherProperties.isSnapshotSkipValidation() || instance.checkSnapshotVersion()) { return false; } - - if (!instance.checkSnapshotVersion()) { - instance.updateSnapshot(); - } - + + instance.updateSnapshot(); return true; } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherApiMockTest.java b/src/test/java/com/github/switcherapi/client/SwitcherApiMockTest.java index 1114b30e..7b36b932 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherApiMockTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherApiMockTest.java @@ -253,7 +253,7 @@ void shouldValidateAndNotUpdateSnapshot() { assertDoesNotThrow(() -> { Switchers.initializeClient(); - assertTrue(Switchers.validateSnapshot()); + assertFalse(Switchers.validateSnapshot()); }); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java b/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java index 58813edc..878ee593 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java @@ -227,4 +227,34 @@ void shouldUpdateSnapshot_online_inMemory() { assertEquals(2, Switchers.getSnapshotVersion()); } + @Test + @Order(5) + void shouldNotKillThread_whenAPI_wentOffline() { + //given + givenResponse(generateMockAuth()); //auth + givenResponse(generateSnapshotResponse("default_outdated.json")); //graphql + + //that + Switchers.configure(ContextBuilder.builder() + .url(String.format("http://localhost:%s", mockBackEnd.getPort())) + .snapshotLocation(null) + .environment("generated_mock_default_6") + .offlineMode(true) + .snapshotAutoLoad(true) + .snapshotAutoUpdateInterval("1s")); + + Switchers.initializeClient(); + assertEquals(1, Switchers.getSnapshotVersion()); + + CountDownHelper.wait(1); + + //given - API is online again + givenResponse(generateCheckSnapshotVersionResponse(Boolean.toString(false))); //criteria/snapshot_check + givenResponse(generateSnapshotResponse("default.json")); //graphql + + //test + CountDownHelper.wait(2); + assertEquals(2, Switchers.getSnapshotVersion()); + } + }