From 30e12c939f595c5281a3de565eb58050231cff4e Mon Sep 17 00:00:00 2001
From: Roger Floriano <31597636+petruki@users.noreply.github.com>
Date: Sat, 14 Jun 2025 19:37:26 -0700
Subject: [PATCH 1/2] Closes #342 - Added switcher.relay.restrict to allow or
bypass Relay check when local (#343)
---
README.md | 7 +-
.../switcherapi/client/ContextBuilder.java | 9 +
.../client/SwitcherPropertiesImpl.java | 2 +
.../switcherapi/client/model/ContextKey.java | 5 +
.../client/model/EntryOperation.java | 2 -
.../switcherapi/client/model/RelayType.java | 10 +
.../client/model/SwitcherBuilder.java | 24 +-
.../client/model/SwitcherRequest.java | 4 +
.../client/model/criteria/Config.java | 38 +-
.../client/model/criteria/Domain.java | 29 +-
.../client/model/criteria/Group.java | 18 +-
.../client/model/criteria/Relay.java | 27 ++
.../client/model/criteria/Strategy.java | 25 +-
.../model/criteria/SwitcherElement.java | 17 +-
.../switcherapi/client/remote/Constants.java | 1 +
.../service/local/ClientLocalService.java | 5 +
.../client/utils/SnapshotLoader.java | 26 +-
.../client/utils/SnapshotSerializer.java | 108 ++++++
.../com/github/switcherapi/Switchers.java | 6 +
.../client/SwitcherLocal1Test.java | 42 ++-
.../switcherapi/client/model/ModelTest.java | 68 ++--
.../client/utils/SnapshotWatcherTest.java | 10 +-
.../client/validator/ValidatorsTest.java | 9 +-
src/test/resources/default.json | 332 +-----------------
src/test/resources/snapshot/fixture1.json | 205 ++++++++---
src/test/resources/test.json | 3 -
26 files changed, 537 insertions(+), 495 deletions(-)
create mode 100644 src/main/java/com/github/switcherapi/client/model/RelayType.java
create mode 100644 src/main/java/com/github/switcherapi/client/model/criteria/Relay.java
create mode 100644 src/main/java/com/github/switcherapi/client/utils/SnapshotSerializer.java
diff --git a/README.md b/README.md
index ab8bf73b..89c82adb 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ https://github.com/switcherapi/switcher-api
- Able to work local using a snapshot file pulled from your remote Switcher-API Domain.
- Silent mode is a hybrid configuration that automatically enables contingent sub-processes in case of any connectivity issue.
- Built-in test annotation for clear and easy implementation of automated testing.
-- Easy to setup. Switcher Context is responsible to manage all the configuration complexity between your application and API.
+- Easy to set up. Switcher Context is responsible to manage all the configuration complexity between your application and API.
# Usage
@@ -70,6 +70,7 @@ switcher.domain -> Domain name
#optional
switcher.environment -> Environment name
switcher.local -> true/false When local, it will only use a local snapshot
+switcher.relay.restrict -> true/false When true, it will check snapshot relay status
switcher.snapshot.location -> Folder from where snapshots will be saved/read
switcher.snapshot.auto -> true/false Automated lookup for snapshot when initializing the client
switcher.snapshot.skipvalidation -> true/false Skip snapshotValidation() that can be used for UT executions
@@ -250,9 +251,7 @@ MyAppFeatures.scheduleSnapshotAutoUpdate("5s", new SnapshotCallback() {
});
```
-
-
-## Real-time snapshot updater
+## Real-time snapshot reload
Let the Switcher Client manage your application local snapshot.
These features allow you to configure the SDK to automatically update the snapshot in the background.
diff --git a/src/main/java/com/github/switcherapi/client/ContextBuilder.java b/src/main/java/com/github/switcherapi/client/ContextBuilder.java
index fda61419..cb0fad81 100644
--- a/src/main/java/com/github/switcherapi/client/ContextBuilder.java
+++ b/src/main/java/com/github/switcherapi/client/ContextBuilder.java
@@ -182,6 +182,15 @@ public ContextBuilder local(boolean local) {
return this;
}
+ /**
+ * @param restrictRelay true/false When true, it will check snapshot relay status
+ * @return ContextBuilder
+ */
+ public ContextBuilder restrictRelay(boolean restrictRelay) {
+ switcherProperties.setValue(ContextKey.RESTRICT_RELAY, restrictRelay);
+ return this;
+ }
+
/**
* @param truststorePath Path to the truststore file
* @return ContextBuilder
diff --git a/src/main/java/com/github/switcherapi/client/SwitcherPropertiesImpl.java b/src/main/java/com/github/switcherapi/client/SwitcherPropertiesImpl.java
index 1cbf40c2..d8ee7d94 100644
--- a/src/main/java/com/github/switcherapi/client/SwitcherPropertiesImpl.java
+++ b/src/main/java/com/github/switcherapi/client/SwitcherPropertiesImpl.java
@@ -23,6 +23,7 @@ public SwitcherPropertiesImpl() {
setValue(ContextKey.SNAPSHOT_AUTO_LOAD, false);
setValue(ContextKey.SNAPSHOT_SKIP_VALIDATION, false);
setValue(ContextKey.LOCAL_MODE, false);
+ setValue(ContextKey.RESTRICT_RELAY, true);
}
@Override
@@ -39,6 +40,7 @@ public void loadFromProperties(Properties prop) {
setValue(ContextKey.SNAPSHOT_AUTO_UPDATE_INTERVAL, SwitcherUtils.resolveProperties(ContextKey.SNAPSHOT_AUTO_UPDATE_INTERVAL.getParam(), prop));
setValue(ContextKey.SILENT_MODE, SwitcherUtils.resolveProperties(ContextKey.SILENT_MODE.getParam(), prop));
setValue(ContextKey.LOCAL_MODE, getBoolDefault(SwitcherUtils.resolveProperties(ContextKey.LOCAL_MODE.getParam(), prop), false));
+ setValue(ContextKey.RESTRICT_RELAY, getBoolDefault(SwitcherUtils.resolveProperties(ContextKey.RESTRICT_RELAY.getParam(), prop), true));
setValue(ContextKey.REGEX_TIMEOUT, getIntDefault(SwitcherUtils.resolveProperties(ContextKey.REGEX_TIMEOUT.getParam(), prop), DEFAULT_REGEX_TIMEOUT));
setValue(ContextKey.TRUSTSTORE_PATH, SwitcherUtils.resolveProperties(ContextKey.TRUSTSTORE_PATH.getParam(), prop));
setValue(ContextKey.TRUSTSTORE_PASSWORD, SwitcherUtils.resolveProperties(ContextKey.TRUSTSTORE_PASSWORD.getParam(), prop));
diff --git a/src/main/java/com/github/switcherapi/client/model/ContextKey.java b/src/main/java/com/github/switcherapi/client/model/ContextKey.java
index d551e872..e0d62279 100644
--- a/src/main/java/com/github/switcherapi/client/model/ContextKey.java
+++ b/src/main/java/com/github/switcherapi/client/model/ContextKey.java
@@ -69,6 +69,11 @@ public enum ContextKey {
*/
LOCAL_MODE("switcher.local"),
+ /**
+ * (boolean) Defines if client will trigger local snapshot relay verification (default is true)
+ */
+ RESTRICT_RELAY("switcher.relay.restrict"),
+
/**
* (Number) Defines the Timed Match regex time out.
*/
diff --git a/src/main/java/com/github/switcherapi/client/model/EntryOperation.java b/src/main/java/com/github/switcherapi/client/model/EntryOperation.java
index 882fac59..2d3ab6c2 100644
--- a/src/main/java/com/github/switcherapi/client/model/EntryOperation.java
+++ b/src/main/java/com/github/switcherapi/client/model/EntryOperation.java
@@ -1,7 +1,6 @@
package com.github.switcherapi.client.model;
public enum EntryOperation {
-
EQUAL,
NOT_EQUAL,
EXIST,
@@ -12,5 +11,4 @@ public enum EntryOperation {
HAS_ONE,
HAS_ALL,
INVALID
-
}
diff --git a/src/main/java/com/github/switcherapi/client/model/RelayType.java b/src/main/java/com/github/switcherapi/client/model/RelayType.java
new file mode 100644
index 00000000..83e72e81
--- /dev/null
+++ b/src/main/java/com/github/switcherapi/client/model/RelayType.java
@@ -0,0 +1,10 @@
+package com.github.switcherapi.client.model;
+
+/**
+ * @author Roger Floriano (petruki)
+ * @since 2025-06-13
+ */
+public enum RelayType {
+ NOTIFICATION,
+ WEBHOOK
+}
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 82aef0bc..478dbed2 100644
--- a/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java
+++ b/src/main/java/com/github/switcherapi/client/model/SwitcherBuilder.java
@@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.List;
+import java.util.Objects;
/**
* Builder class that simplifies how input are programmatically wrapped inside the Switcher.
@@ -23,6 +24,8 @@ public abstract class SwitcherBuilder implements Switcher {
protected boolean bypassMetrics;
+ protected Boolean restrictRelay;
+
protected String defaultResult;
protected List entry;
@@ -71,7 +74,18 @@ public SwitcherBuilder defaultResult(boolean defaultResult) {
this.defaultResult = String.valueOf(defaultResult);
return this;
}
-
+
+ /**
+ * Allow local snapshots to ignore or require Relay verification.
+ *
+ * @param restrictRelay true to restrict Relay verification
+ * @return {@link SwitcherBuilder}
+ */
+ public SwitcherBuilder restrictRelay(boolean restrictRelay) {
+ this.restrictRelay = restrictRelay;
+ return this;
+ }
+
/**
* Add a validation to the entry stack
*
@@ -171,6 +185,14 @@ public boolean isRemote() {
return remote;
}
+ public boolean isRelayRestricted() {
+ return restrictRelay;
+ }
+
+ public boolean isRestrictRelaySet() {
+ return Objects.nonNull(restrictRelay);
+ }
+
public String getDefaultResult() {
return defaultResult;
}
diff --git a/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java b/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java
index c1dd188a..b2bf34df 100644
--- a/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java
+++ b/src/main/java/com/github/switcherapi/client/model/SwitcherRequest.java
@@ -111,6 +111,10 @@ public SwitcherResult submit() throws SwitcherException {
@Override
public SwitcherResult executeCriteria() {
+ if (!isRestrictRelaySet()) {
+ this.restrictRelay(properties.getBoolean(ContextKey.RESTRICT_RELAY));
+ }
+
return this.switcherExecutor.executeCriteria(this);
}
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Config.java b/src/main/java/com/github/switcherapi/client/model/criteria/Config.java
index 4db582fb..67895404 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Config.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Config.java
@@ -1,6 +1,7 @@
package com.github.switcherapi.client.model.criteria;
import java.util.Arrays;
+import java.util.Objects;
/**
* @author Roger Floriano (petruki)
@@ -8,34 +9,41 @@
*/
public class Config extends SwitcherElement {
- private String key;
+ private final String key;
- private Strategy[] strategies;
+ private final Strategy[] strategies;
- private String[] components;
+ private final String[] components;
- public String getKey() {
- return key;
+ private final Relay relay;
+
+ public Config(String key, String description, boolean activated, Strategy[] strategies, String[] components,
+ Relay relay) {
+ super(description, activated);
+ this.key = key;
+ this.strategies = strategies;
+ this.components = components;
+ this.relay = relay;
}
- public Strategy[] getStrategies() {
- return strategies;
+ public boolean hasRelayEnabled() {
+ return Objects.nonNull(relay) && relay.isActivated();
}
- public void setKey(String key) {
- this.key = key;
+ public String getKey() {
+ return key;
}
- public void setStrategies(Strategy[] strategies) {
- this.strategies = strategies;
+ public Relay getRelay() {
+ return relay;
}
- public String[] getComponents() {
- return components;
+ public Strategy[] getStrategies() {
+ return strategies;
}
- public void setComponents(String[] components) {
- this.components = components;
+ public String[] getComponents() {
+ return components;
}
@Override
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Domain.java b/src/main/java/com/github/switcherapi/client/model/criteria/Domain.java
index 0fd0ff5d..a827b989 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Domain.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Domain.java
@@ -8,36 +8,35 @@
*/
public class Domain extends SwitcherElement {
- private String name;
+ private final String name;
- private long version;
+ private final long version;
- private Group[] group;
+ private final Group[] group;
- public Group[] getGroup() {
- return group;
+ public Domain(String name, String description, boolean activated, long version, Group[] group) {
+ super(description, activated);
+ this.name = name;
+ this.version = version;
+ this.group = group;
}
- public void setGroup(Group[] group) {
- this.group = group;
+ public Domain() {
+ this(null, null, false, 0L, null);
}
- public String getName() {
- return name;
+ public Group[] getGroup() {
+ return group;
}
- public void setName(String name) {
- this.name = name;
+ public String getName() {
+ return name;
}
public long getVersion() {
return version;
}
- public void setVersion(long version) {
- this.version = version;
- }
-
@Override
public String toString() {
return String.format("Domain [name = %s, description = %s, activated = %s, version = %s, group = %s]", name,
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Group.java b/src/main/java/com/github/switcherapi/client/model/criteria/Group.java
index 026491b8..6a0b608e 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Group.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Group.java
@@ -8,26 +8,24 @@
*/
public class Group extends SwitcherElement {
- private String name;
+ private final String name;
- private Config[] config;
+ private final Config[] config;
- public Config[] getConfig() {
- return config;
+ public Group(String name, String description, boolean activated, Config[] config) {
+ super(description, activated);
+ this.name = name;
+ this.config = config;
}
- public void setConfig(Config[] config) {
- this.config = config;
+ public Config[] getConfig() {
+ return config;
}
public String getName() {
return name;
}
- public void setName(String name) {
- this.name = name;
- }
-
@Override
public String toString() {
return String.format("Group [name = %s, description = %s, activated = %s, config = %s]", name, description,
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java b/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java
new file mode 100644
index 00000000..9af97bba
--- /dev/null
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java
@@ -0,0 +1,27 @@
+package com.github.switcherapi.client.model.criteria;
+
+/**
+ * @author Roger Floriano (petruki)
+ * @since 2025-06-13
+ */
+public class Relay {
+
+ private final String type;
+
+ private final boolean activated;
+
+ public Relay(String type, boolean activated) {
+ this.type = type;
+ this.activated = activated;
+ }
+
+ public boolean isActivated() {
+ return activated;
+ }
+
+ @Override
+ public String toString() {
+ return String.format("Relay [type = %s, activated = %s]", type, activated);
+ }
+
+}
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java b/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java
index b1c5e041..dc62ef5d 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java
@@ -11,11 +11,18 @@
*/
public class Strategy extends SwitcherElement {
- private String strategy;
+ private final String strategy;
- private String operation;
+ private final String operation;
- private String[] values;
+ private final String[] values;
+
+ public Strategy(String strategy, String operation, String description, boolean activated, String[] values) {
+ super(description, activated);
+ this.strategy = strategy;
+ this.operation = operation;
+ this.values = values;
+ }
public EntryOperation getEntryOperation() {
return Arrays.stream(EntryOperation.values())
@@ -39,22 +46,10 @@ public String getOperation() {
return operation;
}
- public void setOperation(String operation) {
- this.operation = operation;
- }
-
public String[] getValues() {
return values;
}
- public void setStrategy(String strategy) {
- this.strategy = strategy;
- }
-
- public void setValues(String[] values) {
- this.values = values;
- }
-
@Override
public String toString() {
return String.format("Strategy [strategy = %s, operation = %s, description = %s, activated = %s, values = %s]",
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/SwitcherElement.java b/src/main/java/com/github/switcherapi/client/model/criteria/SwitcherElement.java
index 67a6dcbe..f65a024f 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/SwitcherElement.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/SwitcherElement.java
@@ -6,9 +6,14 @@
*/
abstract class SwitcherElement {
- protected String description;
+ protected final String description;
- protected boolean activated;
+ protected final boolean activated;
+
+ protected SwitcherElement(String description, boolean activated) {
+ this.description = description;
+ this.activated = activated;
+ }
public String getDescription() {
return description;
@@ -18,12 +23,4 @@ public boolean isActivated() {
return activated;
}
- public void setDescription(String description) {
- this.description = description;
- }
-
- public void setActivated(boolean activated) {
- this.activated = activated;
- }
-
}
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 c61772ea..0ac1e60d 100644
--- a/src/main/java/com/github/switcherapi/client/remote/Constants.java
+++ b/src/main/java/com/github/switcherapi/client/remote/Constants.java
@@ -18,6 +18,7 @@ public final class Constants {
"group { name description activated " +
"config { key description activated " +
"strategies { strategy activated operation values } " +
+ "relay { type activated } " +
"components } } } }\"}";
private Constants() {}
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 dd2dae25..1e231f77 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
@@ -35,6 +35,7 @@ public class ClientLocalService implements ClientLocal {
public static final String DISABLED_DOMAIN = "Domain disabled";
public static final String DISABLED_GROUP = "Group disabled";
public static final String DISABLED_CONFIG = "Config disabled";
+ public static final String HAS_RELAY = "Config has Relay enabled";
private static final String STRATEGY_FAIL_PATTERN = "Strategy %s does not agree";
private static final String STRATEGY_FAIL_NO_INPUT_PATTERN = "Strategy %s did not receive any input";
@@ -88,6 +89,10 @@ private SwitcherResult getSwitcherResult(SwitcherRequest switcher, Group group,
return SwitcherFactory.buildResultFail(DISABLED_CONFIG, switcher);
}
+ if (config.hasRelayEnabled() && switcher.isRelayRestricted()) {
+ return SwitcherFactory.buildResultFail(HAS_RELAY, switcher);
+ }
+
if (ArrayUtils.isNotEmpty(config.getStrategies())) {
return this.processOperation(config.getStrategies(), switcher.getEntry(), switcher);
}
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 150b3778..428ab9fa 100644
--- a/src/main/java/com/github/switcherapi/client/utils/SnapshotLoader.java
+++ b/src/main/java/com/github/switcherapi/client/utils/SnapshotLoader.java
@@ -104,16 +104,13 @@ private static Domain loadSnapshotFromResources(final String snapshotLocation, f
public static void saveSnapshot(final Snapshot snapshot, final String snapshotLocation,
final String environment) throws SwitcherSnapshotWriteException {
- final Gson gson = new GsonBuilder().setPrettyPrinting().create();
+ final Gson gson = new GsonBuilder()
+ .setPrettyPrinting()
+ .registerTypeAdapter(Domain.class, new SnapshotSerializer())
+ .create();
+
+ createDirectoryPath(snapshotLocation, environment);
- try {
- Path path = Paths.get(snapshotLocation);
- if (!path.toFile().exists())
- Files.createDirectories(path);
- } catch (Exception e) {
- throw new SwitcherSnapshotWriteException(String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment), e);
- }
-
try (
final FileWriter fileWriter = new FileWriter(String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment));
final BufferedWriter bw = new BufferedWriter(fileWriter);
@@ -124,4 +121,15 @@ public static void saveSnapshot(final Snapshot snapshot, final String snapshotLo
}
}
+ private static void createDirectoryPath(String snapshotLocation, String environment) {
+ try {
+ Path path = Paths.get(snapshotLocation);
+ if (!path.toFile().exists()) {
+ Files.createDirectories(path);
+ }
+ } catch (Exception e) {
+ throw new SwitcherSnapshotWriteException(String.format(SNAPSHOT_FILE_FORMAT, snapshotLocation, environment), e);
+ }
+ }
+
}
diff --git a/src/main/java/com/github/switcherapi/client/utils/SnapshotSerializer.java b/src/main/java/com/github/switcherapi/client/utils/SnapshotSerializer.java
new file mode 100644
index 00000000..6b7289c8
--- /dev/null
+++ b/src/main/java/com/github/switcherapi/client/utils/SnapshotSerializer.java
@@ -0,0 +1,108 @@
+package com.github.switcherapi.client.utils;
+
+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.google.gson.*;
+
+import java.lang.reflect.Type;
+import java.util.Objects;
+
+class SnapshotSerializer implements JsonSerializer {
+
+ @Override
+ public JsonElement serialize(Domain domain, Type typeOfSrc, JsonSerializationContext context) {
+ JsonObject jsonObject = new JsonObject();
+
+ jsonObject.add(Field.NAME.value(), context.serialize(domain.getName()));
+ jsonObject.add(Field.DESCRIPTION.value(), context.serialize(domain.getDescription()));
+ jsonObject.add(Field.ACTIVATED.value(), context.serialize(domain.isActivated()));
+ jsonObject.add(Field.VERSION.value(), context.serialize(domain.getVersion()));
+ jsonObject.add(Field.GROUP.value(), serializeGroup(domain, context));
+
+ return jsonObject;
+ }
+
+ private JsonArray serializeGroup(Domain domain, JsonSerializationContext context) {
+ JsonArray groupArray = new JsonArray();
+
+ if (Objects.nonNull(domain.getGroup())) {
+ for (Group group : domain.getGroup()) {
+ JsonObject groupObject = new JsonObject();
+ groupObject.add(Field.NAME.value(), context.serialize(group.getName()));
+ groupObject.add(Field.DESCRIPTION.value(), context.serialize(group.getDescription()));
+ groupObject.add(Field.ACTIVATED.value(), context.serialize(group.isActivated()));
+ groupObject.add(Field.CONFIG.value(), serializeConfig(group, context));
+ groupArray.add(groupObject);
+ }
+ }
+
+ return groupArray;
+ }
+
+ private JsonArray serializeConfig(Group group, JsonSerializationContext context) {
+ JsonArray configArray = new JsonArray();
+
+ if (Objects.nonNull(group.getConfig())) {
+ for (Config config : group.getConfig()) {
+ JsonObject configObject = new JsonObject();
+ configObject.add(Field.KEY.value(), context.serialize(config.getKey()));
+ configObject.add(Field.DESCRIPTION.value(), context.serialize(config.getDescription()));
+ configObject.add(Field.ACTIVATED.value(), context.serialize(config.isActivated()));
+ configObject.add(Field.STRATEGIES.value(), serializeStrategies(config, context));
+ configObject.add(Field.RELAY.value(), context.serialize(config.getRelay()));
+ configObject.add(Field.COMPONENTS.value(), context.serialize(config.getComponents()));
+
+ configArray.add(configObject);
+ }
+ }
+
+ return configArray;
+ }
+
+ private JsonArray serializeStrategies(Config config, JsonSerializationContext context) {
+ JsonArray strategiesArray = new JsonArray();
+
+ if (Objects.nonNull(config.getStrategies())) {
+ for (Strategy strategy : config.getStrategies()) {
+ JsonObject strategyObject = new JsonObject();
+ strategyObject.add(Field.STRATEGY.value(), context.serialize(strategy.getStrategy()));
+ strategyObject.add(Field.OPERATION.value(), context.serialize(strategy.getOperation()));
+ strategyObject.add(Field.DESCRIPTION.value(), context.serialize(strategy.getDescription()));
+ strategyObject.add(Field.ACTIVATED.value(), context.serialize(strategy.isActivated()));
+ strategyObject.add(Field.VALUES.value(), context.serialize(strategy.getValues()));
+ strategiesArray.add(strategyObject);
+ }
+ }
+
+ return strategiesArray;
+ }
+
+ private enum Field {
+ NAME("name"),
+ DESCRIPTION("description"),
+ ACTIVATED("activated"),
+ VERSION("version"),
+ GROUP("group"),
+ CONFIG("config"),
+ KEY("key"),
+ COMPONENTS("components"),
+ STRATEGIES("strategies"),
+ RELAY("relay"),
+ STRATEGY("strategy"),
+ OPERATION("operation"),
+ VALUES("values");
+
+ private final String value;
+
+ Field(String value) {
+ this.value = value;
+ }
+
+ public String value() {
+ return value;
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/test/java/com/github/switcherapi/Switchers.java b/src/test/java/com/github/switcherapi/Switchers.java
index 5789b8df..9b98a10e 100644
--- a/src/test/java/com/github/switcherapi/Switchers.java
+++ b/src/test/java/com/github/switcherapi/Switchers.java
@@ -134,6 +134,12 @@ public class Switchers extends SwitcherContext {
@SwitcherKey
public static final String USECASE102 = "USECASE102";
+ @SwitcherKey
+ public static final String USECASE103 = "USECASE103";
+
+ @SwitcherKey
+ public static final String USECASE104 = "USECASE104";
+
@SwitcherKey
public static final String NOT_FOUND_KEY = "NOT_FOUND_KEY";
}
diff --git a/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java b/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java
index 1c57691c..1f20e9f7 100644
--- a/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java
+++ b/src/test/java/com/github/switcherapi/client/SwitcherLocal1Test.java
@@ -4,10 +4,7 @@
import com.github.switcherapi.client.exception.SwitcherInvalidNumericFormat;
import com.github.switcherapi.client.exception.SwitcherInvalidTimeFormat;
import com.github.switcherapi.client.exception.SwitcherKeyNotFoundException;
-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.SwitcherRequest;
+import com.github.switcherapi.client.model.*;
import com.github.switcherapi.fixture.Product;
import com.google.gson.Gson;
import org.apache.commons.lang3.StringUtils;
@@ -360,4 +357,41 @@ void localShouldTestChained_payloadValidation(String useCaseKey, String input, b
assertEquals(expected, switcher.checkPayload(input).isItOn());
}
+ static Stream relayTestArguments() {
+ return Stream.of(
+ // Relay enabled should cause local to return false
+ Arguments.of(Switchers.USECASE103, true, false),
+ // Relay enabled should cause local to return true when Switcher restrictRelay is set false
+ Arguments.of(Switchers.USECASE103, false, true),
+ // Relay disabled should cause local to return true
+ Arguments.of(Switchers.USECASE104, false, true),
+ // Relay disabled should cause local to return true regardless of Switcher restrictRelay
+ Arguments.of(Switchers.USECASE104, true, true)
+ );
+ }
+
+ @ParameterizedTest()
+ @MethodSource("relayTestArguments")
+ void localShouldTest_relayValidation(String useCaseKey, Boolean restrictRelay, boolean expected) {
+ SwitcherContext.configure(ContextBuilder.builder()
+ .restrictRelay(restrictRelay));
+
+ SwitcherContext.initializeClient();
+
+ SwitcherRequest switcher = Switchers.getSwitcher(useCaseKey);
+ assertEquals(expected, switcher.isItOn());
+ }
+
+ @Test
+ void localShouldReturnFalse_relayRestrictDefaultEnabled() {
+ SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE103);
+ assertFalse(switcher.isItOn());
+ }
+
+ @Test
+ void localShouldReturnTrue_relayRestrictProgrammaticallyDisabled() {
+ SwitcherRequest switcher = Switchers.getSwitcher(Switchers.USECASE103);
+ assertTrue(switcher.restrictRelay(false).isItOn());
+ }
+
}
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 85ce136c..6b726f17 100644
--- a/src/test/java/com/github/switcherapi/client/model/ModelTest.java
+++ b/src/test/java/com/github/switcherapi/client/model/ModelTest.java
@@ -1,14 +1,8 @@
package com.github.switcherapi.client.model;
+import com.github.switcherapi.client.model.criteria.*;
import org.junit.jupiter.api.Test;
-import com.github.switcherapi.client.model.criteria.Config;
-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;
-import com.github.switcherapi.client.model.criteria.Strategy;
-
import static org.junit.jupiter.api.Assertions.*;
class ModelTest {
@@ -25,51 +19,57 @@ void testModelEntry() {
@Test
void testCriteriaPackage() {
- final Strategy strategy = new Strategy();
- strategy.setActivated(true);
- strategy.setDescription("Description");
- strategy.setOperation("Operation");
- strategy.setStrategy("Strategy");
String[] strategyValues = new String[] { "Value" };
- strategy.setValues(strategyValues);
+ final Strategy strategy = new Strategy(
+ "Strategy",
+ "Operation",
+ "Description",
+ true,
+ strategyValues
+ );
assertSame("Description", strategy.getDescription());
assertSame("Operation", strategy.getOperation());
assertSame("Strategy", strategy.getStrategy());
assertSame(strategyValues, strategy.getValues());
-
- final Config config = new Config();
- config.setActivated(true);
- config.setKey("Key");
- config.setDescription("Description");
- String[] configComponents = new String[] { "Component" };
- config.setComponents(configComponents);
+
Strategy[] strategies = new Strategy[] { strategy };
- config.setStrategies(strategies);
+ String[] configComponents = new String[] { "Component" };
+ Relay relay = new Relay(RelayType.NOTIFICATION.name(), false);
+ final Config config = new Config(
+ "Key",
+ "Description",
+ true,
+ strategies,
+ configComponents,
+ relay
+ );
assertSame("Description", config.getDescription());
assertSame("Key", config.getKey());
assertSame(configComponents, config.getComponents());
assertSame(strategies, config.getStrategies());
-
- final Group group = new Group();
- group.setActivated(true);
- group.setDescription("Description");
- group.setName("Name");
+
Config[] configs = new Config[] { config };
- group.setConfig(configs);
+ final Group group = new Group(
+ "Name",
+ "Description",
+ true,
+ configs
+ );
assertSame("Description", group.getDescription());
assertSame("Name", group.getName());
assertSame(configs, group.getConfig());
-
- final Domain domain = new Domain();
- domain.setActivated(true);
- domain.setDescription("Description");
- domain.setName("Name");
- domain.setVersion(10000000000L);
+
Group[] groups = new Group[] { group };
- domain.setGroup(groups);
+ final Domain domain = new Domain(
+ "Name",
+ "Description",
+ true,
+ 10000000000L,
+ groups
+ );
assertSame("Description", domain.getDescription());
assertSame("Name", domain.getName());
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 e3d6468f..5dbdc486 100644
--- a/src/test/java/com/github/switcherapi/client/utils/SnapshotWatcherTest.java
+++ b/src/test/java/com/github/switcherapi/client/utils/SnapshotWatcherTest.java
@@ -4,6 +4,7 @@
import com.github.switcherapi.client.ContextBuilder;
import com.github.switcherapi.client.model.SwitcherRequest;
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.fixture.CountDownHelper;
import com.google.gson.Gson;
@@ -76,8 +77,13 @@ void changeFixture() {
final Data data = new Data();
data.setDomain(SnapshotLoader.loadSnapshot(SNAPSHOTS_LOCAL + "/snapshot_watcher.json"));
mockedSnapshot.setData(data);
-
- data.getDomain().setActivated(false);
+
+ data.setDomain(new Domain(
+ data.getDomain().getName(),
+ data.getDomain().getDescription(),
+ !data.getDomain().isActivated(),
+ data.getDomain().getVersion(),
+ data.getDomain().getGroup()));
final Gson gson = new GsonBuilder().setPrettyPrinting().create();
writeFixture(gson.toJson(mockedSnapshot));
diff --git a/src/test/java/com/github/switcherapi/client/validator/ValidatorsTest.java b/src/test/java/com/github/switcherapi/client/validator/ValidatorsTest.java
index c22431ea..e6d6f88d 100644
--- a/src/test/java/com/github/switcherapi/client/validator/ValidatorsTest.java
+++ b/src/test/java/com/github/switcherapi/client/validator/ValidatorsTest.java
@@ -14,8 +14,13 @@ class ValidatorsTest {
@Test
void shouldRegisterCustomValidator() {
assertDoesNotThrow(() -> service.registerValidator(new CustomValidator()));
- Strategy strategy = new Strategy();
- strategy.setStrategy("CUSTOM");
+ Strategy strategy = new Strategy(
+ "CUSTOM",
+ "INVALID",
+ "Custom Validator Test",
+ true,
+ new String[] { "Value1", "Value2" }
+ );
assertTrue(service.execute(strategy, null));
}
diff --git a/src/test/resources/default.json b/src/test/resources/default.json
index 1c5d5d41..4d4bcba6 100644
--- a/src/test/resources/default.json
+++ b/src/test/resources/default.json
@@ -2,346 +2,36 @@
"data": {
"domain": {
"name": "switcher-domain",
+ "description": "Description of the domain",
+ "activated": true,
"version": 1588557288037,
"group": [
{
"name": "Group 1",
+ "description": "Description of the group",
+ "activated": true,
"config": [
{
"key": "USECASE11",
- "components": [
- "switcher-client"
- ],
- "description": "Simple test - Config enabled",
- "activated": true
- },
- {
- "key": "USECASE12",
- "components": [
- "switcher-client"
- ],
- "description": "Simple test - Config disabled",
- "activated": false
- }
- ],
- "description": "Simple test",
- "activated": true
- },
- {
- "name": "Group 2",
- "config": [
- {
- "key": "USECASE21",
- "components": [
- "switcher-client"
- ],
- "description": "Simple test - Config enabled",
- "activated": true
- }
- ],
- "description": "Simple test - Group disabled",
- "activated": false
- },
- {
- "name": "Group 3",
- "config": [
- {
- "key": "USECASE31",
- "strategies": [
- {
- "strategy": "DATE_VALIDATION",
- "operation": "GREATER",
- "values": [
- "2019-12-10"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Date Validation [GREATER]",
- "activated": true
- },
- {
- "key": "USECASE32",
- "strategies": [
- {
- "strategy": "DATE_VALIDATION",
- "operation": "LOWER",
- "values": [
- "2019-12-10"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Date Validation [LOWER]",
- "activated": true
- },
- {
- "key": "USECASE33",
- "strategies": [
- {
- "strategy": "DATE_VALIDATION",
- "operation": "BETWEEN",
- "values": [
- "2019-12-10",
- "2019-12-12"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Date Validation [BETWEEN]",
- "activated": true
- }
- ],
- "description": "Date Validation",
- "activated": true
- },
- {
- "name": "Group 4",
- "config": [
- {
- "key": "USECASE41",
- "strategies": [
- {
- "strategy": "VALUE_VALIDATION",
- "operation": "EXIST",
- "values": [
- "Value1",
- "Value2",
- "Value3"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Value Validation [EXIST]",
- "activated": true
- },
- {
- "key": "USECASE42",
- "strategies": [
- {
- "strategy": "VALUE_VALIDATION",
- "operation": "NOT_EXIST",
- "values": [
- "Value1",
- "Value2",
- "Value3"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Value Validation [NOT_EXIST]",
- "activated": true
- },
- {
- "key": "USECASE43",
+ "description": "Simple test - Domain disabled",
+ "activated": true,
"strategies": [
{
"strategy": "VALUE_VALIDATION",
"operation": "EQUAL",
+ "activated": false,
"values": [
"Value1"
- ],
- "activated": true
+ ]
}
],
"components": [
"switcher-client"
- ],
- "description": "Config with Value Validation [EQUAL]",
- "activated": true
- },
- {
- "key": "USECASE44",
- "strategies": [
- {
- "strategy": "VALUE_VALIDATION",
- "operation": "NOT_EQUAL",
- "values": [
- "Value1"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Value Validation [NOT_EQUAL]",
- "activated": true
- }
- ],
- "description": "Value Validation",
- "activated": true
- },
- {
- "name": "Group 5",
- "config": [
- {
- "key": "USECASE51",
- "strategies": [
- {
- "strategy": "TIME_VALIDATION",
- "operation": "GREATER",
- "values": [
- "10:00"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Time Validation [GREATER]",
- "activated": true
- },
- {
- "key": "USECASE52",
- "strategies": [
- {
- "strategy": "TIME_VALIDATION",
- "operation": "LOWER",
- "values": [
- "10:00"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Time Validation [LOWER]",
- "activated": true
- },
- {
- "key": "USECASE53",
- "strategies": [
- {
- "strategy": "TIME_VALIDATION",
- "operation": "BETWEEN",
- "values": [
- "10:00",
- "16:00"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Time Validation [BETWEEN]",
- "activated": true
- }
- ],
- "description": "Time Validation",
- "activated": true
- },
- {
- "name": "Group 6",
- "config": [
- {
- "key": "USECASE61",
- "strategies": [
- {
- "strategy": "NETWORK_VALIDATION",
- "operation": "EXIST",
- "values": [
- "10.0.0.0/29"
- ],
- "description": "From 10.0.0.0 to 10.0.0.7",
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Network Validation [EXIST]",
- "activated": true
- },
- {
- "key": "USECASE62",
- "strategies": [
- {
- "strategy": "NETWORK_VALIDATION",
- "operation": "NOT_EXIST",
- "values": [
- "10.0.0.0/29"
- ],
- "description": "From 10.0.0.0 to 10.0.0.7",
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Network Validation [NOT_EXIST]",
- "activated": true
- },
- {
- "key": "USECASE63",
- "strategies": [
- {
- "strategy": "NETWORK_VALIDATION",
- "operation": "EXIST",
- "values": [
- "10.0.0.1",
- "10.0.0.2",
- "10.0.0.3"
- ],
- "activated": true
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Config with Network Validation [EXIST]",
- "activated": true
- }
- ],
- "description": "Network Validation",
- "activated": true
- },
- {
- "name": "Group 7",
- "config": [
- {
- "key": "USECASE71",
- "strategies": [
- {
- "strategy": "VALUE_VALIDATION",
- "operation": "EQUAL",
- "values": [
- "Value1"
- ],
- "activated": false
- }
- ],
- "components": [
- "switcher-client"
- ],
- "description": "Simple test - Config enabled",
- "activated": true
+ ]
}
- ],
- "description": "Simple test - Strategy disabled",
- "activated": true
+ ]
}
- ],
- "description": "Fixture #1",
- "activated": true
+ ]
}
}
}
\ No newline at end of file
diff --git a/src/test/resources/snapshot/fixture1.json b/src/test/resources/snapshot/fixture1.json
index 6f9a8df3..a74bdcc5 100644
--- a/src/test/resources/snapshot/fixture1.json
+++ b/src/test/resources/snapshot/fixture1.json
@@ -15,13 +15,17 @@
"key": "USECASE11",
"description": "Simple test - Config enabled",
"activated": true,
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE12",
"description": "Simple test - Config disabled",
"activated": false,
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -34,7 +38,9 @@
"key": "USECASE21",
"description": "Simple test - Config enabled",
"activated": true,
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -57,7 +63,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE32",
@@ -73,7 +81,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE33",
@@ -90,7 +100,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -109,11 +121,15 @@
"activated": true,
"operation": "EXIST",
"values": [
- "Value1", "Value2", "Value3"
+ "Value1",
+ "Value2",
+ "Value3"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE42",
@@ -125,11 +141,15 @@
"activated": true,
"operation": "NOT_EXIST",
"values": [
- "Value1", "Value2", "Value3"
+ "Value1",
+ "Value2",
+ "Value3"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE43",
@@ -145,7 +165,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE44",
@@ -161,7 +183,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -184,7 +208,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE52",
@@ -200,7 +226,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE53",
@@ -217,7 +245,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -241,7 +271,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE62",
@@ -258,7 +290,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE63",
@@ -270,11 +304,15 @@
"activated": true,
"operation": "EXIST",
"values": [
- "10.0.0.1", "10.0.0.2", "10.0.0.3"
+ "10.0.0.1",
+ "10.0.0.2",
+ "10.0.0.3"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -297,7 +335,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -316,11 +356,15 @@
"activated": true,
"operation": "EXIST",
"values": [
- "1", "2", "3"
+ "1",
+ "2",
+ "3"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE82",
@@ -332,11 +376,15 @@
"activated": true,
"operation": "NOT_EXIST",
"values": [
- "1", "2", "3"
+ "1",
+ "2",
+ "3"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE83",
@@ -352,7 +400,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE84",
@@ -368,7 +418,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE85",
@@ -384,7 +436,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE86",
@@ -400,7 +454,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE87",
@@ -412,11 +468,14 @@
"activated": true,
"operation": "BETWEEN",
"values": [
- "1", "3"
+ "1",
+ "3"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -435,11 +494,14 @@
"activated": true,
"operation": "EXIST",
"values": [
- "\\bUSER_[0-9]{1,2}\\b", "\\buser-[0-9]{1,2}\\b"
+ "\\bUSER_[0-9]{1,2}\\b",
+ "\\buser-[0-9]{1,2}\\b"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE92",
@@ -451,11 +513,14 @@
"activated": true,
"operation": "NOT_EXIST",
"values": [
- "\\bUSER_[0-9]{1,2}\\b", "\\buser-[0-9]{1,2}\\b"
+ "\\bUSER_[0-9]{1,2}\\b",
+ "\\buser-[0-9]{1,2}\\b"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE93",
@@ -467,11 +532,13 @@
"activated": true,
"operation": "EQUAL",
"values": [
- "USER_[0-9]{1,2}"
+ "USER_[0-9]{1,2}"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE94",
@@ -487,7 +554,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE95",
@@ -503,7 +572,9 @@
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
}
]
},
@@ -522,11 +593,14 @@
"activated": true,
"operation": "HAS_ONE",
"values": [
- "order.tracking.status", "order.tracking.date"
+ "order.tracking.status",
+ "order.tracking.date"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE101",
@@ -538,11 +612,13 @@
"activated": true,
"operation": "HAS_ONE",
"values": [
- "product"
+ "product"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
},
{
"key": "USECASE102",
@@ -554,17 +630,50 @@
"activated": true,
"operation": "HAS_ALL",
"values": [
- "name",
- "categories",
- "order",
- "order.qty",
- "order.tracking",
+ "name",
+ "categories",
+ "order",
+ "order.qty",
+ "order.tracking",
"order.tracking.status",
"order.tracking.comments"
]
}
],
- "components": ["switcher-client"]
+ "components": [
+ "switcher-client"
+ ]
+ }
+ ]
+ },
+ {
+ "name": "Group 11",
+ "description": "Relay group",
+ "activated": true,
+ "config": [
+ {
+ "key": "USECASE103",
+ "description": "Relay enabled",
+ "activated": true,
+ "relay": {
+ "type": "VALIDATOR",
+ "activated": true
+ },
+ "components": [
+ "switcher-client"
+ ]
+ },
+ {
+ "key": "USECASE104",
+ "description": "Relay disabled",
+ "relay": {
+ "type": "VALIDATOR",
+ "activated": false
+ },
+ "activated": true,
+ "components": [
+ "switcher-client"
+ ]
}
]
}
diff --git a/src/test/resources/test.json b/src/test/resources/test.json
index b03705d0..52cd0c8e 100644
--- a/src/test/resources/test.json
+++ b/src/test/resources/test.json
@@ -2,17 +2,14 @@
"data": {
"domain": {
"name": "switcher-domain",
- "description": "Test Snapshot",
"activated": true,
"group": [
{
"name": "Group 1",
- "description": "Simple test",
"activated": true,
"config": [
{
"key": "USECASE11",
- "description": "Simple test - Domain disabled",
"activated": true,
"components": ["switcher-client"]
}
From c4201fb3a5d075489b5ddb35ec2c49e3a5c206e1 Mon Sep 17 00:00:00 2001
From: petruki <31597636+petruki@users.noreply.github.com>
Date: Sat, 14 Jun 2025 20:05:29 -0700
Subject: [PATCH 2/2] fix: default constructor required for obj serialization
---
pom.xml | 6 ++++++
.../switcherapi/client/model/criteria/Config.java | 4 ++++
.../switcherapi/client/model/criteria/Group.java | 4 ++++
.../switcherapi/client/model/criteria/Relay.java | 8 ++++++++
.../switcherapi/client/model/criteria/Strategy.java | 4 ++++
.../client/validator/RegexValidatorV8Test.java | 13 +++++++------
6 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/pom.xml b/pom.xml
index 515b0987..2281843e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -55,6 +55,7 @@
2.47
2.47
2.47
+ 1.2.0
2.13.1
@@ -109,6 +110,11 @@
jersey-media-json-jackson
${jersey-media-json-jackson.version}
+
+ javax.activation
+ javax.activation-api
+ ${javax.activation-api.version}
+
com.google.code.gson
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Config.java b/src/main/java/com/github/switcherapi/client/model/criteria/Config.java
index 67895404..eb4ae1f9 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Config.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Config.java
@@ -26,6 +26,10 @@ public Config(String key, String description, boolean activated, Strategy[] stra
this.relay = relay;
}
+ public Config() {
+ this(null, null, false, null, null, null);
+ }
+
public boolean hasRelayEnabled() {
return Objects.nonNull(relay) && relay.isActivated();
}
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Group.java b/src/main/java/com/github/switcherapi/client/model/criteria/Group.java
index 6a0b608e..2768ad72 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Group.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Group.java
@@ -18,6 +18,10 @@ public Group(String name, String description, boolean activated, Config[] config
this.config = config;
}
+ public Group() {
+ this(null, null, false, null);
+ }
+
public Config[] getConfig() {
return config;
}
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java b/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java
index 9af97bba..0d00fcb9 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Relay.java
@@ -15,10 +15,18 @@ public Relay(String type, boolean activated) {
this.activated = activated;
}
+ public Relay() {
+ this(null, false);
+ }
+
public boolean isActivated() {
return activated;
}
+ public String getType() {
+ return type;
+ }
+
@Override
public String toString() {
return String.format("Relay [type = %s, activated = %s]", type, activated);
diff --git a/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java b/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java
index dc62ef5d..7bcdb4c3 100644
--- a/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java
+++ b/src/main/java/com/github/switcherapi/client/model/criteria/Strategy.java
@@ -24,6 +24,10 @@ public Strategy(String strategy, String operation, String description, boolean a
this.values = values;
}
+ public Strategy() {
+ this(null, null, null, false, null);
+ }
+
public EntryOperation getEntryOperation() {
return Arrays.stream(EntryOperation.values())
.filter(o -> o.toString().equals(this.operation))
diff --git a/src/test/java/com/github/switcherapi/client/validator/RegexValidatorV8Test.java b/src/test/java/com/github/switcherapi/client/validator/RegexValidatorV8Test.java
index d4ac5321..e623aa90 100644
--- a/src/test/java/com/github/switcherapi/client/validator/RegexValidatorV8Test.java
+++ b/src/test/java/com/github/switcherapi/client/validator/RegexValidatorV8Test.java
@@ -105,12 +105,13 @@ void shouldCompleteWorkerThreadsAfterTimeout() {
}
private Strategy givenStrategy(EntryOperation operation, List values) {
- Strategy strategy = new Strategy();
- strategy.setStrategy(StrategyValidator.REGEX.toString());
- strategy.setOperation(operation.toString());
- strategy.setValues(values.toArray(new String[0]));
-
- return strategy;
+ return new Strategy(
+ StrategyValidator.REGEX.toString(),
+ operation.toString(),
+ "Regex validator strategy for test",
+ Boolean.TRUE,
+ values.toArray(new String[0])
+ );
}
private void assertWorkerNotExists() {