From 7cec26f49c8ba69bee0b5332a362ac3c14e8e77d Mon Sep 17 00:00:00 2001 From: petruki <31597636+petruki@users.noreply.github.com> Date: Sun, 19 May 2024 13:13:54 -0700 Subject: [PATCH 1/2] bump pom version to 1.5.0-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 482530b9..48fdcb6b 100644 --- a/pom.xml +++ b/pom.xml @@ -8,7 +8,7 @@ com.github.switcherapi switcher-client jar - 1.4.6 + 1.5.0-SNAPSHOT Switcher Client Switcher Client SDK for working with Switcher API From aa6291d925928e4404e065f55a23e0520e2d9184 Mon Sep 17 00:00:00 2001 From: Roger Floriano <31597636+petruki@users.noreply.github.com> Date: Sun, 19 May 2024 12:58:27 -0700 Subject: [PATCH 2/2] Added switcher.defaultResult() to handle panic events (#297) --- .../client/model/SwitcherBuilder.java | 17 ++++++++++ .../model/response/CriteriaResponse.java | 4 +++ .../service/local/SwitcherLocalService.java | 25 ++++++++------ .../service/remote/SwitcherRemoteService.java | 21 ++++++++---- .../switcherapi/client/SwitcherFail1Test.java | 12 +++++++ .../client/SwitcherLocal3Test.java | 12 ++++--- .../fixture/MockWebServerHelper.java | 2 +- .../playground/ClientPlayground.java | 2 ++ .../snapshot/playground/default.json | 34 +++++++++++++++++++ 9 files changed, 107 insertions(+), 22 deletions(-) create mode 100644 src/test/resources/snapshot/playground/default.json diff --git a/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java b/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java index 9fdea553..d9b551ae 100644 --- a/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java +++ b/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java @@ -23,6 +23,8 @@ public abstract class SwitcherBuilder { protected boolean remote; protected boolean bypassMetrics; + + protected String defaultResult; protected List entry; @@ -58,6 +60,17 @@ public SwitcherBuilder remote(boolean remote) { this.remote = remote; return this; } + + /** + * Set the default result when client panics + * + * @param defaultResult true/false + * @return {@link SwitcherBuilder} + */ + public SwitcherBuilder defaultResult(boolean defaultResult) { + this.defaultResult = String.valueOf(defaultResult); + return this; + } /** * Add a validation to the entry stack @@ -219,4 +232,8 @@ public SwitcherBuilder bypassMetrics() { public boolean isRemote() { return remote; } + + public String getDefaultResult() { + return defaultResult; + } } diff --git a/src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java b/src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java index 0992ea9e..eea5cb30 100644 --- a/src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java +++ b/src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java @@ -39,6 +39,10 @@ public CriteriaResponse buildFromSwitcher(Switcher switcher) { return this; } + public static CriteriaResponse buildFromDefault(Switcher switcher) { + return new CriteriaResponse(true, "Default result", switcher); + } + public boolean isItOn() { return result; } diff --git a/src/main/java/com/github/switcherapi/client/service/local/SwitcherLocalService.java b/src/main/java/com/github/switcherapi/client/service/local/SwitcherLocalService.java index 7f4994ad..e32cd690 100644 --- a/src/main/java/com/github/switcherapi/client/service/local/SwitcherLocalService.java +++ b/src/main/java/com/github/switcherapi/client/service/local/SwitcherLocalService.java @@ -2,10 +2,7 @@ import com.github.switcherapi.client.SwitcherContextBase; import com.github.switcherapi.client.SwitcherExecutor; -import com.github.switcherapi.client.exception.SwitcherContextException; -import com.github.switcherapi.client.exception.SwitcherException; -import com.github.switcherapi.client.exception.SwitcherSnapshotLoadException; -import com.github.switcherapi.client.exception.SwitchersValidationException; +import com.github.switcherapi.client.exception.*; import com.github.switcherapi.client.model.ContextKey; import com.github.switcherapi.client.model.Switcher; import com.github.switcherapi.client.model.criteria.Domain; @@ -71,12 +68,20 @@ public CriteriaResponse executeCriteria(final Switcher switcher) { SwitcherUtils.debug(logger, "switcher: {}", switcher); CriteriaResponse response; - if (switcher.isRemote()) { - response = this.clientRemote.executeCriteria(switcher); - SwitcherUtils.debug(logger, "[Remote] response: {}", response); - } else { - response = this.clientLocalService.executeCriteria(switcher, this.domain); - SwitcherUtils.debug(logger, "[Local] response: {}", response); + try { + if (switcher.isRemote()) { + response = this.clientRemote.executeCriteria(switcher); + SwitcherUtils.debug(logger, "[Remote] response: {}", response); + } else { + response = this.clientLocalService.executeCriteria(switcher, this.domain); + SwitcherUtils.debug(logger, "[Local] response: {}", response); + } + } catch (SwitcherKeyNotFoundException e) { + if (StringUtils.isNotBlank(switcher.getDefaultResult())) { + return CriteriaResponse.buildFromDefault(switcher); + } + + throw e; } return response; diff --git a/src/main/java/com/github/switcherapi/client/service/remote/SwitcherRemoteService.java b/src/main/java/com/github/switcherapi/client/service/remote/SwitcherRemoteService.java index 8dab1f36..3efa9586 100644 --- a/src/main/java/com/github/switcherapi/client/service/remote/SwitcherRemoteService.java +++ b/src/main/java/com/github/switcherapi/client/service/remote/SwitcherRemoteService.java @@ -47,20 +47,27 @@ public CriteriaResponse executeCriteria(final Switcher switcher) { return response; } catch (final SwitcherRemoteException e) { logger.error("Failed to execute criteria - {}\nCause: {}", e.getMessage(), e.getCause()); - return executeSilentCriteria(switcher, e); + return tryExecuteLocalCriteria(switcher, e); } } - private CriteriaResponse executeSilentCriteria(final Switcher switcher, - final SwitcherRemoteException e) { + private CriteriaResponse tryExecuteLocalCriteria(final Switcher switcher, + final SwitcherRemoteException e) { if (StringUtils.isNotBlank(SwitcherContextBase.contextStr(ContextKey.SILENT_MODE))) { - CriteriaResponse response = this.switcherLocal.executeCriteria(switcher); + final CriteriaResponse response = this.switcherLocal.executeCriteria(switcher); SwitcherUtils.debug(logger, "[Silent] response: {}", response); - + return response; - } else { - throw e; } + + if (StringUtils.isNotBlank(switcher.getDefaultResult())) { + final CriteriaResponse response = CriteriaResponse.buildFromDefault(switcher); + SwitcherUtils.debug(logger, "[Default] response: {}", response); + + return response; + } + + throw e; } @Override diff --git a/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java b/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java index 5926b830..3b3107ff 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java @@ -63,6 +63,18 @@ void shouldReturnError_keyNotFound() { Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertThrows(SwitcherRemoteException.class, switcher::isItOn); } + + @Test + void shouldReturnSuccessDefaultResult_keyNotFound() { + //auth + givenResponse(generateMockAuth(10)); + + //criteria + givenResponse(generateStatusResponse("404")); + + Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + assertTrue(switcher.defaultResult(true).isItOn()); + } @Test void shouldReturnError_unauthorizedAPIAccess() { diff --git a/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java b/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java index 492b5866..f0533180 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java @@ -1,9 +1,5 @@ package com.github.switcherapi.client; -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - import java.nio.file.Paths; import java.util.Set; import java.util.stream.Stream; @@ -27,6 +23,8 @@ import com.github.switcherapi.client.model.Switcher; import com.github.switcherapi.client.service.local.SwitcherLocalService; +import static org.junit.jupiter.api.Assertions.*; + class SwitcherLocal3Test { private static final String SNAPSHOTS_LOCAL = Paths.get(StringUtils.EMPTY).toAbsolutePath() + "/src/test/resources/snapshot"; @@ -101,4 +99,10 @@ void localShouldCheckSwitchers_notFound() { ex.getMessage()); } + @Test + void localShouldReturnTrue_defaultResult() { + Switcher switcher = Switchers.getSwitcher(Switchers.NOT_FOUND_KEY); + assertTrue(switcher.defaultResult(true).isItOn()); + } + } diff --git a/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java b/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java index 84f40f44..c64bdd54 100644 --- a/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java +++ b/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java @@ -95,7 +95,7 @@ protected MockResponse generateCheckSnapshotVersionResponse(String status) { */ protected MockResponse generateStatusResponse(String code) { MockResponse.Builder builder = new MockResponse.Builder(); - builder.status(code); + builder.setCode(Integer.parseInt(code)); return builder.build(); } diff --git a/src/test/java/com/github/switcherapi/playground/ClientPlayground.java b/src/test/java/com/github/switcherapi/playground/ClientPlayground.java index 9b9e1838..6b995bd1 100644 --- a/src/test/java/com/github/switcherapi/playground/ClientPlayground.java +++ b/src/test/java/com/github/switcherapi/playground/ClientPlayground.java @@ -24,6 +24,8 @@ public static void test() { .url("https://api.switcherapi.com") .apiKey("JDJiJDA4JEFweTZjSTR2bE9pUjNJOUYvRy9raC4vRS80Q2tzUnk1d3o1aXFmS2o5eWJmVW11cjR0ODNT") .domain("Playground") + .local(true) + .snapshotLocation("src/test/resources/snapshot/playground") .component("switcher-playground")); initializeClient(); diff --git a/src/test/resources/snapshot/playground/default.json b/src/test/resources/snapshot/playground/default.json new file mode 100644 index 00000000..7261d9c0 --- /dev/null +++ b/src/test/resources/snapshot/playground/default.json @@ -0,0 +1,34 @@ +{ + "data": { + "domain": { + "name": "Playground", + "version": 0, + "description": "My playground", + "activated": true, + "group": [ + { + "name": "Experimental", + "description": "Open feature flags for experimentation", + "activated": true, + "config": [ + { + "key": "MY_SWITCHER", + "description": "My first switcher", + "activated": true, + "strategies": [ + { + "strategy": "VALUE_VALIDATION", + "operation": "EXIST", + "activated": false, + "values": [ + "user_1" + ] + } + ] + } + ] + } + ] + } + } +} \ No newline at end of file