diff --git a/README.md b/README.md index 62eed593..a2e6d629 100644 --- a/README.md +++ b/README.md @@ -154,13 +154,13 @@ Switcher switcher = MyAppFeatures.getSwitcher(FEATURE01); switcher.isItOn(); ``` -Or, you can submit the switcher request and get the criteria response, which contains result, reason and metadata that can be used for any additional verification. +Or, you can submit the switcher request and get the switcher result, which contains result, reason and metadata that can be used for any additional verification. ```java -CriteriaResponse response = switcher.submit(); -response.isItOn(); // true/false -response.getReason(); // Descriptive response based on result value -response.getMetadata(YourMetadata.class); // Additional information +SwitcherResult result = switcher.submit(); +result.isItOn(); // true/false +result.getReason(); // Descriptive response based on result value +result.getMetadata(YourMetadata.class); // Additional information ``` 2. **Strategy validation - preparing input** diff --git a/pom.xml b/pom.xml index 162d1c45..1a2d9395 100644 --- a/pom.xml +++ b/pom.xml @@ -83,6 +83,8 @@ java **/model/**/*.java, + **/remote/dto/*.java, + **/utils/Utils.java, **/exception/**/*.java, **/service/validators/RegexValidatorV8.java, **/client/remote/Constants.java diff --git a/src/main/java/com/github/switcherapi/client/SwitcherConfig.java b/src/main/java/com/github/switcherapi/client/SwitcherConfig.java index 463c74a1..c2acdbd2 100644 --- a/src/main/java/com/github/switcherapi/client/SwitcherConfig.java +++ b/src/main/java/com/github/switcherapi/client/SwitcherConfig.java @@ -1,5 +1,7 @@ package com.github.switcherapi.client; +import com.github.switcherapi.client.model.ContextKey; + abstract class SwitcherConfig { protected String url; @@ -21,6 +23,35 @@ abstract class SwitcherConfig { this.truststore = new TruststoreConfig(); } + /** + * Update Switcher Configurations state using pre-configured properties. + * + * @param properties Switcher Properties + */ + protected void updateSwitcherConfig(SwitcherProperties properties) { + setUrl(properties.getValue(ContextKey.URL)); + setApikey(properties.getValue(ContextKey.APIKEY)); + setDomain(properties.getValue(ContextKey.DOMAIN)); + setComponent(properties.getValue(ContextKey.COMPONENT)); + setEnvironment(properties.getValue(ContextKey.ENVIRONMENT)); + setLocal(properties.getBoolean(ContextKey.LOCAL_MODE)); + setSilent(properties.getValue(ContextKey.SILENT_MODE)); + setTimeout(properties.getInt(ContextKey.TIMEOUT_MS)); + setPoolSize(properties.getInt(ContextKey.POOL_CONNECTION_SIZE)); + + SnapshotConfig snapshotConfig = new SnapshotConfig(); + snapshotConfig.setLocation(properties.getValue(ContextKey.SNAPSHOT_LOCATION)); + snapshotConfig.setAuto(properties.getBoolean(ContextKey.SNAPSHOT_AUTO_LOAD)); + snapshotConfig.setSkipValidation(properties.getBoolean(ContextKey.SNAPSHOT_SKIP_VALIDATION)); + snapshotConfig.setUpdateInterval(properties.getValue(ContextKey.SNAPSHOT_AUTO_UPDATE_INTERVAL)); + setSnapshot(snapshotConfig); + + TruststoreConfig truststoreConfig = new TruststoreConfig(); + truststoreConfig.setPath(properties.getValue(ContextKey.TRUSTSTORE_PATH)); + truststoreConfig.setPassword(properties.getValue(ContextKey.TRUSTSTORE_PASSWORD)); + setTruststore(truststoreConfig); + } + /** * Initialize the Switcher Client.
* - Build context {@link ContextBuilder}
diff --git a/src/main/java/com/github/switcherapi/client/SwitcherContext.java b/src/main/java/com/github/switcherapi/client/SwitcherContext.java index 612dfae3..36502d23 100644 --- a/src/main/java/com/github/switcherapi/client/SwitcherContext.java +++ b/src/main/java/com/github/switcherapi/client/SwitcherContext.java @@ -3,7 +3,7 @@ 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; +import com.github.switcherapi.client.model.SwitcherRequest; /** * Switcher Context @@ -54,7 +54,7 @@ public static void initializeClient() { * @return a ready to use Switcher * @throws SwitcherKeyNotFoundException in case the key was not properly loaded */ - public static Switcher getSwitcher(String key, boolean keepEntries) { + public static SwitcherRequest getSwitcher(String key, boolean keepEntries) { return SwitcherContextBase.getSwitcher(key, keepEntries); } @@ -64,7 +64,7 @@ public static Switcher getSwitcher(String key, boolean keepEntries) { * @param key name * @return a ready to use Switcher */ - public static Switcher getSwitcher(String key) { + public static SwitcherRequest getSwitcher(String key) { return SwitcherContextBase.getSwitcher(key); } diff --git a/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java b/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java index e35cd1a0..34adfcc5 100644 --- a/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java +++ b/src/main/java/com/github/switcherapi/client/SwitcherContextBase.java @@ -5,7 +5,7 @@ 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; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.remote.ClientWS; import com.github.switcherapi.client.remote.ClientWSImpl; import com.github.switcherapi.client.service.SwitcherValidator; @@ -73,7 +73,6 @@ * * Features.initializeClient(); * } - * * * * @see SwitcherKey @@ -86,7 +85,7 @@ public abstract class SwitcherContextBase extends SwitcherConfig { protected static SwitcherProperties switcherProperties; protected static Set switcherKeys; - protected static Map switchers; + protected static Map switchers; protected static SwitcherExecutor instance; private static ScheduledExecutorService scheduledExecutorService; private static ExecutorService watcherExecutorService; @@ -119,21 +118,28 @@ protected void configureClient() { .truststorePath(truststore.getPath()) .truststorePassword(truststore.getPassword())); - switcherProperties.setValue(ContextKey.CONTEXT_LOCATION, contextBase.getClass().getName()); initializeClient(); } @Override protected void configureClient(String contextFile) { setContextBase(this); - loadProperties(contextFile); + loadProperties(contextFile); switcherProperties.setValue(ContextKey.CONTEXT_LOCATION, contextBase.getClass().getName()); + + updateSwitcherConfig(switcherProperties); initializeClient(); } - private static synchronized void setContextBase(SwitcherContextBase contextBase) { - SwitcherContextBase.contextBase = contextBase; + /** + * Manually register Switcher Keys.
+ * Use this method before calling {@link #configureClient()} to register the Switcher Keys. + * + * @param switcherKeys to be registered + */ + protected void registerSwitcherKeys(String... switcherKeys) { + setSwitcherKeys(new HashSet<>(Arrays.asList(switcherKeys))); } /** @@ -173,7 +179,7 @@ public static void loadProperties(String contextFilename) { */ public static void initializeClient() { validateContext(); - validateSwitcherKeys(); + registerSwitcherKeys(); instance = buildInstance(); loadSwitchers(); @@ -195,9 +201,10 @@ private static SwitcherExecutor buildInstance() { if (contextBol(ContextKey.LOCAL_MODE)) { return new SwitcherLocalService(clientRemote, clientLocal, switcherProperties); - } else { - return new SwitcherRemoteService(clientRemote, new SwitcherLocalService(clientRemote, clientLocal, switcherProperties)); } + + return new SwitcherRemoteService(clientRemote, new SwitcherLocalService(clientRemote, + clientLocal, switcherProperties)); } /** @@ -212,10 +219,9 @@ private static void validateContext() throws SwitcherContextException { } /** - * Validate Switcher Keys.
- * It will ensure that only properly annotated Switchers can be used. + * Register Switcher Keys based on context properties */ - private static void validateSwitcherKeys() { + private static void registerSwitcherKeys() { if (Objects.nonNull(contextBase)) { registerSwitcherKey(contextBase.getClass().getFields()); } else { @@ -234,7 +240,7 @@ private static void validateSwitcherKeys() { * @param fields to be registered */ private static void registerSwitcherKey(Field[] fields) { - switcherKeys = new HashSet<>(); + switcherKeys = Optional.ofNullable(switcherKeys).orElse(new HashSet<>()); for (Field field : fields) { if (field.isAnnotationPresent(SwitcherKey.class)) { switcherKeys.add(field.getName()); @@ -246,13 +252,13 @@ private static void registerSwitcherKey(Field[] fields) { * Load Switcher instances into a map cache */ private static void loadSwitchers() { - if (switchers == null) { + if (Objects.isNull(switchers)) { switchers = new HashMap<>(); } switchers.clear(); for (String key : switcherKeys) { - switchers.put(key, new Switcher(key, instance)); + switchers.put(key, new SwitcherRequest(key, instance)); } } @@ -348,14 +354,14 @@ private static ClientWS initRemotePoolExecutorService() { * @return a ready to use Switcher * @throws SwitcherKeyNotFoundException in case the key was not properly loaded */ - public static Switcher getSwitcher(String key, boolean keepEntries) { + public static SwitcherRequest getSwitcher(String key, boolean keepEntries) { SwitcherUtils.debug(logger, "key: {} - keepEntries: {}", key, keepEntries); if (!switchers.containsKey(key)) { throw new SwitcherKeyNotFoundException(key); } - final Switcher switcher = switchers.get(key); + final SwitcherRequest switcher = switchers.get(key); if (!keepEntries) { switcher.resetEntry(); } @@ -369,7 +375,7 @@ public static Switcher getSwitcher(String key, boolean keepEntries) { * @param key name * @return a ready to use Switcher */ - public static Switcher getSwitcher(String key) { + public static SwitcherRequest getSwitcher(String key) { return getSwitcher(key, false); } @@ -414,7 +420,7 @@ public static void watchSnapshot(SnapshotEventHandler handler) { throw new SwitcherException("Cannot watch snapshot when using remote", new UnsupportedOperationException()); } - if (watcherSnapshot == null) { + if (Objects.isNull(watcherSnapshot)) { watcherSnapshot = new SnapshotWatcher((SwitcherLocalService) instance, handler, contextStr(ContextKey.SNAPSHOT_LOCATION)); } @@ -429,7 +435,7 @@ public static void watchSnapshot(SnapshotEventHandler handler) { * @throws SwitcherException if watch thread never started */ public static void stopWatchingSnapshot() { - if (watcherSnapshot != null) { + if (Objects.nonNull(watcherSnapshot)) { watcherExecutorService.shutdownNow(); watcherSnapshot.terminate(); watcherSnapshot = null; @@ -497,10 +503,18 @@ public static void configure(ContextBuilder builder) { * Cancel existing scheduled task for updating local Snapshot */ public static void terminateSnapshotAutoUpdateWorker() { - if (scheduledExecutorService != null) { + if (Objects.nonNull(scheduledExecutorService)) { scheduledExecutorService.shutdownNow(); scheduledExecutorService = null; } } + + private static synchronized void setContextBase(SwitcherContextBase contextBase) { + SwitcherContextBase.contextBase = contextBase; + } + + private static synchronized void setSwitcherKeys(Set switcherKeys) { + SwitcherContextBase.switcherKeys = switcherKeys; + } } diff --git a/src/main/java/com/github/switcherapi/client/SwitcherExecutor.java b/src/main/java/com/github/switcherapi/client/SwitcherExecutor.java index 1f10e2d5..7ff68845 100644 --- a/src/main/java/com/github/switcherapi/client/SwitcherExecutor.java +++ b/src/main/java/com/github/switcherapi/client/SwitcherExecutor.java @@ -3,10 +3,10 @@ import com.github.switcherapi.client.exception.SwitcherRemoteException; import com.github.switcherapi.client.exception.SwitcherSnapshotWriteException; import com.github.switcherapi.client.model.ContextKey; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.model.criteria.Domain; import com.github.switcherapi.client.model.criteria.Snapshot; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherResult; import com.github.switcherapi.client.service.remote.ClientRemote; import com.github.switcherapi.client.utils.SnapshotLoader; import com.github.switcherapi.client.utils.SwitcherUtils; @@ -17,6 +17,7 @@ import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.Set; /** @@ -30,7 +31,7 @@ public abstract class SwitcherExecutor { private static final Logger logger = LoggerFactory.getLogger(SwitcherExecutor.class); - private static final Map bypass = new HashMap<>(); + private static final Map bypass = new HashMap<>(); protected final SwitcherProperties switcherProperties; @@ -46,7 +47,7 @@ protected SwitcherExecutor(final SwitcherProperties switcherProperties) { * @param switcher to be evaluated * @return Criteria response containing the evaluation details */ - public abstract CriteriaResponse executeCriteria(final Switcher switcher); + public abstract SwitcherResult executeCriteria(final SwitcherRequest switcher); /** * Check the snapshot versions against the Remote configuration. @@ -77,10 +78,10 @@ protected SwitcherExecutor(final SwitcherProperties switcherProperties) { protected boolean checkSnapshotVersion(ClientRemote clientRemote, final Domain domain) { final String environment = switcherProperties.getValue(ContextKey.ENVIRONMENT); SwitcherUtils.debug(logger, "verifying snapshot version - environment: {}", environment); - + return clientRemote.checkSnapshotVersion(domain.getVersion()); } - + protected Domain initializeSnapshotFromAPI(ClientRemote clientRemote) throws SwitcherRemoteException, SwitcherSnapshotWriteException { final String environment = switcherProperties.getValue(ContextKey.ENVIRONMENT); @@ -89,25 +90,21 @@ protected Domain initializeSnapshotFromAPI(ClientRemote clientRemote) final Snapshot snapshot = clientRemote.resolveSnapshot(); final String snapshotLocation = switcherProperties.getValue(ContextKey.SNAPSHOT_LOCATION); - if (snapshotLocation != null) { + if (Objects.nonNull(snapshotLocation)) { SnapshotLoader.saveSnapshot(snapshot, snapshotLocation, environment); } return snapshot.getDomain(); } - - public boolean isLocalEnabled() { - return switcherProperties.getBoolean(ContextKey.LOCAL_MODE); - } /** * It manipulates the result of a given Switcher key. * * @param key name of the key that you want to change the result * @param expectedResult that will be returned when performing isItOn - * @return CriteriaResponse with the manipulated result + * @return SwitcherResult with the manipulated result */ - public static CriteriaResponse assume(final String key, boolean expectedResult) { + public static SwitcherResult assume(final String key, boolean expectedResult) { return assume(key, expectedResult, null); } @@ -117,20 +114,20 @@ public static CriteriaResponse assume(final String key, boolean expectedResult) * @param key name of the key that you want to change the result * @param metadata additional information about the assumption (JSON) * @param expectedResult that will be returned when performing isItOn - * @return CriteriaResponse with the manipulated result + * @return SwitcherResult with the manipulated result */ - public static CriteriaResponse assume(final String key, boolean expectedResult, String metadata) { - CriteriaResponse criteriaResponse = new CriteriaResponse(); - criteriaResponse.setResult(expectedResult); - criteriaResponse.setReason("Switcher bypassed"); + public static SwitcherResult assume(final String key, boolean expectedResult, String metadata) { + SwitcherResult switcherResult = new SwitcherResult(); + switcherResult.setResult(expectedResult); + switcherResult.setReason("Switcher bypassed"); if (StringUtils.isNotBlank(metadata)) { Gson gson = new Gson(); - criteriaResponse.setMetadata(gson.fromJson(metadata, Object.class)); + switcherResult.setMetadata(gson.fromJson(metadata, Object.class)); } - bypass.put(key, criteriaResponse); - return criteriaResponse; + bypass.put(key, switcherResult); + return switcherResult; } /** @@ -142,7 +139,7 @@ public static void forget(final String key) { bypass.remove(key); } - public static Map getBypass() { + public static Map getBypass() { return bypass; } diff --git a/src/main/java/com/github/switcherapi/client/model/AsyncSwitcher.java b/src/main/java/com/github/switcherapi/client/model/AsyncSwitcher.java index d9c98975..1f5b577e 100644 --- a/src/main/java/com/github/switcherapi/client/model/AsyncSwitcher.java +++ b/src/main/java/com/github/switcherapi/client/model/AsyncSwitcher.java @@ -1,7 +1,6 @@ package com.github.switcherapi.client.model; import com.github.switcherapi.client.exception.SwitcherException; -import com.github.switcherapi.client.model.response.CriteriaResponse; import com.github.switcherapi.client.utils.SwitcherUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -25,13 +24,13 @@ public class AsyncSwitcher { private final ExecutorService executorService; - private final SwitcherInterface switcherInterface; + private final Switcher switcher; private final long delay; private long nextRun = 0; - public AsyncSwitcher(final SwitcherInterface switcherInterface, long delay) { + public AsyncSwitcher(final Switcher switcher, long delay) { this.executorService = Executors.newCachedThreadPool(r -> { Thread thread = new Thread(r); thread.setName(SWITCHER_ASYNC_WORKER.toString()); @@ -39,7 +38,7 @@ public AsyncSwitcher(final SwitcherInterface switcherInterface, long delay) { return thread; }); - this.switcherInterface = switcherInterface; + this.switcher = switcher; this.delay = delay; } @@ -60,8 +59,8 @@ public synchronized void execute() { public void run() { try { - final CriteriaResponse response = switcherInterface.executeCriteria(); - switcherInterface.updateHistoryExecution(response); + final SwitcherResult response = switcher.executeCriteria(); + switcher.updateHistoryExecution(response); } catch (SwitcherException e) { logger.error(e.getMessage(), e); } diff --git a/src/main/java/com/github/switcherapi/client/model/Switcher.java b/src/main/java/com/github/switcherapi/client/model/Switcher.java index dce49576..2abc0076 100644 --- a/src/main/java/com/github/switcherapi/client/model/Switcher.java +++ b/src/main/java/com/github/switcherapi/client/model/Switcher.java @@ -1,179 +1,110 @@ package com.github.switcherapi.client.model; import com.github.switcherapi.client.SwitcherContext; -import com.github.switcherapi.client.SwitcherExecutor; import com.github.switcherapi.client.exception.SwitcherException; -import com.github.switcherapi.client.model.response.CriteriaResponse; -import java.util.*; +import java.util.List; /** - * Switchers are the entry point to evaluate criteria and return the result. - *
To execute a criteria evaluation, use one of the available methods: {@link #isItOn()}. - * - * @author Roger Floriano (petruki) - * @since 2019-12-24 - * - * @see #isItOn() - * @see #submit() + * The API that handles the switcher operations. + * + *
    + *
  • Switcher creation
  • + *
  • Switcher execution
  • + *
  • Switcher get input/output
  • + *
*/ -public final class Switcher extends SwitcherBuilder { - - public static final String KEY = "key"; - - public static final String SHOW_REASON = "showReason"; - - public static final String BYPASS_METRIC = "bypassMetric"; - - private final String switcherKey; - - private final Set historyExecution; +public interface Switcher { - private AsyncSwitcher asyncSwitcher; - /** - * Use {@link SwitcherContext#getSwitcher(String)} to create this object. - * - * @param switcherKey name of the key created - * @param context client context in which the switcher will be executed (local/remote) + * This method builds the Switcher object.
+ * Uses to isolate Switcher creation from the execution.
+ * + * For example: + *
+	 * Switcher switcher = SwitcherContext
+	 * 	.getSwitcher(MY_SWITCHER)
+	 * 	.remote(true)
+	 * 	.throttle(1000)
+	 * 	.checkValue("value")
+	 * 	.build();
+	 * 
+ * + * @return instance of SwitcherInterface + * @see SwitcherRequest */ - public Switcher(final String switcherKey, final SwitcherExecutor context) { - super(context); - this.switcherKey = switcherKey; - this.historyExecution = new HashSet<>(); - this.entry = new ArrayList<>(); - } + Switcher build(); - @Override - public Switcher build() { - return this; - } - - @Override - public Switcher prepareEntry(final List entry) { - this.entry = Optional.ofNullable(entry).orElse(new ArrayList<>()); - return this; - } - - @Override - public Switcher prepareEntry(final Entry entry, final boolean add) { - if (!add) { - this.entry.clear(); - } - - if (!this.entry.contains(entry)) { - this.entry.add(entry); - } - - return this; - } - - @Override - public Switcher prepareEntry(final Entry entry) { - return this.prepareEntry(entry, false); - } - - @Override - public boolean isItOn() throws SwitcherException { - final CriteriaResponse response = submit(); - return response.isItOn(); - } - - @Override - public CriteriaResponse submit() throws SwitcherException { - if (SwitcherExecutor.getBypass().containsKey(switcherKey)) { - return SwitcherExecutor.getBypass().get(switcherKey).buildFromSwitcher(this); - } - - if (canUseAsync()) { - if (asyncSwitcher == null) { - asyncSwitcher = new AsyncSwitcher(this, super.delay); - } - - asyncSwitcher.execute(); - final Optional response = getFromHistory(); - if (response.isPresent()) { - return response.get(); - } - } - - final CriteriaResponse response = this.context.executeCriteria(this); - this.updateHistoryExecution(response); - return response; - } - - @Override - public CriteriaResponse executeCriteria() { - return this.context.executeCriteria(this); - } - - @Override - public void updateHistoryExecution(final CriteriaResponse response) { - this.historyExecution.removeIf(item -> - this.switcherKey.equals(item.getSwitcherKey()) && this.entry.equals(item.getEntry())); + /** + * Prepare the Switcher including a list of inputs necessary to run the criteria afterward. + * + * @param entry input object + * @return instance of SwitcherInterface + */ + Switcher prepareEntry(final List entry); - this.historyExecution.add(response); - } + /** + * Prepare the Switcher including a list of inputs necessary to run the criteria afterward. + * + * @param entry input object + * @param add if false, the list will be cleaned and the entry provided will be the only input for this Switcher. + * @return instance of SwitcherInterface + */ + Switcher prepareEntry(final Entry entry, final boolean add); - @Override - public String getSwitcherKey() { - return this.switcherKey; - } + /** + * It adds an input to the list of inputs. + *
Under the table it calls {@link #prepareEntry(Entry, boolean)} passing true to the second argument. + * + * @param entry input object + * @return instance of SwitcherInterface + */ + Switcher prepareEntry(final Entry entry); - @Override - public List getEntry() { - return this.entry; - } - /** - * This method builds up the request made by the client to reach the Switcher API. - * - * @return json input request + * Execute criteria based on a given switcher key provided via {@link SwitcherContext#getSwitcher(String)}. + *
The detailed result is available in list of {@link SwitcherResult}. + * + * @return criteria result + * @throws SwitcherException connectivity or criteria errors regarding reading malformed snapshots */ - public GsonInputRequest getInputRequest() { - return new GsonInputRequest( - this.entry != null ? - this.entry.toArray(new Entry[0]) : null); - } + boolean isItOn() throws SwitcherException; - public boolean isBypassMetrics() { - return bypassMetrics; - } - - public void resetEntry() { - this.entry = new ArrayList<>(); - } + /** + * Execute criteria based on a given switcher key provided via {@link SwitcherContext#getSwitcher(String)}. + *
The detailed result is available in list of {@link SwitcherResult}. + * + * @return {@link SwitcherResult} + * @throws SwitcherException connectivity or criteria errors regarding reading malformed snapshots + */ + SwitcherResult submit() throws SwitcherException; - private boolean canUseAsync() { - return super.delay > 0 && !this.historyExecution.isEmpty(); - } + /** + * Execute the criteria evaluation. + * + * @return the switcher result + */ + SwitcherResult executeCriteria(); - private Optional getFromHistory() { - for (CriteriaResponse criteriaResponse : historyExecution) { - if (criteriaResponse.getEntry().equals(getEntry())) { - return Optional.of(criteriaResponse); - } - } - return Optional.empty(); - } + /** + * Update the history of executions. + * + * @param response the response to be updated + */ + void updateHistoryExecution(SwitcherResult response); - @Override - public String toString() { - return String.format("Switcher [switcherKey= %s, entry= %s, bypassMetrics= %s]", - switcherKey, entry, bypassMetrics); - } - - public static class GsonInputRequest { - - private final Entry[] entry; - - public GsonInputRequest(final Entry[] entry) { - this.entry = entry; - } + /** + * Get the key of the switcher. + * + * @return the key of the switcher + */ + String getSwitcherKey(); - public Entry[] getEntry() { - return this.entry; - } - } + /** + * Get the entry input list for the switcher. + * + * @return the entry of the switcher + */ + List getEntry(); } 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 49884f51..82aef0bc 100644 --- a/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java +++ b/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java @@ -1,6 +1,6 @@ package com.github.switcherapi.client.model; -import com.github.switcherapi.client.SwitcherExecutor; +import com.github.switcherapi.client.SwitcherProperties; import com.github.switcherapi.client.exception.SwitcherContextException; import org.apache.commons.lang3.StringUtils; @@ -13,9 +13,9 @@ * * @author Roger Floriano (petruki) */ -public abstract class SwitcherBuilder implements SwitcherInterface { +public abstract class SwitcherBuilder implements Switcher { - protected final SwitcherExecutor context; + protected final SwitcherProperties properties; protected long delay; @@ -26,9 +26,9 @@ public abstract class SwitcherBuilder implements SwitcherInterface { protected String defaultResult; protected List entry; - - protected SwitcherBuilder(final SwitcherExecutor context) { - this.context = context; + + protected SwitcherBuilder(final SwitcherProperties properties) { + this.properties = properties; this.entry = new ArrayList<>(); this.delay = 0; } @@ -53,7 +53,7 @@ public SwitcherBuilder throttle(long delay) { * @throws SwitcherContextException if Switcher is not configured to run locally using local mode */ public SwitcherBuilder remote(boolean remote) { - if (!this.context.isLocalEnabled()) { + if (!this.properties.getBoolean(ContextKey.LOCAL_MODE)) { throw new SwitcherContextException("Switcher is not configured to run locally"); } @@ -175,7 +175,4 @@ public String getDefaultResult() { return defaultResult; } - public SwitcherExecutor getContext() { - return context; - } } diff --git a/src/main/java/com/github/switcherapi/client/model/SwitcherInterface.java b/src/main/java/com/github/switcherapi/client/model/SwitcherInterface.java deleted file mode 100644 index b098522e..00000000 --- a/src/main/java/com/github/switcherapi/client/model/SwitcherInterface.java +++ /dev/null @@ -1,110 +0,0 @@ -package com.github.switcherapi.client.model; - -import com.github.switcherapi.client.SwitcherContext; -import com.github.switcherapi.client.exception.SwitcherException; -import com.github.switcherapi.client.model.response.CriteriaResponse; - -import java.util.List; - -/** - * Defines minimal contract for Switcher implementations for: - * - *
    - *
  • Switcher creation
  • - *
  • Switcher execution
  • - *
  • Switcher get input/output
  • - *
- */ -public interface SwitcherInterface { - - /** - * This method builds the Switcher object.
- * Uses to isolate Switcher creation from the execution.
- * - * For example: - *
-	 * Switcher switcher = SwitcherContext
-	 * 	.getSwitcher(MY_SWITCHER)
-	 * 	.remote(true)
-	 * 	.throttle(1000)
-	 * 	.checkValue("value")
-	 * 	.build();
-	 * 
- * - * @return {@link Switcher} - */ - Switcher build(); - - /** - * Prepare the Switcher including a list of inputs necessary to run the criteria afterward. - * - * @param entry input object - * @return {@link Switcher} - */ - Switcher prepareEntry(final List entry); - - /** - * Prepare the Switcher including a list of inputs necessary to run the criteria afterward. - * - * @param entry input object - * @param add if false, the list will be cleaned and the entry provided will be the only input for this Switcher. - * @return {@link Switcher} - */ - Switcher prepareEntry(final Entry entry, final boolean add); - - /** - * It adds an input to the list of inputs. - *
Under the table it calls {@link #prepareEntry(Entry, boolean)} passing true to the second argument. - * - * @param entry input object - * @return {@link Switcher} - */ - Switcher prepareEntry(final Entry entry); - - /** - * Execute criteria based on a given switcher key provided via {@link SwitcherContext#getSwitcher(String)}. - *
The detailed result is available in list of {@link CriteriaResponse}. - * - * @return criteria result - * @throws SwitcherException connectivity or criteria errors regarding reading malformed snapshots - */ - boolean isItOn() throws SwitcherException; - - /** - * Execute criteria based on a given switcher key provided via {@link SwitcherContext#getSwitcher(String)}. - *
The detailed result is available in list of {@link CriteriaResponse}. - * - * @return {@link CriteriaResponse} - * @throws SwitcherException connectivity or criteria errors regarding reading malformed snapshots - */ - CriteriaResponse submit() throws SwitcherException; - - /** - * Execute the criteria evaluation. - * - * @return the criteria response - */ - CriteriaResponse executeCriteria(); - - /** - * Update the history of executions. - * - * @param response the response to be updated - */ - void updateHistoryExecution(CriteriaResponse response); - - /** - * Get the key of the switcher. - * - * @return the key of the switcher - */ - String getSwitcherKey(); - - /** - * Get the entry input list for the switcher. - * - * @return the entry of the switcher - */ - List getEntry(); - -} diff --git a/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java b/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java new file mode 100644 index 00000000..a9f8978d --- /dev/null +++ b/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java @@ -0,0 +1,157 @@ +package com.github.switcherapi.client.model; + +import com.github.switcherapi.client.SwitcherContext; +import com.github.switcherapi.client.SwitcherExecutor; +import com.github.switcherapi.client.exception.SwitcherException; + +import java.util.*; + +/** + * SwitcherRequest are the entry point to evaluate criteria and return the result. + *
To execute a criteria evaluation, use one of the available methods: {@link #isItOn()}. + * + * @author Roger Floriano (petruki) + * @since 2019-12-24 + * + * @see #isItOn() + * @see #submit() + */ +public final class SwitcherRequest extends SwitcherBuilder { + + public static final String KEY = "key"; + + public static final String SHOW_REASON = "showReason"; + + public static final String BYPASS_METRIC = "bypassMetric"; + + private final SwitcherExecutor switcherExecutor; + + private final String switcherKey; + + private final Set historyExecution; + + private AsyncSwitcher asyncSwitcher; + + /** + * Use {@link SwitcherContext#getSwitcher(String)} to create this object. + * + * @param switcherKey name of the key created + * @param switcherExecutor client context in which the switcher will be executed (local/remote) + */ + public SwitcherRequest(final String switcherKey, final SwitcherExecutor switcherExecutor) { + super(switcherExecutor.getSwitcherProperties()); + this.switcherExecutor = switcherExecutor; + this.switcherKey = switcherKey; + this.historyExecution = new HashSet<>(); + this.entry = new ArrayList<>(); + } + + @Override + public SwitcherRequest build() { + return this; + } + + @Override + public SwitcherRequest prepareEntry(final List entry) { + this.entry = Optional.ofNullable(entry).orElse(new ArrayList<>()); + return this; + } + + @Override + public SwitcherRequest prepareEntry(final Entry entry, final boolean add) { + if (!add) { + this.entry.clear(); + } + + if (!this.entry.contains(entry)) { + this.entry.add(entry); + } + + return this; + } + + @Override + public SwitcherRequest prepareEntry(final Entry entry) { + return this.prepareEntry(entry, false); + } + + @Override + public boolean isItOn() throws SwitcherException { + final SwitcherResult response = submit(); + return response.isItOn(); + } + + @Override + public SwitcherResult submit() throws SwitcherException { + if (SwitcherExecutor.getBypass().containsKey(switcherKey)) { + return SwitcherExecutor.getBypass().get(switcherKey).buildFromSwitcher(switcherKey, entry); + } + + if (canUseAsync()) { + if (Objects.isNull(asyncSwitcher)) { + asyncSwitcher = new AsyncSwitcher(this, super.delay); + } + + asyncSwitcher.execute(); + final Optional response = getFromHistory(); + if (response.isPresent()) { + return response.get(); + } + } + + final SwitcherResult response = this.switcherExecutor.executeCriteria(this); + this.updateHistoryExecution(response); + return response; + } + + @Override + public SwitcherResult executeCriteria() { + return this.switcherExecutor.executeCriteria(this); + } + + @Override + public void updateHistoryExecution(final SwitcherResult response) { + this.historyExecution.removeIf(item -> + this.switcherKey.equals(item.getSwitcherKey()) && this.entry.equals(item.getEntry())); + + this.historyExecution.add(response); + } + + @Override + public String getSwitcherKey() { + return this.switcherKey; + } + + @Override + public List getEntry() { + return this.entry; + } + + public boolean isBypassMetrics() { + return bypassMetrics; + } + + public void resetEntry() { + this.entry = new ArrayList<>(); + } + + private boolean canUseAsync() { + return super.delay > 0 && !this.historyExecution.isEmpty(); + } + + private Optional getFromHistory() { + for (SwitcherResult switcherResult : historyExecution) { + if (switcherResult.getEntry().equals(getEntry())) { + return Optional.of(switcherResult); + } + } + return Optional.empty(); + } + + @Override + public String toString() { + return String.format("SwitcherRequest [switcherKey= %s, entry= %s, bypassMetrics= %s]", + switcherKey, entry, bypassMetrics); + } + +} diff --git a/src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java b/src/main/java/com/github/switcherapi/client/model/SwitcherResult.java similarity index 58% rename from src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java rename to src/main/java/com/github/switcherapi/client/model/SwitcherResult.java index a27d7215..6725fa73 100644 --- a/src/main/java/com/github/switcherapi/client/model/response/CriteriaResponse.java +++ b/src/main/java/com/github/switcherapi/client/model/SwitcherResult.java @@ -1,21 +1,18 @@ -package com.github.switcherapi.client.model.response; +package com.github.switcherapi.client.model; -import java.util.*; - -import com.github.switcherapi.client.model.Entry; -import com.github.switcherapi.client.model.StrategyValidator; -import com.github.switcherapi.client.model.Switcher; import com.google.gson.Gson; +import java.util.*; + /** * @author Roger Floriano (petruki) * @since 2019-12-24 */ -public class CriteriaResponse { +public class SwitcherResult { - private static final String DEFAULT_REASON = "Default result"; + public static final String DEFAULT_REASON = "Default result"; - private static final String DEFAULT_SUCCESS = "Success"; + public static final String DEFAULT_SUCCESS = "Success"; private boolean result; @@ -29,26 +26,27 @@ public class CriteriaResponse { protected Map> entryWhen; - public CriteriaResponse() { + public SwitcherResult() { entryWhen = new HashMap<>(); + entry = new ArrayList<>(); } - public CriteriaResponse(final boolean result, final String reason, final Switcher switcher) { + public SwitcherResult(String switcherKey, boolean result, String reason, List entry) { this(); this.result = result; this.reason = reason; - this.switcherKey = switcher.getSwitcherKey(); - this.entry = switcher.getEntry(); + this.switcherKey = switcherKey; + this.entry = entry; } - public CriteriaResponse buildFromSwitcher(Switcher switcher) { - this.switcherKey = switcher.getSwitcherKey(); - this.entry = switcher.getEntry(); + public SwitcherResult buildFromSwitcher(String switcherKey, List entry) { + this.switcherKey = switcherKey; + this.entry = entry; if (Objects.nonNull(entry)) { for (Entry inputEntry : entry) { if (!isEntryMatching(inputEntry)) { - return new CriteriaResponse(!this.result, this.reason, switcher); + return new SwitcherResult(switcherKey, !this.result, this.reason, entry); } } } @@ -61,18 +59,6 @@ private boolean isEntryMatching(Entry inputEntry) { entryWhen.get(inputEntry.getStrategy()).contains(inputEntry.getInput()); } - public static CriteriaResponse buildFromDefault(Switcher switcher) { - return new CriteriaResponse(Boolean.parseBoolean(switcher.getDefaultResult()), DEFAULT_REASON, switcher); - } - - public static CriteriaResponse buildResultFail(String reason, Switcher switcher) { - return new CriteriaResponse(Boolean.FALSE, reason, switcher); - } - - public static CriteriaResponse buildResultSuccess(Switcher switcher) { - return new CriteriaResponse(Boolean.TRUE, DEFAULT_SUCCESS, switcher); - } - public boolean isItOn() { return result; } @@ -114,11 +100,11 @@ public void setEntry(List entry) { this.entry = entry; } - public CriteriaResponse when(StrategyValidator strategy, String input) { + public SwitcherResult when(StrategyValidator strategy, String input) { return when(strategy, Collections.singletonList(input)); } - public CriteriaResponse when(StrategyValidator strategy, List inputs) { + public SwitcherResult when(StrategyValidator strategy, List inputs) { entryWhen.put(strategy.toString(), inputs); return this; } @@ -137,7 +123,7 @@ public boolean equals(Object obj) { if (getClass() != obj.getClass()) return false; - final CriteriaResponse other = (CriteriaResponse) obj; + final SwitcherResult other = (SwitcherResult) obj; return Objects.equals(entry, other.entry) && result == other.result && Objects.equals(switcherKey, other.switcherKey); @@ -145,7 +131,7 @@ public boolean equals(Object obj) { @Override public String toString() { - return "CriteriaResponse [result=" + result + + return "SwitcherResult [result=" + result + ", reason=" + reason + ", metadata=" + metadata + ", switcherKey=" + switcherKey + diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Criteria.java b/src/main/java/com/github/switcherapi/client/model/criteria/Data.java similarity index 91% rename from src/main/java/com/github/switcherapi/client/model/criteria/Criteria.java rename to src/main/java/com/github/switcherapi/client/model/criteria/Data.java index ba0aeec6..d1f8d47b 100644 --- a/src/main/java/com/github/switcherapi/client/model/criteria/Criteria.java +++ b/src/main/java/com/github/switcherapi/client/model/criteria/Data.java @@ -4,7 +4,7 @@ * @author Roger Floriano (petruki) * @since 2019-12-24 */ -public class Criteria { +public class Data { private Domain domain; diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Snapshot.java b/src/main/java/com/github/switcherapi/client/model/criteria/Snapshot.java index 81e3663f..62dcd3e0 100644 --- a/src/main/java/com/github/switcherapi/client/model/criteria/Snapshot.java +++ b/src/main/java/com/github/switcherapi/client/model/criteria/Snapshot.java @@ -7,17 +7,17 @@ */ public class Snapshot { - private Criteria data; + private Data data; public Domain getDomain() { return data != null ? data.getDomain() : new Domain(); } - public Criteria getData() { + public Data getData() { return data; } - public void setData(Criteria data) { + public void setData(Data data) { this.data = data; } diff --git a/src/main/java/com/github/switcherapi/client/remote/ClientWS.java b/src/main/java/com/github/switcherapi/client/remote/ClientWS.java index ccb79c17..d848a4cc 100644 --- a/src/main/java/com/github/switcherapi/client/remote/ClientWS.java +++ b/src/main/java/com/github/switcherapi/client/remote/ClientWS.java @@ -1,15 +1,12 @@ package com.github.switcherapi.client.remote; +import com.github.switcherapi.client.model.criteria.Snapshot; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; +import com.github.switcherapi.client.remote.dto.*; + import java.util.Optional; import java.util.Set; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.criteria.Snapshot; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; -import com.github.switcherapi.client.model.response.AuthResponse; -import com.github.switcherapi.client.model.response.CriteriaResponse; -import com.github.switcherapi.client.model.response.SnapshotVersionResponse; - /** * @author Roger Floriano {petruki) * @since 2019-12-24 @@ -49,11 +46,11 @@ public interface ClientWS { /** * Returns the verification configured for a specific switcher (key) * - * @param switcher store all necessary input to access the criteria + * @param criteriaRequest Criteria request * @param token Access token * @return the execution based on the configured switcher */ - CriteriaResponse executeCriteria(final Switcher switcher, final String token); + CriteriaResponse executeCriteria(final CriteriaRequest criteriaRequest, final String token); /** * Returns the token to access all available endpoints diff --git a/src/main/java/com/github/switcherapi/client/remote/ClientWSImpl.java b/src/main/java/com/github/switcherapi/client/remote/ClientWSImpl.java index 03b165b8..f56d8ce7 100644 --- a/src/main/java/com/github/switcherapi/client/remote/ClientWSImpl.java +++ b/src/main/java/com/github/switcherapi/client/remote/ClientWSImpl.java @@ -3,13 +3,10 @@ import com.github.switcherapi.client.SwitcherProperties; import com.github.switcherapi.client.exception.SwitcherRemoteException; import com.github.switcherapi.client.model.ContextKey; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.model.criteria.Snapshot; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; -import com.github.switcherapi.client.model.response.AuthRequest; -import com.github.switcherapi.client.model.response.AuthResponse; -import com.github.switcherapi.client.model.response.CriteriaResponse; -import com.github.switcherapi.client.model.response.SnapshotVersionResponse; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; +import com.github.switcherapi.client.remote.dto.*; import javax.ws.rs.client.Client; import javax.ws.rs.client.Entity; @@ -48,22 +45,21 @@ public static ClientWS build(SwitcherProperties switcherProperties, ExecutorServ } @Override - public CriteriaResponse executeCriteria(final Switcher switcher, final String token) { + public CriteriaResponse executeCriteria(final CriteriaRequest criteriaRequest, final String token) { final String url = switcherProperties.getValue(ContextKey.URL); final WebTarget myResource = client.target(String.format(CRITERIA_URL, url)) - .queryParam(Switcher.KEY, switcher.getSwitcherKey()) - .queryParam(Switcher.SHOW_REASON, Boolean.TRUE) - .queryParam(Switcher.BYPASS_METRIC, switcher.isBypassMetrics()); + .queryParam(SwitcherRequest.KEY, criteriaRequest.getSwitcherKey()) + .queryParam(SwitcherRequest.SHOW_REASON, Boolean.TRUE) + .queryParam(SwitcherRequest.BYPASS_METRIC, criteriaRequest.isBypassMetric()); try { final Response response = myResource.request(MediaType.APPLICATION_JSON) .header(HEADER_AUTHORIZATION, String.format(TOKEN_TEXT, token)) - .post(Entity.json(switcher.getInputRequest())); + .post(Entity.json(criteriaRequest.getInputRequest())); if (response.getStatus() == 200) { final CriteriaResponse criteriaResponse = response.readEntity(CriteriaResponse.class); - criteriaResponse.setSwitcherKey(switcher.getSwitcherKey()); - criteriaResponse.setEntry(switcher.getEntry()); + criteriaResponse.setSwitcherKey(criteriaRequest.getSwitcherKey()); response.close(); return criteriaResponse; diff --git a/src/main/java/com/github/switcherapi/client/remote/Constants.java b/src/main/java/com/github/switcherapi/client/remote/Constants.java index df0a3f4f..c61772ea 100644 --- a/src/main/java/com/github/switcherapi/client/remote/Constants.java +++ b/src/main/java/com/github/switcherapi/client/remote/Constants.java @@ -8,8 +8,9 @@ public final class Constants { public static final int DEFAULT_POOL_SIZE = 2; public static final String HEADER_AUTHORIZATION = "Authorization"; public static final String HEADER_APIKEY = "switcher-api-key"; + public static final String HEADER_CONTENT_TYPE = "Content-Type"; + public static final String HEADER_JSON = "application/json"; public static final String TOKEN_TEXT = "Bearer %s"; - public static final String[] CONTENT_TYPE = { "Content-Type", "application/json" }; public static final String QUERY = "{\"query\":\"{ domain(name: \\\"%s\\\", environment: \\\"%s\\\", _component: \\\"%s\\\") { " + diff --git a/src/main/java/com/github/switcherapi/client/model/response/AuthRequest.java b/src/main/java/com/github/switcherapi/client/remote/dto/AuthRequest.java similarity index 93% rename from src/main/java/com/github/switcherapi/client/model/response/AuthRequest.java rename to src/main/java/com/github/switcherapi/client/remote/dto/AuthRequest.java index 4ae46439..63f86f75 100644 --- a/src/main/java/com/github/switcherapi/client/model/response/AuthRequest.java +++ b/src/main/java/com/github/switcherapi/client/remote/dto/AuthRequest.java @@ -1,4 +1,4 @@ -package com.github.switcherapi.client.model.response; +package com.github.switcherapi.client.remote.dto; /** * @author Roger Floriano (petruki) diff --git a/src/main/java/com/github/switcherapi/client/model/response/AuthResponse.java b/src/main/java/com/github/switcherapi/client/remote/dto/AuthResponse.java similarity index 69% rename from src/main/java/com/github/switcherapi/client/model/response/AuthResponse.java rename to src/main/java/com/github/switcherapi/client/remote/dto/AuthResponse.java index d9c97c3c..db336a61 100644 --- a/src/main/java/com/github/switcherapi/client/model/response/AuthResponse.java +++ b/src/main/java/com/github/switcherapi/client/remote/dto/AuthResponse.java @@ -1,4 +1,4 @@ -package com.github.switcherapi.client.model.response; +package com.github.switcherapi.client.remote.dto; /** * @author Roger Floriano (petruki) @@ -26,4 +26,11 @@ public boolean isExpired() { return (this.exp * 1000) < System.currentTimeMillis(); } + @Override + public String toString() { + return "AuthResponse{" + + "token='" + token + '\'' + + ", exp=" + exp + + '}'; + } } diff --git a/src/main/java/com/github/switcherapi/client/remote/dto/CriteriaRequest.java b/src/main/java/com/github/switcherapi/client/remote/dto/CriteriaRequest.java new file mode 100644 index 00000000..8a06239f --- /dev/null +++ b/src/main/java/com/github/switcherapi/client/remote/dto/CriteriaRequest.java @@ -0,0 +1,66 @@ +package com.github.switcherapi.client.remote.dto; + +import com.github.switcherapi.client.model.Entry; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +public class CriteriaRequest { + + private String switcherKey; + + private List entry; + + private boolean bypassMetric; + + public String getSwitcherKey() { + return switcherKey; + } + + public void setSwitcherKey(String switcherKey) { + this.switcherKey = switcherKey; + } + + public List getEntry() { + return entry; + } + + public void setEntry(List entry) { + this.entry = entry; + } + + public boolean isBypassMetric() { + return bypassMetric; + } + + public void setBypassMetric(boolean bypassMetric) { + this.bypassMetric = bypassMetric; + } + + /** + * This method builds up the request made by the client to reach the Switcher API. + * + * @return json input request + */ + public CriteriaRequest.GsonInputRequest getInputRequest() { + return new CriteriaRequest.GsonInputRequest( + Optional.ofNullable(this.entry) + .orElseGet(ArrayList::new) + .toArray(new Entry[0])); + } + + public static class GsonInputRequest { + + private final Entry[] entry; + + public GsonInputRequest(final Entry[] entry) { + this.entry = entry; + } + + public Entry[] getEntry() { + return this.entry; + } + } + +} diff --git a/src/main/java/com/github/switcherapi/client/remote/dto/CriteriaResponse.java b/src/main/java/com/github/switcherapi/client/remote/dto/CriteriaResponse.java new file mode 100644 index 00000000..b8d4789b --- /dev/null +++ b/src/main/java/com/github/switcherapi/client/remote/dto/CriteriaResponse.java @@ -0,0 +1,42 @@ +package com.github.switcherapi.client.remote.dto; + +public class CriteriaResponse { + + private boolean result; + + private String reason; + + private Object metadata; + + private String switcherKey; + + public boolean getResult() { + return result; + } + + public String getReason() { + return reason; + } + + public Object getMetadata() { + return metadata; + } + + public String getSwitcherKey() { + return switcherKey; + } + + public void setSwitcherKey(String switcherKey) { + this.switcherKey = switcherKey; + } + + @Override + public String toString() { + return "CriteriaResponse{" + + "result=" + result + + ", reason='" + reason + '\'' + + ", metadata=" + metadata + + ", switcherKey='" + switcherKey + '\'' + + '}'; + } +} diff --git a/src/main/java/com/github/switcherapi/client/model/response/SnapshotVersionResponse.java b/src/main/java/com/github/switcherapi/client/remote/dto/SnapshotVersionResponse.java similarity index 60% rename from src/main/java/com/github/switcherapi/client/model/response/SnapshotVersionResponse.java rename to src/main/java/com/github/switcherapi/client/remote/dto/SnapshotVersionResponse.java index 8b7b6f6d..530b6e10 100644 --- a/src/main/java/com/github/switcherapi/client/model/response/SnapshotVersionResponse.java +++ b/src/main/java/com/github/switcherapi/client/remote/dto/SnapshotVersionResponse.java @@ -1,4 +1,4 @@ -package com.github.switcherapi.client.model.response; +package com.github.switcherapi.client.remote.dto; /** * @author Roger Floriano (petruki) @@ -16,4 +16,10 @@ public void setStatus(boolean status) { this.status = status; } + @Override + public String toString() { + return "SnapshotVersionResponse{" + + "status=" + status + + '}'; + } } diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/SwitchersCheck.java b/src/main/java/com/github/switcherapi/client/remote/dto/SwitchersCheck.java similarity index 94% rename from src/main/java/com/github/switcherapi/client/model/criteria/SwitchersCheck.java rename to src/main/java/com/github/switcherapi/client/remote/dto/SwitchersCheck.java index 2a7a77ae..a43bd3bf 100644 --- a/src/main/java/com/github/switcherapi/client/model/criteria/SwitchersCheck.java +++ b/src/main/java/com/github/switcherapi/client/remote/dto/SwitchersCheck.java @@ -1,4 +1,4 @@ -package com.github.switcherapi.client.model.criteria; +package com.github.switcherapi.client.remote.dto; import java.util.Arrays; import java.util.Set; diff --git a/src/main/java/com/github/switcherapi/client/service/SwitcherFactory.java b/src/main/java/com/github/switcherapi/client/service/SwitcherFactory.java new file mode 100644 index 00000000..35aef579 --- /dev/null +++ b/src/main/java/com/github/switcherapi/client/service/SwitcherFactory.java @@ -0,0 +1,28 @@ +package com.github.switcherapi.client.service; + +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.SwitcherResult; + +import static com.github.switcherapi.client.model.SwitcherResult.DEFAULT_REASON; +import static com.github.switcherapi.client.model.SwitcherResult.DEFAULT_SUCCESS; + +public class SwitcherFactory { + + private SwitcherFactory() {} + + public static SwitcherResult buildFromDefault(SwitcherRequest switcher) { + return new SwitcherResult( + switcher.getSwitcherKey(), + Boolean.parseBoolean(switcher.getDefaultResult()), + DEFAULT_REASON, switcher.getEntry()); + } + + public static SwitcherResult buildResultFail(String reason, SwitcherRequest switcher) { + return new SwitcherResult(switcher.getSwitcherKey(), Boolean.FALSE, reason, switcher.getEntry()); + } + + public static SwitcherResult buildResultSuccess(SwitcherRequest switcher) { + return new SwitcherResult(switcher.getSwitcherKey(), Boolean.TRUE, DEFAULT_SUCCESS, switcher.getEntry()); + } + +} diff --git a/src/main/java/com/github/switcherapi/client/service/local/ClientLocal.java b/src/main/java/com/github/switcherapi/client/service/local/ClientLocal.java index cabcc403..3c43eb44 100644 --- a/src/main/java/com/github/switcherapi/client/service/local/ClientLocal.java +++ b/src/main/java/com/github/switcherapi/client/service/local/ClientLocal.java @@ -1,9 +1,9 @@ package com.github.switcherapi.client.service.local; import com.github.switcherapi.client.exception.SwitcherException; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.model.criteria.Domain; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherResult; import java.util.List; import java.util.Set; @@ -34,6 +34,6 @@ public interface ClientLocal { * @return The criteria result * @throws SwitcherException If encountered either invalid input or misconfiguration */ - CriteriaResponse executeCriteria(final Switcher switcher, final Domain domain); + SwitcherResult executeCriteria(final SwitcherRequest switcher, final Domain domain); } diff --git a/src/main/java/com/github/switcherapi/client/service/local/ClientLocalService.java b/src/main/java/com/github/switcherapi/client/service/local/ClientLocalService.java index 361244c9..dd2dae25 100644 --- a/src/main/java/com/github/switcherapi/client/service/local/ClientLocalService.java +++ b/src/main/java/com/github/switcherapi/client/service/local/ClientLocalService.java @@ -3,12 +3,13 @@ import com.github.switcherapi.client.exception.SwitcherException; import com.github.switcherapi.client.exception.SwitcherKeyNotFoundException; import com.github.switcherapi.client.model.Entry; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.model.criteria.Config; import com.github.switcherapi.client.model.criteria.Domain; import com.github.switcherapi.client.model.criteria.Group; import com.github.switcherapi.client.model.criteria.Strategy; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherResult; +import com.github.switcherapi.client.service.SwitcherFactory; import com.github.switcherapi.client.service.SwitcherValidator; import com.github.switcherapi.client.utils.SwitcherUtils; import org.apache.commons.lang3.ArrayUtils; @@ -61,9 +62,9 @@ public List checkSwitchers(final Set switchers, final Domain dom } @Override - public CriteriaResponse executeCriteria(final Switcher switcher, final Domain domain) { + public SwitcherResult executeCriteria(final SwitcherRequest switcher, final Domain domain) { if (!domain.isActivated()) { - return CriteriaResponse.buildResultFail(DISABLED_DOMAIN, switcher); + return SwitcherFactory.buildResultFail(DISABLED_DOMAIN, switcher); } Config config; @@ -71,27 +72,27 @@ public CriteriaResponse executeCriteria(final Switcher switcher, final Domain do config = findConfigInGroup(group, switcher.getSwitcherKey()); if (config != null) { - return getCriteriaResponse(switcher, group, config); + return getSwitcherResult(switcher, group, config); } } throw new SwitcherKeyNotFoundException(switcher.getSwitcherKey()); } - private CriteriaResponse getCriteriaResponse(Switcher switcher, Group group, Config config) { + private SwitcherResult getSwitcherResult(SwitcherRequest switcher, Group group, Config config) { if (!group.isActivated()) { - return CriteriaResponse.buildResultFail(DISABLED_GROUP, switcher); + return SwitcherFactory.buildResultFail(DISABLED_GROUP, switcher); } if (!config.isActivated()) { - return CriteriaResponse.buildResultFail(DISABLED_CONFIG, switcher); + return SwitcherFactory.buildResultFail(DISABLED_CONFIG, switcher); } if (ArrayUtils.isNotEmpty(config.getStrategies())) { return this.processOperation(config.getStrategies(), switcher.getEntry(), switcher); } - return CriteriaResponse.buildResultSuccess(switcher); + return SwitcherFactory.buildResultSuccess(switcher); } private Config findConfigInGroup(final Group group, final String switcherKey) { @@ -106,11 +107,11 @@ private Config findConfigInGroup(final Group group, final String switcherKey) { * * @param configStrategies to be processed * @param input sent by the client - * @return CriteriaResponse containing the result of the execution + * @return SwitcherResult containing the result of the execution * @throws SwitcherException If encountered either invalid input or misconfiguration */ - private CriteriaResponse processOperation(final Strategy[] configStrategies, final List input, - final Switcher switcher) { + private SwitcherResult processOperation(final Strategy[] configStrategies, final List input, + final SwitcherRequest switcher) { SwitcherUtils.debug(logger, LOG_PROCESS_OP_TEMPLATE, Arrays.toString(configStrategies)); for (final Strategy strategy : configStrategies) { @@ -129,11 +130,11 @@ private CriteriaResponse processOperation(final Strategy[] configStrategies, fin } } - return CriteriaResponse.buildResultSuccess(switcher); + return SwitcherFactory.buildResultSuccess(switcher); } - private CriteriaResponse strategyFailed(Switcher switcher, Strategy strategy, String pattern) { - return CriteriaResponse.buildResultFail(String.format(pattern, strategy.getStrategy()), switcher); + private SwitcherResult strategyFailed(SwitcherRequest switcher, Strategy strategy, String pattern) { + return SwitcherFactory.buildResultFail(String.format(pattern, strategy.getStrategy()), switcher); } private Entry tryGetSwitcherInput(final List input, Strategy strategy) { 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 8e98a52c..8a4207a9 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,11 +2,16 @@ import com.github.switcherapi.client.SwitcherExecutor; import com.github.switcherapi.client.SwitcherProperties; -import com.github.switcherapi.client.exception.*; +import com.github.switcherapi.client.exception.SwitcherException; +import com.github.switcherapi.client.exception.SwitcherKeyNotFoundException; +import com.github.switcherapi.client.exception.SwitcherSnapshotLoadException; +import com.github.switcherapi.client.exception.SwitchersValidationException; import com.github.switcherapi.client.model.ContextKey; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.SwitcherResult; +import com.github.switcherapi.client.service.SwitcherFactory; import com.github.switcherapi.client.service.remote.ClientRemote; +import com.github.switcherapi.client.utils.Mapper; import com.github.switcherapi.client.utils.SnapshotEventHandler; import com.github.switcherapi.client.utils.SnapshotLoader; import com.github.switcherapi.client.utils.SwitcherUtils; @@ -99,13 +104,13 @@ public boolean notifyChange(final String snapshotFile) { } @Override - public CriteriaResponse executeCriteria(final Switcher switcher) { + public SwitcherResult executeCriteria(final SwitcherRequest switcher) { SwitcherUtils.debug(logger, "[Local] request: {}", switcher); - CriteriaResponse response; + SwitcherResult response; try { if (switcher.isRemote()) { - response = this.clientRemote.executeCriteria(switcher); + response = Mapper.mapFrom(this.clientRemote.executeCriteria(Mapper.mapFrom(switcher))); SwitcherUtils.debug(logger, "[Remote] response: {}", response); } else { response = this.clientLocal.executeCriteria(switcher, this.domain); @@ -116,7 +121,7 @@ public CriteriaResponse executeCriteria(final Switcher switcher) { throw e; } - response = CriteriaResponse.buildFromDefault(switcher); + response = SwitcherFactory.buildFromDefault(switcher); SwitcherUtils.debug(logger, "[Default] response: {}", response); } diff --git a/src/main/java/com/github/switcherapi/client/service/remote/ClientRemote.java b/src/main/java/com/github/switcherapi/client/service/remote/ClientRemote.java index 9bc71dcf..82707c6c 100644 --- a/src/main/java/com/github/switcherapi/client/service/remote/ClientRemote.java +++ b/src/main/java/com/github/switcherapi/client/service/remote/ClientRemote.java @@ -1,10 +1,10 @@ package com.github.switcherapi.client.service.remote; import com.github.switcherapi.client.exception.SwitcherException; -import com.github.switcherapi.client.model.Switcher; import com.github.switcherapi.client.model.criteria.Snapshot; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; +import com.github.switcherapi.client.remote.dto.CriteriaRequest; +import com.github.switcherapi.client.remote.dto.CriteriaResponse; import java.util.Set; @@ -19,11 +19,11 @@ public interface ClientRemote { * validating from the top of the node (Domain) ascending to the lower level * (Strategy) * - * @param switcher Configuration switcher to be validated + * @param criteriaRequest Criteria request * @return The criteria result * @throws SwitcherException If encountered either invalid input or misconfiguration */ - CriteriaResponse executeCriteria(final Switcher switcher); + CriteriaResponse executeCriteria(final CriteriaRequest criteriaRequest); /** * Resolve the snapshot from the remote server diff --git a/src/main/java/com/github/switcherapi/client/service/remote/ClientRemoteService.java b/src/main/java/com/github/switcherapi/client/service/remote/ClientRemoteService.java index d4197f64..75fe6b58 100644 --- a/src/main/java/com/github/switcherapi/client/service/remote/ClientRemoteService.java +++ b/src/main/java/com/github/switcherapi/client/service/remote/ClientRemoteService.java @@ -5,12 +5,9 @@ import com.github.switcherapi.client.exception.SwitcherInvalidDateTimeArgumentException; import com.github.switcherapi.client.exception.SwitcherRemoteException; import com.github.switcherapi.client.model.ContextKey; -import com.github.switcherapi.client.model.Switcher; import com.github.switcherapi.client.model.criteria.Snapshot; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; -import com.github.switcherapi.client.model.response.AuthResponse; -import com.github.switcherapi.client.model.response.CriteriaResponse; -import com.github.switcherapi.client.model.response.SnapshotVersionResponse; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; +import com.github.switcherapi.client.remote.dto.*; import com.github.switcherapi.client.remote.ClientWS; import com.github.switcherapi.client.utils.SwitcherUtils; import org.apache.commons.lang3.StringUtils; @@ -41,13 +38,13 @@ public ClientRemoteService(ClientWS clientWs, SwitcherProperties switcherPropert } @Override - public CriteriaResponse executeCriteria(final Switcher switcher) { + public CriteriaResponse executeCriteria(final CriteriaRequest criteriaRequest) { final TokenStatus tokenStatus = this.isTokenValid(); try { this.auth(tokenStatus); - return this.clientWs.executeCriteria(switcher, + return this.clientWs.executeCriteria(criteriaRequest, Optional.of(this.authResponse).orElseGet(AuthResponse::new).getToken()); } catch (final SwitcherRemoteException e) { if (tokenStatus != TokenStatus.SILENT) { 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 a4282281..d3b5c782 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 @@ -4,9 +4,12 @@ import com.github.switcherapi.client.exception.SwitcherRemoteException; import com.github.switcherapi.client.exception.SwitchersValidationException; import com.github.switcherapi.client.model.ContextKey; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.SwitcherResult; +import com.github.switcherapi.client.remote.dto.CriteriaResponse; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; +import com.github.switcherapi.client.service.SwitcherFactory; +import com.github.switcherapi.client.utils.Mapper; import com.github.switcherapi.client.utils.SwitcherUtils; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; @@ -34,31 +37,31 @@ public SwitcherRemoteService(ClientRemote clientRemote, SwitcherExecutor switche } @Override - public CriteriaResponse executeCriteria(final Switcher switcher) { + public SwitcherResult executeCriteria(final SwitcherRequest switcher) { SwitcherUtils.debug(logger, "[Remote] request: {}", switcher); try { - final CriteriaResponse response = this.clientRemote.executeCriteria(switcher); + final CriteriaResponse response = this.clientRemote.executeCriteria(Mapper.mapFrom(switcher)); SwitcherUtils.debug(logger, "[Remote] response: {}", response); - return response; + return Mapper.mapFrom(response); } catch (final SwitcherRemoteException e) { logger.error("Failed to execute criteria - Cause: {}", e.getMessage(), e.getCause()); return tryExecuteLocalCriteria(switcher, e); } } - private CriteriaResponse tryExecuteLocalCriteria(final Switcher switcher, - final SwitcherRemoteException e) { + private SwitcherResult tryExecuteLocalCriteria(final SwitcherRequest switcher, + final SwitcherRemoteException e) { if (StringUtils.isNotBlank(switcherProperties.getValue(ContextKey.SILENT_MODE))) { - final CriteriaResponse response = this.switcherLocal.executeCriteria(switcher); + final SwitcherResult response = this.switcherLocal.executeCriteria(switcher); SwitcherUtils.debug(logger, "[Silent] response: {}", response); return response; } if (StringUtils.isNotBlank(switcher.getDefaultResult())) { - final CriteriaResponse response = CriteriaResponse.buildFromDefault(switcher); + final SwitcherResult response = SwitcherFactory.buildFromDefault(switcher); SwitcherUtils.debug(logger, "[Default] response: {}", response); return response; diff --git a/src/main/java/com/github/switcherapi/client/test/SwitcherTestExtension.java b/src/main/java/com/github/switcherapi/client/test/SwitcherTestExtension.java index 04dc6a06..0abbdfaf 100644 --- a/src/main/java/com/github/switcherapi/client/test/SwitcherTestExtension.java +++ b/src/main/java/com/github/switcherapi/client/test/SwitcherTestExtension.java @@ -1,7 +1,7 @@ package com.github.switcherapi.client.test; import com.github.switcherapi.client.SwitcherExecutor; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherResult; import org.apache.commons.lang3.ArrayUtils; import org.junit.jupiter.api.extension.*; import org.junit.jupiter.api.extension.ExtensionContext.Namespace; @@ -79,22 +79,22 @@ private void mockMultipleSwitchers(ExtensionContext context, SwitcherTest switch .toArray(String[]::new); for (SwitcherTestValue value : switcherTest.switchers()) { - CriteriaResponse criteriaResponse = SwitcherExecutor.assume(value.key(), inverted != value.result(), value.metadata()); - applySwitcherTestWhen(criteriaResponse, value.when()); + SwitcherResult switcherResult = SwitcherExecutor.assume(value.key(), inverted != value.result(), value.metadata()); + applySwitcherTestWhen(switcherResult, value.when()); } getStore(context).put(STORE_KEYS, keys); } private void mockSingleSwitcher(ExtensionContext context, SwitcherTest switcherTest, boolean inverted) { - CriteriaResponse criteriaResponse = SwitcherExecutor.assume(switcherTest.key(), inverted != switcherTest.result(), switcherTest.metadata()); - applySwitcherTestWhen(criteriaResponse, switcherTest.when()); + SwitcherResult switcherResult = SwitcherExecutor.assume(switcherTest.key(), inverted != switcherTest.result(), switcherTest.metadata()); + applySwitcherTestWhen(switcherResult, switcherTest.when()); getStore(context).put(STORE_KEY, switcherTest.key()); } - private void applySwitcherTestWhen(CriteriaResponse criteriaResponse, SwitcherTestWhen[] whens) { + private void applySwitcherTestWhen(SwitcherResult switcherResult, SwitcherTestWhen[] whens) { for (SwitcherTestWhen when : whens) { - criteriaResponse.when(when.strategy(), Arrays.asList(when.input())); + switcherResult.when(when.strategy(), Arrays.asList(when.input())); } } diff --git a/src/main/java/com/github/switcherapi/client/utils/Mapper.java b/src/main/java/com/github/switcherapi/client/utils/Mapper.java new file mode 100644 index 00000000..2c5b6706 --- /dev/null +++ b/src/main/java/com/github/switcherapi/client/utils/Mapper.java @@ -0,0 +1,28 @@ +package com.github.switcherapi.client.utils; + +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.SwitcherResult; +import com.github.switcherapi.client.remote.dto.CriteriaRequest; +import com.github.switcherapi.client.remote.dto.CriteriaResponse; + +public class Mapper { + + private Mapper() {} + + public static CriteriaRequest mapFrom(final SwitcherRequest switcher) { + CriteriaRequest request = new CriteriaRequest(); + request.setSwitcherKey(switcher.getSwitcherKey()); + request.setEntry(switcher.getEntry()); + request.setBypassMetric(switcher.isBypassMetrics()); + return request; + } + + public static SwitcherResult mapFrom(final CriteriaResponse criteriaResponse) { + SwitcherResult switcherResult = new SwitcherResult(); + switcherResult.setSwitcherKey(criteriaResponse.getSwitcherKey()); + switcherResult.setResult(criteriaResponse.getResult()); + switcherResult.setReason(criteriaResponse.getReason()); + switcherResult.setMetadata(criteriaResponse.getMetadata()); + return switcherResult; + } +} diff --git a/src/main/java/com/github/switcherapi/client/utils/SnapshotLoader.java b/src/main/java/com/github/switcherapi/client/utils/SnapshotLoader.java index 0b24cd2d..150b3778 100644 --- a/src/main/java/com/github/switcherapi/client/utils/SnapshotLoader.java +++ b/src/main/java/com/github/switcherapi/client/utils/SnapshotLoader.java @@ -13,6 +13,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Objects; /** * @author Roger Floriano (petruki) @@ -23,7 +24,7 @@ public class SnapshotLoader { private static final String SNAPSHOT_FILE_FORMAT = "%s/%s.json"; private static final Gson gson = new Gson(); - + private SnapshotLoader() {} /** @@ -53,11 +54,42 @@ public static Domain loadSnapshot(final String snapshotFile) throws SwitcherSnap */ public static Domain loadSnapshot(final String snapshotLocation, final String environment) throws SwitcherSnapshotLoadException, IOException { - try (FileReader fileReader = new FileReader(String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment))) { + final String path = String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment); + + try (FileReader fileReader = new FileReader(path)) { final Snapshot data = gson.fromJson(fileReader, Snapshot.class); return data.getDomain(); } catch (JsonSyntaxException | JsonIOException e) { throw new SwitcherSnapshotLoadException(String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment), e); + } catch (FileNotFoundException e) { + return loadSnapshotFromResources(snapshotLocation, environment); + } + } + + /** + * Load snapshot from the resources folder + * + * @param snapshotLocation Snapshot folder + * @param environment name that is represented as [environment].json + * @return Serialized Domain object + * @throws SwitcherSnapshotLoadException when JSON file has errors + * @throws IOException when failing to read JSON file + */ + private static Domain loadSnapshotFromResources(final String snapshotLocation, final String environment) + throws SwitcherSnapshotLoadException, IOException { + final String path = String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment); + + try (InputStream is = SnapshotLoader.class.getResourceAsStream(path)) { + if (Objects.isNull(is)) { + throw new FileNotFoundException(path); + } + + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { + final Snapshot data = gson.fromJson(reader, Snapshot.class); + return data.getDomain(); + } catch (JsonSyntaxException | JsonIOException e) { + throw new SwitcherSnapshotLoadException(String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment), e); + } } } diff --git a/src/main/java/com/github/switcherapi/client/utils/SwitcherUtils.java b/src/main/java/com/github/switcherapi/client/utils/SwitcherUtils.java index de9279cb..74ec7dbe 100644 --- a/src/main/java/com/github/switcherapi/client/utils/SwitcherUtils.java +++ b/src/main/java/com/github/switcherapi/client/utils/SwitcherUtils.java @@ -10,11 +10,8 @@ import org.apache.commons.lang3.time.DateUtils; import org.slf4j.Logger; -import java.util.Date; +import java.util.*; import java.util.Map.Entry; -import java.util.Objects; -import java.util.Properties; -import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -26,9 +23,9 @@ public class SwitcherUtils { private static final String[] DURATION_UNIT = { "s", "m", "h", "d" }; private static final String ENV_VARIABLE_PATTERN = "\\$\\{(\\w+)}"; - private static final String ENV_DEFAULT_VARIABLE_PATTERN = "\\$\\{(\\w+):(.+)}"; + private static final String ENV_DEFAULT_VARIABLE_PATTERN = "\\$\\{(\\w+):(.+)?}"; private static final String PAYLOAD_PATTERN = "%s.%s"; - + private SwitcherUtils() {} public static Date addTimeDuration(final String addValue, final Date date) @@ -101,12 +98,12 @@ public static String resolveProperties(String key, Properties prop) { return null; } - final StringBuilder sBuilder = resolveEnvironmentVariable(value); - if (sBuilder.toString().isEmpty()) { + final Object[] sBuilder = resolveEnvironmentVariable(value); + if (sBuilder[1].equals(Boolean.FALSE) && sBuilder[0].toString().isEmpty()) { return value; } - - return sBuilder.toString(); + + return sBuilder[0].toString(); } /** @@ -118,9 +115,7 @@ public static String resolveProperties(String key, Properties prop) { * @param args arguments to be replaced in the message */ public static void debug(Logger logger, String message, Object... args) { - if (logger.isDebugEnabled()) { - logger.debug(message, args); - } + logger.debug(message, args); } /** @@ -128,9 +123,9 @@ public static void debug(Logger logger, String message, Object... args) { * System environment or default argument. * * @param value assigned from the properties file - * @return Resolved value + * @return Array-pair: Resolved value and a boolean to indicate if it was resolved by var notation ${VAR:VALUE} */ - private static StringBuilder resolveEnvironmentVariable(final String value) { + private static Object[] resolveEnvironmentVariable(final String value) { Pattern pattern = Pattern.compile(ENV_VARIABLE_PATTERN); Matcher matcher = pattern.matcher(value); StringBuilder sBuilder = new StringBuilder(); @@ -143,11 +138,21 @@ private static StringBuilder resolveEnvironmentVariable(final String value) { pattern = Pattern.compile(ENV_DEFAULT_VARIABLE_PATTERN); matcher = pattern.matcher(value); - if (matcher.find() && setWithSystemEnv(matcher, sBuilder) && matcher.group(2) != null) { - sBuilder.append(matcher.group(2)); + if (matcher.find() && setWithSystemEnv(matcher, sBuilder)) { + // when a value is assigned to variable, e.g. ${PORT:8080} + if (Objects.nonNull(matcher.group(2))) { + sBuilder.append(matcher.group(2)); + return new Object[] { sBuilder.toString(), Boolean.TRUE }; + } + + // when nothing is assigned to variable, e.g. ${PORT:} + if (Objects.nonNull(matcher.group(1))) { + return new Object[] { StringUtils.EMPTY, Boolean.TRUE }; + } } } - return sBuilder; + + return new Object[] { sBuilder.toString(), Boolean.FALSE }; } /** @@ -158,10 +163,11 @@ private static StringBuilder resolveEnvironmentVariable(final String value) { * @return true if System.getenv returns a value */ private static boolean setWithSystemEnv(Matcher matcher, StringBuilder sBuilder) { - if (Objects.nonNull(matcher.group(1))) { - String envVarName = matcher.group(1); - String envVarValue = System.getenv(envVarName); - sBuilder.append(null == envVarValue ? StringUtils.EMPTY : envVarValue); + final String envVarName = matcher.group(1); + + if (Objects.nonNull(envVarName)) { + sBuilder.append(Optional.ofNullable(System.getenv(envVarName)) + .orElse(StringUtils.EMPTY)); } return StringUtils.isEmpty(sBuilder.toString()); diff --git a/src/main/resources/META-INF/native-image/com.github.switcherapi.client/switcher-client/reflect-config.json b/src/main/resources/META-INF/native-image/com.github.switcherapi.client/switcher-client/reflect-config.json new file mode 100644 index 00000000..b9bd1dc3 --- /dev/null +++ b/src/main/resources/META-INF/native-image/com.github.switcherapi.client/switcher-client/reflect-config.json @@ -0,0 +1,175 @@ +[ + { + "name": "com.github.switcherapi.client.model.Entry", + "condition": { + "typeReachable": "com.github.switcherapi.client.remote.dto.CriteriaRequest.GsonInputRequest" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.remote.dto.CriteriaRequest.GsonInputRequest", + "condition": { + "typeReachable": "com.github.switcherapi.client.model.Switcher" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.Config", + "condition": { + "typeReachable": "com.github.switcherapi.client.model.criteria.Snapshot" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.Criteria", + "condition": { + "typeReachable": "com.github.switcherapi.client.model.criteria.Snapshot" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.Domain", + "condition": { + "typeReachable": "com.github.switcherapi.client.model.criteria.Snapshot" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.Group", + "condition": { + "typeReachable": "com.github.switcherapi.client.model.criteria.Snapshot" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.Snapshot", + "condition": { + "typeReachable": "com.github.switcherapi.client.SwitcherExecutor" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.Strategy", + "condition": { + "typeReachable": "com.github.switcherapi.client.model.criteria.Snapshot" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.model.criteria.SwitcherElement", + "allDeclaredFields": true + }, + { + "name": "com.github.switcherapi.client.remote.dto.SwitchersCheck", + "condition": { + "typeReachable": "com.github.switcherapi.client.remote.ClientWSImpl" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.remote.dto.AuthRequest", + "condition": { + "typeReachable": "com.github.switcherapi.client.remote.ClientWSImpl" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.remote.dto.AuthResponse", + "condition": { + "typeReachable": "com.github.switcherapi.client.remote.ClientWSImpl" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.remote.dto.SnapshotVersionResponse", + "condition": { + "typeReachable": "com.github.switcherapi.client.remote.ClientWSImpl" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + }, + { + "name": "com.github.switcherapi.client.remote.dto.CriteriaResponse", + "condition": { + "typeReachable": "com.github.switcherapi.client.remote.ClientWSImpl" + }, + "allDeclaredFields": true, + "methods": [ + { + "name": "", + "parameterTypes": [] + } + ] + } +] \ No newline at end of file diff --git a/src/main/resources/META-INF/native-image/com.github.switcherapi.client/switcher-client/resource-config.json b/src/main/resources/META-INF/native-image/com.github.switcherapi.client/switcher-client/resource-config.json new file mode 100644 index 00000000..d47e6561 --- /dev/null +++ b/src/main/resources/META-INF/native-image/com.github.switcherapi.client/switcher-client/resource-config.json @@ -0,0 +1,18 @@ +{ + "resources": { + "includes": [ + { + "pattern": "switcherapi.*\\.properties$", + "condition": { + "typeReachable": "com.github.switcherapi.client.SwitcherContextBase" + } + }, + { + "pattern": "snapshots/.*\\.json$", + "condition": { + "typeReachable": "com.github.switcherapi.client.SwitcherContextBase" + } + } + ] + } +} \ No newline at end of file diff --git a/src/test/java/com/github/switcherapi/SwitchersBaseNative.java b/src/test/java/com/github/switcherapi/SwitchersBaseNative.java new file mode 100644 index 00000000..c40418e5 --- /dev/null +++ b/src/test/java/com/github/switcherapi/SwitchersBaseNative.java @@ -0,0 +1,24 @@ +package com.github.switcherapi; + +import com.github.switcherapi.client.SwitcherContextBase; + +public class SwitchersBaseNative extends SwitcherContextBase { + + public static final String USECASE11 = "USECASE11"; + + @Override + public void configureClient() { + super.registerSwitcherKeys(USECASE11); + super.configureClient(); + } + + public static SwitchersBaseNative buildSwitcherClientConfigMinimal(String url) { + SwitchersBaseNative context = new SwitchersBaseNative(); + context.setUrl(url); + context.setApikey("[API-KEY]"); + context.setDomain("domain"); + context.setComponent("component"); + return context; + } + +} diff --git a/src/test/java/com/github/switcherapi/client/SwitcherBasicCriteriaResponseTest.java b/src/test/java/com/github/switcherapi/client/SwitcherBasicCriteriaResponseTest.java index fc3f5c7a..353af422 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherBasicCriteriaResponseTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherBasicCriteriaResponseTest.java @@ -1,8 +1,8 @@ package com.github.switcherapi.client; import com.github.switcherapi.Switchers; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.SwitcherResult; import com.github.switcherapi.fixture.MetadataErrorSample; import com.github.switcherapi.fixture.MetadataSample; import com.github.switcherapi.fixture.MockWebServerHelper; @@ -58,8 +58,8 @@ void shouldReturnCriteriaResponse() { givenResponse(generateCriteriaResponse("true", "Success")); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); - CriteriaResponse response = switcher.submit(); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherResult response = switcher.submit(); assertTrue(response.isItOn()); assertEquals("Success", response.getReason()); @@ -74,8 +74,8 @@ void shouldReturnCriteriaResponseWithInputs() { givenResponse(generateCriteriaResponse("false", "Strategy VALUE_VALIDATION does not agree")); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); - CriteriaResponse response = switcher + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherResult response = switcher .checkValue("value") .checkNumeric("10") .submit(); @@ -93,8 +93,8 @@ void shouldReturnCriteriaResponseWithMetadata() { givenResponse(generateCriteriaResponse(new MetadataSample("123"))); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); - CriteriaResponse response = switcher.submit(); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherResult response = switcher.submit(); assertEquals("123", response.getMetadata(MetadataSample.class).getTransactionId()); } @@ -108,8 +108,8 @@ void shouldReturnCriteriaResponseWithWrongMetadata() { givenResponse(generateCriteriaResponse(new MetadataErrorSample("123"))); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); - CriteriaResponse response = switcher.submit(); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherResult response = switcher.submit(); assertNotNull(response.getMetadata(MetadataSample.class)); assertNull(response.getMetadata(MetadataSample.class).getTransactionId()); diff --git a/src/test/java/com/github/switcherapi/client/SwitcherBasicTest.java b/src/test/java/com/github/switcherapi/client/SwitcherBasicTest.java index 4848dc3f..7c3dd131 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherBasicTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherBasicTest.java @@ -1,7 +1,7 @@ package com.github.switcherapi.client; import com.github.switcherapi.Switchers; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.MockWebServerHelper; import mockwebserver3.QueueDispatcher; import org.junit.jupiter.api.AfterAll; @@ -56,7 +56,7 @@ void shouldReturnTrue() { givenResponse(generateCriteriaResponse("true", false)); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertTrue(switcher.isItOn()); } @@ -69,7 +69,7 @@ void shouldReturnFalse() { givenResponse(generateCriteriaResponse("false", false)); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertFalse(switcher.isItOn()); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherBypassTest.java b/src/test/java/com/github/switcherapi/client/SwitcherBypassTest.java index 0fdc5167..d23677b0 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherBypassTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherBypassTest.java @@ -1,8 +1,9 @@ package com.github.switcherapi.client; import com.github.switcherapi.client.model.StrategyValidator; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherResult; import com.github.switcherapi.client.test.SwitcherTest; import com.github.switcherapi.client.test.SwitcherTestValue; import com.github.switcherapi.client.test.SwitcherTestWhen; @@ -43,7 +44,7 @@ void shouldReturnFalse_afterAssumingItsFalse() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE11); + SwitcherRequest switcher = getSwitcher(USECASE11); assertTrue(switcher.isItOn()); SwitcherExecutor.assume(USECASE11, false); @@ -56,7 +57,7 @@ void shouldReturnTrue_afterAssumingItsTrue() { SwitcherContext.configure(ContextBuilder.builder().snapshotLocation(SNAPSHOTS_LOCAL).environment(FIXTURE2)); SwitcherContext.initializeClient(); - Switcher switcher = getSwitcher(USECASE111); + SwitcherRequest switcher = getSwitcher(USECASE111); assertFalse(switcher.isItOn()); SwitcherExecutor.assume(USECASE111, true); @@ -70,7 +71,7 @@ void shouldReturnTrue_afterForgettingItWasFalse() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE11); + SwitcherRequest switcher = getSwitcher(USECASE11); assertTrue(switcher.isItOn()); SwitcherExecutor.assume(USECASE11, false); @@ -87,7 +88,7 @@ void shouldReturnFalse_afterAssumingItsTrue() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); + SwitcherRequest switcher = getSwitcher(USECASE111); assertFalse(switcher.isItOn()); SwitcherExecutor.assume(USECASE111, true); @@ -104,7 +105,7 @@ void shouldReturnFalse_usingAnnotationAsFalse() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); + SwitcherRequest switcher = getSwitcher(USECASE111); assertFalse(switcher.isItOn()); } @@ -172,7 +173,7 @@ void shouldReturnTrue_usingAnnotationAsTrue() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); + SwitcherRequest switcher = getSwitcher(USECASE111); assertTrue(switcher.isItOn()); } @@ -183,10 +184,10 @@ void shouldReturnSwitcherBypassedAsReason() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); - CriteriaResponse criteriaResponse = switcher.submit(); - assertTrue(criteriaResponse.isItOn()); - assertEquals("Switcher bypassed", criteriaResponse.getReason()); + SwitcherRequest switcher = getSwitcher(USECASE111); + SwitcherResult switcherResult = switcher.submit(); + assertTrue(switcherResult.isItOn()); + assertEquals("Switcher bypassed", switcherResult.getReason()); } @SwitcherTest(switchers = { @@ -199,7 +200,7 @@ void shouldReturnTrue_usingMultipleSwitchersAnnotation() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); + SwitcherRequest switcher = getSwitcher(USECASE111); assertTrue(switcher.isItOn()); switcher = getSwitcher(USECASE112); @@ -218,9 +219,9 @@ void shouldReturnWithMetadata() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); - CriteriaResponse criteriaResponse = switcher.submit(); - assertEquals("123", criteriaResponse.getMetadata(MetadataSample.class).getTransactionId()); + SwitcherRequest switcher = getSwitcher(USECASE111); + SwitcherResult switcherResult = switcher.submit(); + assertEquals("123", switcherResult.getMetadata(MetadataSample.class).getTransactionId()); } @SwitcherTest(switchers = { @@ -233,13 +234,13 @@ void shouldReturnWithMetadata_usingMultipleSwitchersAnnotation() { SwitcherContext.initializeClient(); //test - Switcher switcher = getSwitcher(USECASE111); - CriteriaResponse criteriaResponse = switcher.submit(); - assertEquals("123", criteriaResponse.getMetadata(MetadataSample.class).getTransactionId()); + SwitcherRequest switcher = getSwitcher(USECASE111); + SwitcherResult switcherResult = switcher.submit(); + assertEquals("123", switcherResult.getMetadata(MetadataSample.class).getTransactionId()); switcher = getSwitcher(USECASE112); - criteriaResponse = switcher.submit(); - assertEquals("321", criteriaResponse.getMetadata(MetadataErrorSample.class).getErrorId()); + switcherResult = switcher.submit(); + assertEquals("321", switcherResult.getMetadata(MetadataErrorSample.class).getErrorId()); } @Test @@ -279,7 +280,7 @@ void shouldReturnFalse_afterAssumingItsTrueWhenValueNotMatches() { * It is used to AB Test behavior when the same result is expected. */ private String workBothWay() { - Switcher switcher = getSwitcher(USECASE111); + SwitcherRequest switcher = getSwitcher(USECASE111); // Using String.format if (switcher.isItOn()) { diff --git a/src/test/java/com/github/switcherapi/client/SwitcherConfigNativeTest.java b/src/test/java/com/github/switcherapi/client/SwitcherConfigNativeTest.java index 73f207b8..aa05535a 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherConfigNativeTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherConfigNativeTest.java @@ -1,14 +1,16 @@ package com.github.switcherapi.client; -import com.github.switcherapi.SwitchersBase; +import com.github.switcherapi.SwitchersBaseNative; import com.github.switcherapi.fixture.MockWebServerHelper; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; -import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assertions.*; class SwitcherConfigNativeTest extends MockWebServerHelper { @@ -24,29 +26,39 @@ static void tearDown() throws IOException { @Test void shouldUseNativeContext() { - SwitchersBase context = buildSwitcherClientConfigMinimal(new SwitchersBase(), String.format("http://localhost:%s", mockBackEnd.getPort())); + SwitchersBaseNative context = SwitchersBaseNative.buildSwitcherClientConfigMinimal(String.format("http://localhost:%s", mockBackEnd.getPort())); context.configureClient(); - givenResponse(generateMockAuth(10)); - givenResponse(generateCriteriaResponse("true", false)); + givenResponse(generateMockAuth(10)); //auth + givenResponse(generateCriteriaResponse("true", false)); //criteria - assertTrue(SwitchersBase.getSwitcher(SwitchersBase.USECASE11).isItOn()); + assertTrue(SwitchersBaseNative.getSwitcher(SwitchersBaseNative.USECASE11).isItOn()); } @Test - void shouldUseNativeContextFromProperties() { - SwitchersBase context = new SwitchersBase(); - context.configureClient("switcherapi-native"); + void shouldUseNativeAndValidateSwitchers() { + SwitchersBaseNative context = SwitchersBaseNative.buildSwitcherClientConfigMinimal(String.format("http://localhost:%s", mockBackEnd.getPort())); + context.configureClient(); + + final Set notFound = new HashSet<>(); + givenResponse(generateMockAuth(10)); //auth + givenResponse(generateCheckSwitchersResponse(notFound)); //criteria/check_switchers - assertTrue(SwitchersBase.getSwitcher(SwitchersBase.USECASE11).isItOn()); + assertDoesNotThrow(SwitchersBaseNative::checkSwitchers); } - private T buildSwitcherClientConfigMinimal(T classConfig, String url) { - classConfig.setUrl(url); - classConfig.setApikey("[API-KEY]"); - classConfig.setDomain("domain"); - classConfig.setComponent("component"); - return classConfig; + @Test + void shouldUseNativeContextFromProperties() { + SwitchersBaseNative context = new SwitchersBaseNative(); + context.registerSwitcherKeys(SwitchersBaseNative.USECASE11); + context.configureClient("switcherapi-native"); + + assertTrue(SwitchersBaseNative.getSwitcher(SwitchersBaseNative.USECASE11).isItOn()); + assertEquals("switcher-client", context.component); + assertEquals("switcher-domain", context.domain); + assertEquals("[API_KEY]", context.apikey); + assertEquals("http://localhost:3000", context.url); + assertEquals("fixture1", context.environment); } } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherContextBuilderTest.java b/src/test/java/com/github/switcherapi/client/SwitcherContextBuilderTest.java index 95aba567..259e191b 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherContextBuilderTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherContextBuilderTest.java @@ -3,7 +3,7 @@ import com.github.switcherapi.SwitchersBase; import com.github.switcherapi.client.exception.SwitcherContextException; import com.github.switcherapi.client.model.ContextKey; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.Test; @@ -33,7 +33,7 @@ void shouldReturnSuccess() { initializeClient(); //test - Switcher switcher = getSwitcher(USECASE11); + SwitcherRequest switcher = getSwitcher(USECASE11); assertTrue(switcher.isItOn()); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherContextRemoteExecutorTest.java b/src/test/java/com/github/switcherapi/client/SwitcherContextRemoteExecutorTest.java index 483a0fa6..2482492f 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherContextRemoteExecutorTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherContextRemoteExecutorTest.java @@ -3,7 +3,7 @@ import com.github.switcherapi.Switchers; import com.github.switcherapi.SwitchersBase; import com.github.switcherapi.client.exception.SwitcherRemoteException; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.MockWebServerHelper; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -47,7 +47,7 @@ void shouldConfigureRemotePoolSize() { SwitchersBase.initializeClient(); //test - Switcher switcher = SwitchersBase.getSwitcher(Switchers.USECASE11); + SwitcherRequest switcher = SwitchersBase.getSwitcher(Switchers.USECASE11); assertTrue(switcher.isItOn()); } @@ -73,7 +73,7 @@ void shouldConfigureRemoteTimeout() { SwitchersBase.initializeClient(); //test - Switcher switcher = SwitchersBase.getSwitcher(Switchers.USECASE11); + SwitcherRequest switcher = SwitchersBase.getSwitcher(Switchers.USECASE11); Exception ex = assertThrows(SwitcherRemoteException.class, switcher::isItOn); assertEquals("java.net.SocketTimeoutException: Read timed out", ex.getCause().getMessage()); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java b/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java index 841ba38f..4deabe53 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherFail1Test.java @@ -3,7 +3,7 @@ import com.github.switcherapi.Switchers; import com.github.switcherapi.client.exception.SwitcherException; import com.github.switcherapi.client.exception.SwitcherRemoteException; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.CountDownHelper; import com.github.switcherapi.fixture.MockWebServerHelper; import mockwebserver3.QueueDispatcher; @@ -59,7 +59,7 @@ void shouldReturnError_keyNotFound() { //criteria givenResponse(generateStatusResponse("404")); - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertThrows(SwitcherRemoteException.class, switcher::isItOn); } @@ -71,7 +71,7 @@ void shouldReturnSuccessDefaultResult_keyNotFound() { //criteria givenResponse(generateStatusResponse("404")); - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertTrue(switcher.defaultResult(true).isItOn()); assertFalse(switcher.defaultResult(false).isItOn()); } @@ -81,7 +81,7 @@ void shouldReturnError_unauthorizedAPIAccess() { //auth givenResponse(generateStatusResponse("401")); - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertThrows(SwitcherException.class, switcher::isItOn); } @@ -93,7 +93,7 @@ void shouldReturnTrue_tokenExpired() { //criteria givenResponse(generateCriteriaResponse("true", false)); - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); //test assertTrue(switcher.isItOn()); diff --git a/src/test/java/com/github/switcherapi/client/SwitcherFail2Test.java b/src/test/java/com/github/switcherapi/client/SwitcherFail2Test.java index 6d3478af..d9cce345 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherFail2Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherFail2Test.java @@ -3,7 +3,7 @@ import com.github.switcherapi.Switchers; import com.github.switcherapi.client.exception.SwitcherContextException; import com.github.switcherapi.client.exception.SwitcherRemoteException; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.MockWebServerHelper; import mockwebserver3.QueueDispatcher; import org.junit.jupiter.api.AfterAll; @@ -56,13 +56,13 @@ void shouldReturnError_componentNotRegistered() { //criteria givenResponse(generateStatusResponse("401")); - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertThrows(SwitcherRemoteException.class, switcher::isItOn); } @Test void shouldReturnError_switcherCannotRunLocally() { - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); Exception ex = assertThrows(SwitcherContextException.class, () -> switcher.remote(false)); assertEquals("Something went wrong: Context has errors - Switcher is not configured to run locally", ex.getMessage()); diff --git a/src/test/java/com/github/switcherapi/client/SwitcherForceResolveTest.java b/src/test/java/com/github/switcherapi/client/SwitcherForceResolveTest.java index d00ba909..5f2d45c0 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherForceResolveTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherForceResolveTest.java @@ -1,7 +1,7 @@ package com.github.switcherapi.client; import com.github.switcherapi.Switchers; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.MockWebServerHelper; import mockwebserver3.QueueDispatcher; import org.apache.commons.lang3.StringUtils; @@ -47,7 +47,7 @@ void restoreStubs() { @Test void shouldResolveLocally() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE11); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE11); assertTrue(switcher.remote(false).isItOn()); } @@ -60,7 +60,7 @@ void shouldForceResolveRemotely() { givenResponse(generateCriteriaResponse("false", false)); //test - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE11); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE11); assertFalse(switcher.remote(true).isItOn()); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java b/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java index f7e4ea69..1c57691c 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java @@ -7,7 +7,7 @@ import com.github.switcherapi.client.model.ContextKey; import com.github.switcherapi.client.model.Entry; import com.github.switcherapi.client.model.StrategyValidator; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.Product; import com.google.gson.Gson; import org.apache.commons.lang3.StringUtils; @@ -49,37 +49,37 @@ void localShouldValidateContext() { @Test void localShouldReturnTrue() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE11, true); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE11, true); assertTrue(switcher.isItOn()); } @Test void localShouldReturnFalse() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE12); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE12); assertFalse(switcher.isItOn()); } @Test void localShouldReturnFalse_groupDisabled() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE21); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE21); assertFalse(switcher.isItOn()); } @Test void localShouldReturnTrue_strategyDisabled() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE71); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE71); assertTrue(switcher.isItOn()); } @Test void localShouldNotReturn_keyNotFound() { - Switcher switcher = Switchers.getSwitcher(Switchers.NOT_FOUND_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.NOT_FOUND_KEY); assertThrows(SwitcherKeyNotFoundException.class, switcher::isItOn); } @Test void localShouldReturnFalse_nullEntryForStrategy() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE31); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE31); List entry = null; assertFalse(switcher @@ -104,24 +104,22 @@ static Stream dateTestArguments() { @ParameterizedTest() @MethodSource("dateTestArguments") void localShouldTest_dateValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.DATE, input); - - switcher.prepareEntry(entry); - assertEquals(expected, switcher.isItOn()); + + assertEquals(expected, switcher.prepareEntry(entry).isItOn()); } @ParameterizedTest() @MethodSource("dateTestArguments") void localShouldTestChained_dateValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); - switcher.checkDate(input); - assertEquals(expected, switcher.isItOn()); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); + assertEquals(expected, switcher.checkDate(input).isItOn()); } @Test void localShouldReturnFalse_dateValidationWrongFormat() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE33); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE33); Entry input = Entry.build(StrategyValidator.DATE, "2019/121/13"); switcher.prepareEntry(input); @@ -148,7 +146,7 @@ static Stream valueTestArguments() { @ParameterizedTest() @MethodSource("valueTestArguments") void localShouldTest_valueValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.VALUE, input); switcher.prepareEntry(entry); @@ -158,7 +156,7 @@ void localShouldTest_valueValidation(String useCaseKey, String input, boolean ex @ParameterizedTest() @MethodSource("valueTestArguments") void localShouldTestChained_valueValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); switcher.checkValue(input); assertEquals(expected, switcher.isItOn()); } @@ -189,7 +187,7 @@ static Stream numericTestArguments() { @ParameterizedTest() @MethodSource("numericTestArguments") void localShouldTest_numericValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.NUMERIC, input); switcher.prepareEntry(entry); @@ -199,14 +197,14 @@ void localShouldTest_numericValidation(String useCaseKey, String input, boolean @ParameterizedTest() @MethodSource("numericTestArguments") void localShouldTestChained_numericValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); switcher.checkNumeric(input); assertEquals(expected, switcher.isItOn()); } @Test void localShouldReturnException_invalidNumericInput() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE81); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE81); Entry input = Entry.build(StrategyValidator.NUMERIC, "INVALID_NUMBER"); switcher.prepareEntry(input); @@ -230,7 +228,7 @@ static Stream timeTestArguments() { @ParameterizedTest() @MethodSource("timeTestArguments") void localShouldTest_timeValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.TIME, input); switcher.prepareEntry(entry); @@ -240,14 +238,13 @@ void localShouldTest_timeValidation(String useCaseKey, String input, boolean exp @ParameterizedTest() @MethodSource("timeTestArguments") void localShouldTestChained_timeValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); - switcher.checkTime(input); - assertEquals(expected, switcher.isItOn()); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); + assertEquals(expected, switcher.checkTime(input).isItOn()); } @Test void localShouldReturnFalse_timeValidationWrongFormat() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE53); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE53); Entry input = Entry.build(StrategyValidator.TIME, "2019-12-10"); switcher.prepareEntry(input); @@ -271,7 +268,7 @@ static Stream networkTestArguments() { @ParameterizedTest() @MethodSource("networkTestArguments") void localShouldTest_networkValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.NETWORK, input); switcher.prepareEntry(entry); @@ -281,20 +278,19 @@ void localShouldTest_networkValidation(String useCaseKey, String input, boolean @ParameterizedTest() @MethodSource("networkTestArguments") void localShouldTestChained_networkValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); - switcher.checkNetwork(input); - assertEquals(expected, switcher.isItOn()); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); + assertEquals(expected, switcher.checkNetwork(input).isItOn()); } @Test void localShouldReturnFalse_strategyRequiresInput() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE63); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE63); assertFalse(switcher.isItOn()); } @Test void localShouldReturnFalse_invalidStrategyInput() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE33); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE33); switcher.prepareEntry(Entry.build(StrategyValidator.INVALID, "Value")); assertFalse(switcher.isItOn()); } @@ -321,7 +317,7 @@ static Stream regexTestArguments() { @ParameterizedTest() @MethodSource("regexTestArguments") void localShouldTest_regexValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.REGEX, input); switcher.prepareEntry(entry); @@ -331,9 +327,8 @@ void localShouldTest_regexValidation(String useCaseKey, String input, boolean ex @ParameterizedTest() @MethodSource("regexTestArguments") void localShouldTestChained_regexValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); - switcher.checkRegex(input); - assertEquals(expected, switcher.isItOn()); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); + assertEquals(expected, switcher.checkRegex(input).isItOn()); } static Stream payloadTestArguments() { @@ -351,7 +346,7 @@ static Stream payloadTestArguments() { @ParameterizedTest() @MethodSource("payloadTestArguments") void localShouldTest_payloadValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); Entry entry = Entry.build(StrategyValidator.PAYLOAD, input); switcher.prepareEntry(entry); @@ -361,9 +356,8 @@ void localShouldTest_payloadValidation(String useCaseKey, String input, boolean @ParameterizedTest() @MethodSource("payloadTestArguments") void localShouldTestChained_payloadValidation(String useCaseKey, String input, boolean expected) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); - switcher.checkPayload(input); - assertEquals(expected, switcher.isItOn()); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); + assertEquals(expected, switcher.checkPayload(input).isItOn()); } } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherLocal2Test.java b/src/test/java/com/github/switcherapi/client/SwitcherLocal2Test.java index 95ad26e4..8a8b0305 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherLocal2Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherLocal2Test.java @@ -9,7 +9,7 @@ import org.junit.jupiter.api.Test; import com.github.switcherapi.Switchers; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; class SwitcherLocal2Test { @@ -28,7 +28,7 @@ static void setupContext() { @Test void localShouldReturnFalse_domainDisabled() { - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE111); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE111); assertFalse(switcher.isItOn()); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java b/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java index 780e1fcd..45bbfa48 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherLocal3Test.java @@ -29,7 +29,7 @@ import com.github.switcherapi.client.exception.SwitchersValidationException; import com.github.switcherapi.client.model.Entry; import com.github.switcherapi.client.model.StrategyValidator; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.client.service.local.SwitcherLocalService; import static com.github.switcherapi.client.remote.Constants.DEFAULT_TIMEOUT; @@ -78,7 +78,7 @@ static Stream failTestArguments() { @MethodSource("failTestArguments") void localShouldReturnError(String useCaseKey, String strategyValidator, String input, Class error) { - Switcher switcher = Switchers.getSwitcher(useCaseKey); + SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey); switcher.prepareEntry(Entry.build(strategyValidator, input)); assertThrows(error, switcher::isItOn); @@ -129,7 +129,7 @@ void localShouldCheckSwitchers_notFound() { @Test void localShouldReturnTrue_defaultResult() { - Switcher switcher = Switchers.getSwitcher(Switchers.NOT_FOUND_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.NOT_FOUND_KEY); assertTrue(switcher.defaultResult(true).isItOn()); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherRemoteUnavailableTest.java b/src/test/java/com/github/switcherapi/client/SwitcherRemoteUnavailableTest.java index ac85acbb..6af80a20 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherRemoteUnavailableTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherRemoteUnavailableTest.java @@ -7,7 +7,7 @@ import com.github.switcherapi.Switchers; import com.github.switcherapi.client.exception.SwitcherRemoteException; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; class SwitcherRemoteUnavailableTest { @@ -23,7 +23,7 @@ void shouldReturnError_noConnection() { SwitcherContext.initializeClient(); //test - Switcher switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.REMOTE_KEY); assertThrows(SwitcherRemoteException.class, switcher::isItOn); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherSilentModeTest.java b/src/test/java/com/github/switcherapi/client/SwitcherSilentModeTest.java index 4ffbbf32..39c1ae7e 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherSilentModeTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherSilentModeTest.java @@ -1,7 +1,7 @@ package com.github.switcherapi.client; import com.github.switcherapi.Switchers; -import com.github.switcherapi.client.model.Switcher; +import com.github.switcherapi.client.model.SwitcherRequest; import com.github.switcherapi.fixture.CountDownHelper; import com.github.switcherapi.fixture.MockWebServerHelper; import mockwebserver3.QueueDispatcher; @@ -64,7 +64,7 @@ void shouldReturnTrue_silentMode() { givenResponse(generateCriteriaResponse("true", false)); //test - Switcher switcher = Switchers.getSwitcher(Switchers.USECASE11); + SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE11); assertTrue(switcher.isItOn()); CountDownHelper.wait(2); diff --git a/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java b/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java index 965ad204..fbb4ceb5 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherSnapshotAutoUpdateTest.java @@ -1,7 +1,7 @@ package com.github.switcherapi.client; import com.github.switcherapi.Switchers; -import com.github.switcherapi.client.model.criteria.Criteria; +import com.github.switcherapi.client.model.criteria.Data; import com.github.switcherapi.client.model.criteria.Domain; import com.github.switcherapi.client.model.criteria.Snapshot; import com.github.switcherapi.client.utils.SnapshotLoader; @@ -60,9 +60,9 @@ void restoreStubs() { static void generateFixture(String environment) { final Snapshot mockedSnapshot = new Snapshot(); - final Criteria criteria = new Criteria(); - criteria.setDomain(DOMAIN_OUTDATED); - mockedSnapshot.setData(criteria); + final Data data = new Data(); + data.setDomain(DOMAIN_OUTDATED); + mockedSnapshot.setData(data); SnapshotLoader.saveSnapshot(mockedSnapshot, SNAPSHOTS_LOCAL, environment); } diff --git a/src/test/java/com/github/switcherapi/client/SwitcherSnapshotValidationTest.java b/src/test/java/com/github/switcherapi/client/SwitcherSnapshotValidationTest.java index 9291f2c1..01014688 100644 --- a/src/test/java/com/github/switcherapi/client/SwitcherSnapshotValidationTest.java +++ b/src/test/java/com/github/switcherapi/client/SwitcherSnapshotValidationTest.java @@ -126,7 +126,7 @@ void shouldValidateAndLoadSnapshot_whenLocal() { void shouldNotValidateAndLoadSnapshot_serviceUnavailable() { //given Switchers.configure(ContextBuilder.builder() - .local(true) + .local(false) .snapshotAutoLoad(false) .snapshotLocation(RESOURCES_PATH) .environment("default")); diff --git a/src/test/java/com/github/switcherapi/client/model/ModelTest.java b/src/test/java/com/github/switcherapi/client/model/ModelTest.java index 137fd45c..85ce136c 100644 --- a/src/test/java/com/github/switcherapi/client/model/ModelTest.java +++ b/src/test/java/com/github/switcherapi/client/model/ModelTest.java @@ -3,7 +3,7 @@ import org.junit.jupiter.api.Test; import com.github.switcherapi.client.model.criteria.Config; -import com.github.switcherapi.client.model.criteria.Criteria; +import com.github.switcherapi.client.model.criteria.Data; import com.github.switcherapi.client.model.criteria.Domain; import com.github.switcherapi.client.model.criteria.Group; import com.github.switcherapi.client.model.criteria.Snapshot; @@ -76,13 +76,13 @@ void testCriteriaPackage() { assertEquals(10000000000L, domain.getVersion()); assertSame(groups, domain.getGroup()); - final Criteria criteria = new Criteria(); - criteria.setDomain(domain); + final Data data = new Data(); + data.setDomain(domain); final Snapshot snapshot = new Snapshot(); - snapshot.setData(criteria); + snapshot.setData(data); - assertSame(criteria, snapshot.getData()); + assertSame(data, snapshot.getData()); } } diff --git a/src/test/java/com/github/switcherapi/client/remote/ClientRemoteTest.java b/src/test/java/com/github/switcherapi/client/remote/ClientRemoteTest.java index 7114428e..fdbed95d 100644 --- a/src/test/java/com/github/switcherapi/client/remote/ClientRemoteTest.java +++ b/src/test/java/com/github/switcherapi/client/remote/ClientRemoteTest.java @@ -3,9 +3,9 @@ import com.github.switcherapi.Switchers; import com.github.switcherapi.client.ContextBuilder; import com.github.switcherapi.client.SwitcherProperties; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; -import com.github.switcherapi.client.model.response.CriteriaResponse; +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.SwitcherResult; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; import com.github.switcherapi.client.service.SwitcherValidator; import com.github.switcherapi.client.service.ValidatorService; import com.github.switcherapi.client.service.local.ClientLocal; @@ -14,6 +14,7 @@ import com.github.switcherapi.client.service.remote.ClientRemote; import com.github.switcherapi.client.service.remote.ClientRemoteService; import com.github.switcherapi.client.service.remote.SwitcherRemoteService; +import com.github.switcherapi.client.utils.Mapper; import com.github.switcherapi.fixture.MockWebServerHelper; import mockwebserver3.QueueDispatcher; import org.junit.jupiter.api.AfterAll; @@ -71,10 +72,11 @@ void shouldExecuteCriteria() { SwitcherValidator validatorService = new ValidatorService(); ClientLocal clientLocal = new ClientLocalService(validatorService); - Switcher switcher = new Switcher("KEY", new SwitcherRemoteService(clientRemote, new SwitcherLocalService(clientRemote, clientLocal, Switchers.getSwitcherProperties()))); + SwitcherRequest switcher = new SwitcherRequest("KEY", new SwitcherRemoteService(clientRemote, + new SwitcherLocalService(clientRemote, clientLocal, Switchers.getSwitcherProperties()))); //test - CriteriaResponse actual = clientRemote.executeCriteria(switcher); + SwitcherResult actual = Mapper.mapFrom(clientRemote.executeCriteria(Mapper.mapFrom(switcher))); assertTrue(actual.isItOn()); } diff --git a/src/test/java/com/github/switcherapi/client/service/local/SwitcherLocalServiceTest.java b/src/test/java/com/github/switcherapi/client/service/local/SwitcherLocalServiceTest.java index f6e77cfe..e0c4953f 100644 --- a/src/test/java/com/github/switcherapi/client/service/local/SwitcherLocalServiceTest.java +++ b/src/test/java/com/github/switcherapi/client/service/local/SwitcherLocalServiceTest.java @@ -62,6 +62,15 @@ void shouldNotifyWithError() { assertFalse(service.notifyChange("defect_default.json")); } + + @Test + void shouldNotifyWithErrorResources() { + SwitchersBase.configure(ContextBuilder.builder() + .snapshotLocation("") + .environment("defect_default")); + + assertFalse(service.notifyChange("defect_default.json")); + } @Test void shouldNotifyWithSuccess() { @@ -70,6 +79,15 @@ void shouldNotifyWithSuccess() { assertTrue(service.notifyChange("snapshot_watcher.json")); } + + @Test + void shouldNotifyWithSuccessResources() { + SwitchersBase.configure(ContextBuilder.builder() + .snapshotLocation("") + .environment("snapshot_watcher")); + + assertTrue(service.notifyChange("snapshot_watcher.json")); + } @Test void shouldNotifyWithSuccess_customHandler() { diff --git a/src/test/java/com/github/switcherapi/client/utils/SnapshotWatcherTest.java b/src/test/java/com/github/switcherapi/client/utils/SnapshotWatcherTest.java index 7307f6a0..e3d6468f 100644 --- a/src/test/java/com/github/switcherapi/client/utils/SnapshotWatcherTest.java +++ b/src/test/java/com/github/switcherapi/client/utils/SnapshotWatcherTest.java @@ -2,8 +2,8 @@ import com.github.switcherapi.SwitchersBase; import com.github.switcherapi.client.ContextBuilder; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.criteria.Criteria; +import com.github.switcherapi.client.model.SwitcherRequest; +import com.github.switcherapi.client.model.criteria.Data; import com.github.switcherapi.client.model.criteria.Snapshot; import com.github.switcherapi.fixture.CountDownHelper; import com.google.gson.Gson; @@ -64,20 +64,20 @@ static void removeGeneratedFiles() throws IOException { static void generateFixture() { final Snapshot mockedSnapshot = new Snapshot(); - final Criteria criteria = new Criteria(); - criteria.setDomain(SnapshotLoader.loadSnapshot(SNAPSHOTS_LOCAL + "/snapshot_watcher.json")); - mockedSnapshot.setData(criteria); + final Data data = new Data(); + data.setDomain(SnapshotLoader.loadSnapshot(SNAPSHOTS_LOCAL + "/snapshot_watcher.json")); + mockedSnapshot.setData(data); SnapshotLoader.saveSnapshot(mockedSnapshot, SNAPSHOTS_LOCAL, "generated_watcher_default"); } void changeFixture() { final Snapshot mockedSnapshot = new Snapshot(); - final Criteria criteria = new Criteria(); - criteria.setDomain(SnapshotLoader.loadSnapshot(SNAPSHOTS_LOCAL + "/snapshot_watcher.json")); - mockedSnapshot.setData(criteria); + final Data data = new Data(); + data.setDomain(SnapshotLoader.loadSnapshot(SNAPSHOTS_LOCAL + "/snapshot_watcher.json")); + mockedSnapshot.setData(data); - criteria.getDomain().setActivated(false); + data.getDomain().setActivated(false); final Gson gson = new GsonBuilder().setPrettyPrinting().create(); writeFixture(gson.toJson(mockedSnapshot)); @@ -98,7 +98,7 @@ void writeFixture(String content) { @Test void shouldNotReloadDomainAfterChangingSnapshot() { - Switcher switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11); + SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11); //initial value is true assertTrue(switcher.isItOn()); @@ -116,7 +116,7 @@ void shouldNotReloadDomainAfterChangingSnapshot() { @Test void shouldReloadDomainAfterChangingSnapshot() { - Switcher switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11); + SwitcherRequest switcher = SwitchersBase.getSwitcher(SwitchersBase.USECASE11); //initial value is true assertTrue(switcher.isItOn()); diff --git a/src/test/java/com/github/switcherapi/client/utils/SwitcherUtilsTest.java b/src/test/java/com/github/switcherapi/client/utils/SwitcherUtilsTest.java index e067d563..8ba979e7 100644 --- a/src/test/java/com/github/switcherapi/client/utils/SwitcherUtilsTest.java +++ b/src/test/java/com/github/switcherapi/client/utils/SwitcherUtilsTest.java @@ -123,6 +123,7 @@ static Stream envArguments() { return Stream.of( Arguments.of("default", "default"), Arguments.of("${PORT:8080}", "8080"), + Arguments.of("${SNAPSHOT_LOCAL:}", ""), Arguments.of("${ENVIRONMENT}", "staging") ); } diff --git a/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java b/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java index 6478e69e..bec19f66 100644 --- a/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java +++ b/src/test/java/com/github/switcherapi/fixture/MockWebServerHelper.java @@ -1,10 +1,10 @@ package com.github.switcherapi.fixture; -import com.github.switcherapi.client.model.Switcher; -import com.github.switcherapi.client.model.criteria.Criteria; +import com.github.switcherapi.client.model.criteria.Data; import com.github.switcherapi.client.model.criteria.Snapshot; -import com.github.switcherapi.client.model.criteria.SwitchersCheck; +import com.github.switcherapi.client.remote.dto.SwitchersCheck; import com.github.switcherapi.client.remote.ClientWSImpl; +import com.github.switcherapi.client.remote.dto.CriteriaRequest; import com.github.switcherapi.client.utils.SnapshotLoader; import com.github.switcherapi.client.utils.SwitcherUtils; import com.google.gson.Gson; @@ -72,9 +72,9 @@ protected MockResponse generateSnapshotResponse(String resourcesPath) { */ protected MockResponse generateSnapshotResponse(String snapshotFile, String resourcesPath) { final Snapshot mockedSnapshot = new Snapshot(); - final Criteria criteria = new Criteria(); - criteria.setDomain(SnapshotLoader.loadSnapshot(resourcesPath + "/" + snapshotFile)); - mockedSnapshot.setData(criteria); + final Data data = new Data(); + data.setDomain(SnapshotLoader.loadSnapshot(resourcesPath + "/" + snapshotFile)); + mockedSnapshot.setData(data); Gson gson = new Gson(); MockResponse.Builder builder = new MockResponse.Builder(); @@ -109,7 +109,7 @@ protected MockResponse generateStatusResponse(String code) { } /** - * @see ClientWSImpl#executeCriteria(Switcher, String) + * @see ClientWSImpl#executeCriteria(CriteriaRequest, String) * * @param result returned by the criteria execution * @param reason if you want to display along with the result @@ -124,7 +124,7 @@ protected MockResponse generateCriteriaResponse(String result, boolean reason) { } /** - * @see ClientWSImpl#executeCriteria(Switcher, String) + * @see ClientWSImpl#executeCriteria(CriteriaRequest, String) * * @param result returned by the criteria execution * @return Generated mock /criteria response @@ -134,7 +134,7 @@ protected MockResponse generateCriteriaResponse(String result) { } /** - * @see ClientWSImpl#executeCriteria(Switcher, String) + * @see ClientWSImpl#executeCriteria(CriteriaRequest, String) * * @param result returned by the criteria execution * @param reason returned by the criteria execution @@ -155,7 +155,7 @@ protected MockResponse generateCriteriaResponse(String result, String reason) { } /** - * @see ClientWSImpl#executeCriteria(Switcher, String) + * @see ClientWSImpl#executeCriteria(CriteriaRequest, String) * * @param metadata returned by the criteria execution * @return Generated mock /criteria response diff --git a/src/test/java/com/github/switcherapi/playground/ClientPlayground.java b/src/test/java/com/github/switcherapi/playground/ClientPlayground.java index 56f59ec5..c5bfd890 100644 --- a/src/test/java/com/github/switcherapi/playground/ClientPlayground.java +++ b/src/test/java/com/github/switcherapi/playground/ClientPlayground.java @@ -1,8 +1,5 @@ package com.github.switcherapi.playground; -import static com.github.switcherapi.playground.Features.*; - -import com.github.switcherapi.client.ContextBuilder; import com.github.switcherapi.client.model.Switcher; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -11,24 +8,20 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; +import static com.github.switcherapi.playground.Features.MY_SWITCHER; +import static com.github.switcherapi.playground.Features.getSwitcher; + public class ClientPlayground { static final Logger logger = LoggerFactory.getLogger(ClientPlayground.class); private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); - + public static void test() { - configure(ContextBuilder.builder() - .context(Features.class.getCanonicalName()) - .url("https://api.switcherapi.com") - .apiKey("[API_KEY]") - .domain("Playground") - .local(true) - .snapshotLocation("src/test/resources/snapshot/playground") - .component("switcher-playground")); - - initializeClient(); - Switcher switcher = getSwitcher(MY_SWITCHER); + new Features().configureClient(); + Switcher switcher = getSwitcher(MY_SWITCHER) + .bypassMetrics() + .build(); scheduler.scheduleAtFixedRate(() -> { long time = System.currentTimeMillis(); @@ -36,7 +29,7 @@ public static void test() { logger.info("Time elapsed: {}", System.currentTimeMillis() - time); }, 0, 5, TimeUnit.SECONDS); } - + public static void main(String[] args) { ClientPlayground.test(); } diff --git a/src/test/java/com/github/switcherapi/playground/Features.java b/src/test/java/com/github/switcherapi/playground/Features.java index 964a43b6..04784103 100644 --- a/src/test/java/com/github/switcherapi/playground/Features.java +++ b/src/test/java/com/github/switcherapi/playground/Features.java @@ -1,5 +1,6 @@ package com.github.switcherapi.playground; +import com.github.switcherapi.client.ContextBuilder; import com.github.switcherapi.client.SwitcherContextBase; import com.github.switcherapi.client.SwitcherKey; @@ -8,4 +9,17 @@ public class Features extends SwitcherContextBase { @SwitcherKey public static final String MY_SWITCHER = "MY_SWITCHER"; + @Override + protected void configureClient() { + configure(ContextBuilder.builder() + .context(Features.class.getCanonicalName()) + .url("https://api.switcherapi.com") + .apiKey("[API_KEY]") + .component("switcher-playground") + .domain("Playground") + .local(true) + .snapshotLocation("/snapshot/playground")); + + initializeClient(); + } }