From e752359ec5c774cf644fa6af5401c39eae516a62 Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Wed, 8 Nov 2017 08:02:02 +1100 Subject: [PATCH 01/11] New Roles --- .../io/featureflow/client/FeatureflowClientImplTestInt.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java index 28976eb..9755aa2 100644 --- a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java +++ b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java @@ -29,7 +29,7 @@ public class FeatureflowClientImplTestInt { @Test public void testEvaluateWithUserProvider() throws Exception { - String apiKey = "srv-env-"; + String apiKey = "srv-env-d052272ca9e749b18c384837e34518b2"; FeatureflowConfig config = FeatureflowConfig.builder() .withBaseUri(TestConfiguration.LOCAL_BASE_URL) @@ -40,7 +40,7 @@ public void testEvaluateWithUserProvider() throws Exception { FeatureflowUserProvider userProvider = () -> user; featureflowClient = FeatureflowClient.builder(apiKey) - .withConfig(config) + //.withConfig(config) .withUserProvider(userProvider) .withFeatures(Arrays.asList( new Feature("example-feature"), From 8e53ff18ffa8b757d91201e4921b140f0ee22797 Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Feb 2018 21:54:08 +1100 Subject: [PATCH 02/11] Remove unnecessary config --- src/main/java/io/featureflow/client/FeatureflowClient.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/io/featureflow/client/FeatureflowClient.java b/src/main/java/io/featureflow/client/FeatureflowClient.java index d074973..04ad57b 100644 --- a/src/main/java/io/featureflow/client/FeatureflowClient.java +++ b/src/main/java/io/featureflow/client/FeatureflowClient.java @@ -30,7 +30,6 @@ */ public class FeatureflowClient implements Closeable{ private static final Logger logger = LoggerFactory.getLogger(FeatureflowClient.class); - private final FeatureflowConfig config; private final FeatureControlStreamClient featureControlStreamClient; // manages pubsub events to update a feature control private final FeatureControlCache featureControlCache; //holds the featureControls private final RestClient restClient; //manages retrieving features and pushing updates @@ -46,8 +45,7 @@ public class FeatureflowClient implements Closeable{ FeatureflowUserProvider userProvider, FeatureflowUserLookupProvider userLookupProvider, boolean offline ) { - //set config, use a builder - this.config = config; + this.userProvider = userProvider; this.userLookupProvider = userLookupProvider; this.offline = offline; From 64f6fb9ba5136eff48767dd4bc8e8c96201de475 Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Mar 2018 21:13:25 +1100 Subject: [PATCH 03/11] Minor SDK Optimisations --- .../featureflow/client/FeatureflowClient.java | 5 ++-- .../featureflow/client/model/Condition.java | 26 +++++++++---------- .../io/featureflow/client/model/Operator.java | 18 ------------- .../client/FeatureflowClientImplTestInt.java | 8 ++++-- 4 files changed, 22 insertions(+), 35 deletions(-) diff --git a/src/main/java/io/featureflow/client/FeatureflowClient.java b/src/main/java/io/featureflow/client/FeatureflowClient.java index 04ad57b..38edc0b 100644 --- a/src/main/java/io/featureflow/client/FeatureflowClient.java +++ b/src/main/java/io/featureflow/client/FeatureflowClient.java @@ -119,13 +119,14 @@ public Map evaluateAll(FeatureflowUser user){ private String eval(String featureKey, FeatureflowUser user) { - String failoverVariant = (featuresMap.get(featureKey)!=null&&featuresMap.get(featureKey).failoverVariant!=null)?featuresMap.get(featureKey).failoverVariant: Variant.off; + boolean featureRegistered = featuresMap.containsKey(featureKey); + String failoverVariant = (featuresMap.containsKey(featureKey)&&featuresMap.get(featureKey).failoverVariant!=null)?featuresMap.get(featureKey).failoverVariant: Variant.off; FeatureControl control = featureControlCache.get(featureKey); if(!offline&&!featureControlStreamClient.initialized()){ logger.warn("FeatureFlow is not initialized yet."); } if(control == null){ - logger.warn("Control does not exist, returning failover variant of " + failoverVariant); + logger.warn("Control {} does not exist, control registered: {}. Returning failover variant of {}", featureKey, featureRegistered, failoverVariant); return failoverVariant; } diff --git a/src/main/java/io/featureflow/client/model/Condition.java b/src/main/java/io/featureflow/client/model/Condition.java index 9e2bb5c..f3a6aec 100644 --- a/src/main/java/io/featureflow/client/model/Condition.java +++ b/src/main/java/io/featureflow/client/model/Condition.java @@ -18,7 +18,9 @@ public class Condition { public Operator operator; // = < > like in out public List values = new ArrayList<>(); //some value 1,2,dave,timestamp,2016-01-11-10:10:10:0000UTC - public Condition() {} + public Condition() { + } + public Condition(String target, Operator operator, List values) { this.target = target; this.operator = operator; @@ -27,23 +29,21 @@ public Condition(String target, Operator operator, List values) { public boolean matches(FeatureflowUser user) { //see if context contains target - if(user == null || (user.getAttributes()==null && user.getSessionAttributes() ==null))return false; + if (user == null || (user.getAttributes() == null && user.getSessionAttributes() == null)) return false; Map combined = new HashMap<>(); combined.putAll(user.getAttributes()); combined.putAll(user.getSessionAttributes()); - for(String attributeKey : combined.keySet()){ - if(attributeKey.equals(target)){ - //compare the value using the comparator - JsonElement contextValue = user.getAttributes().get(attributeKey); - if(contextValue.isJsonArray()){ //if the context value is an array of values - JsonArray ar = contextValue.getAsJsonArray(); - for (JsonElement jsonElement : ar) {//return true if any of the list of context values for the key matches - if (operator.evaluate(jsonElement.getAsJsonPrimitive(), values))return true; - } - return false; //else return false + if (combined.containsKey(target)) { + //compare the value using the comparator + JsonElement contextValue = combined.get(target); + if (contextValue.isJsonArray()) { //if the context value is an array of values + JsonArray ar = contextValue.getAsJsonArray(); + for (JsonElement jsonElement : ar) {//return true if any of the list of context values for the key matches + if (operator.evaluate(jsonElement.getAsJsonPrimitive(), values)) return true; } - return operator.evaluate(user.getAttributes().get(attributeKey).getAsJsonPrimitive(), values); //if its a single value then just return the eval + return false; //else return false } + return operator.evaluate(combined.get(target).getAsJsonPrimitive(), values); //if its a single value then just return the eval } return false; } diff --git a/src/main/java/io/featureflow/client/model/Operator.java b/src/main/java/io/featureflow/client/model/Operator.java index aec95cb..a40822f 100644 --- a/src/main/java/io/featureflow/client/model/Operator.java +++ b/src/main/java/io/featureflow/client/model/Operator.java @@ -27,12 +27,6 @@ public boolean evaluate(JsonPrimitive contextValue, List targetVa return false; } }, - testRuleEquals{ - @Override - public boolean evaluate(JsonPrimitive contextValue, List targetValues){ - return contextValue.isNumber() && targetValues.get(0).isNumber() && contextValue.getAsDouble() > targetValues.get(0).getAsDouble(); - } - }, lessThan{ @Override public boolean evaluate(JsonPrimitive contextValue, List targetValues){ @@ -117,18 +111,6 @@ public boolean evaluate(JsonPrimitive contextValue, List targetVa return true; } }, - /* IN{ - @Override - public boolean evaluate(JsonPrimitive contextValue, JsonPrimitive targetValue){ - return contextValue.equals(targetValue); - } - }, //must match one of a list - NOT_IN{ - @Override - public boolean evaluate(JsonPrimitive contextValue, JsonPrimitive targetValue){ - return contextValue.equals(targetValue); - } - }, *///must not match any of a list contains{ @Override public boolean evaluate(JsonPrimitive contextValue, List targetValues){ diff --git a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java index 9755aa2..1563603 100644 --- a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java +++ b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java @@ -38,7 +38,7 @@ public void testEvaluateWithUserProvider() throws Exception { .build(); FeatureflowUserProvider userProvider = () -> user; - + featureflowClient = FeatureflowClient.builder(apiKey) //.withConfig(config) .withUserProvider(userProvider) @@ -46,7 +46,8 @@ public void testEvaluateWithUserProvider() throws Exception { new Feature("example-feature"), new Feature("facebook-login"), new Feature("standard-login"), - new Feature("summary-dashboard") + new Feature("summary-dashboard"), + new Feature("unknown-feature", "green") )) .withUpdateCallback(control -> System.out.println("Received a control update event: " + control.getKey())) @@ -55,6 +56,8 @@ public void testEvaluateWithUserProvider() throws Exception { lock.countDown(); }).build(); String evaluatedVariant = featureflowClient.evaluate("example-feature").value(); + String unknown = featureflowClient.evaluate("unknown-feature").value(); + String nonexistant = featureflowClient.evaluate("nonexistent-feature").value(); System.out.println(featureflowClient.evaluate(FeatureKeys.billing.name()).value()); System.out.println(evaluatedVariant); lock.await(500000, TimeUnit.MILLISECONDS); @@ -67,6 +70,7 @@ public void testEvaluate() throws Exception { String apiKey = "srv-env-"; + FeatureflowConfig config = FeatureflowConfig.builder() .withBaseUri(TestConfiguration.LOCAL_BASE_URL) .withStreamBaseUri(TestConfiguration.LOCAL_BASE_STREAM_URL) From e95c045b33f9f38c54ba85a351f83761a7932a0d Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Thu, 8 Mar 2018 22:31:46 +1100 Subject: [PATCH 04/11] 1.0.2-SNAPSHOT --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 7a5c4e4..bf331bf 100644 --- a/pom.xml +++ b/pom.xml @@ -2,7 +2,7 @@ 4.0.0 io.featureflow featureflow-java-sdk - 1.0.1 + 1.0.2-SNAPSHOT jar Featureflow Java SDK From 7189c565915bfedb16362a14afc8bcee590e9a84 Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Wed, 8 Nov 2017 08:02:02 +1100 Subject: [PATCH 05/11] New Roles --- .../io/featureflow/client/FeatureflowClientImplTestInt.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java index 28976eb..9755aa2 100644 --- a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java +++ b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java @@ -29,7 +29,7 @@ public class FeatureflowClientImplTestInt { @Test public void testEvaluateWithUserProvider() throws Exception { - String apiKey = "srv-env-"; + String apiKey = "srv-env-d052272ca9e749b18c384837e34518b2"; FeatureflowConfig config = FeatureflowConfig.builder() .withBaseUri(TestConfiguration.LOCAL_BASE_URL) @@ -40,7 +40,7 @@ public void testEvaluateWithUserProvider() throws Exception { FeatureflowUserProvider userProvider = () -> user; featureflowClient = FeatureflowClient.builder(apiKey) - .withConfig(config) + //.withConfig(config) .withUserProvider(userProvider) .withFeatures(Arrays.asList( new Feature("example-feature"), From b379e5d6b7f3ece303a8030b5456de59da5eab79 Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Feb 2018 21:54:08 +1100 Subject: [PATCH 06/11] Remove unnecessary config --- src/main/java/io/featureflow/client/FeatureflowClient.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/io/featureflow/client/FeatureflowClient.java b/src/main/java/io/featureflow/client/FeatureflowClient.java index d074973..04ad57b 100644 --- a/src/main/java/io/featureflow/client/FeatureflowClient.java +++ b/src/main/java/io/featureflow/client/FeatureflowClient.java @@ -30,7 +30,6 @@ */ public class FeatureflowClient implements Closeable{ private static final Logger logger = LoggerFactory.getLogger(FeatureflowClient.class); - private final FeatureflowConfig config; private final FeatureControlStreamClient featureControlStreamClient; // manages pubsub events to update a feature control private final FeatureControlCache featureControlCache; //holds the featureControls private final RestClient restClient; //manages retrieving features and pushing updates @@ -46,8 +45,7 @@ public class FeatureflowClient implements Closeable{ FeatureflowUserProvider userProvider, FeatureflowUserLookupProvider userLookupProvider, boolean offline ) { - //set config, use a builder - this.config = config; + this.userProvider = userProvider; this.userLookupProvider = userLookupProvider; this.offline = offline; From a92fdd1801b33b1156496414009817759b7240d1 Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Mar 2018 21:13:25 +1100 Subject: [PATCH 07/11] Minor SDK Optimisations --- .../featureflow/client/FeatureflowClient.java | 5 +++-- .../io/featureflow/client/model/Condition.java | 7 +++++-- .../io/featureflow/client/model/Operator.java | 18 ------------------ .../client/FeatureflowClientImplTestInt.java | 8 ++++++-- 4 files changed, 14 insertions(+), 24 deletions(-) diff --git a/src/main/java/io/featureflow/client/FeatureflowClient.java b/src/main/java/io/featureflow/client/FeatureflowClient.java index 04ad57b..38edc0b 100644 --- a/src/main/java/io/featureflow/client/FeatureflowClient.java +++ b/src/main/java/io/featureflow/client/FeatureflowClient.java @@ -119,13 +119,14 @@ public Map evaluateAll(FeatureflowUser user){ private String eval(String featureKey, FeatureflowUser user) { - String failoverVariant = (featuresMap.get(featureKey)!=null&&featuresMap.get(featureKey).failoverVariant!=null)?featuresMap.get(featureKey).failoverVariant: Variant.off; + boolean featureRegistered = featuresMap.containsKey(featureKey); + String failoverVariant = (featuresMap.containsKey(featureKey)&&featuresMap.get(featureKey).failoverVariant!=null)?featuresMap.get(featureKey).failoverVariant: Variant.off; FeatureControl control = featureControlCache.get(featureKey); if(!offline&&!featureControlStreamClient.initialized()){ logger.warn("FeatureFlow is not initialized yet."); } if(control == null){ - logger.warn("Control does not exist, returning failover variant of " + failoverVariant); + logger.warn("Control {} does not exist, control registered: {}. Returning failover variant of {}", featureKey, featureRegistered, failoverVariant); return failoverVariant; } diff --git a/src/main/java/io/featureflow/client/model/Condition.java b/src/main/java/io/featureflow/client/model/Condition.java index 8ebc80a..1609171 100644 --- a/src/main/java/io/featureflow/client/model/Condition.java +++ b/src/main/java/io/featureflow/client/model/Condition.java @@ -18,7 +18,9 @@ public class Condition { public Operator operator; // = < > like in out public List values = new ArrayList<>(); //some value 1,2,dave,timestamp,2016-01-11-10:10:10:0000UTC - public Condition() {} + public Condition() { + } + public Condition(String target, Operator operator, List values) { this.target = target; this.operator = operator; @@ -27,7 +29,7 @@ public Condition(String target, Operator operator, List values) { public boolean matches(FeatureflowUser user) { //see if context contains target - if(user == null || (user.getAttributes()==null && user.getSessionAttributes() ==null))return false; + if (user == null || (user.getAttributes() == null && user.getSessionAttributes() == null)) return false; Map combined = new HashMap<>(); combined.putAll(user.getAttributes()); combined.putAll(user.getSessionAttributes()); @@ -45,6 +47,7 @@ public boolean matches(FeatureflowUser user) { } return operator.evaluate(contextValue.getAsJsonPrimitive(), values); //if its a single value then just return the eval } + return operator.evaluate(combined.get(target).getAsJsonPrimitive(), values); //if its a single value then just return the eval } return false; diff --git a/src/main/java/io/featureflow/client/model/Operator.java b/src/main/java/io/featureflow/client/model/Operator.java index aec95cb..a40822f 100644 --- a/src/main/java/io/featureflow/client/model/Operator.java +++ b/src/main/java/io/featureflow/client/model/Operator.java @@ -27,12 +27,6 @@ public boolean evaluate(JsonPrimitive contextValue, List targetVa return false; } }, - testRuleEquals{ - @Override - public boolean evaluate(JsonPrimitive contextValue, List targetValues){ - return contextValue.isNumber() && targetValues.get(0).isNumber() && contextValue.getAsDouble() > targetValues.get(0).getAsDouble(); - } - }, lessThan{ @Override public boolean evaluate(JsonPrimitive contextValue, List targetValues){ @@ -117,18 +111,6 @@ public boolean evaluate(JsonPrimitive contextValue, List targetVa return true; } }, - /* IN{ - @Override - public boolean evaluate(JsonPrimitive contextValue, JsonPrimitive targetValue){ - return contextValue.equals(targetValue); - } - }, //must match one of a list - NOT_IN{ - @Override - public boolean evaluate(JsonPrimitive contextValue, JsonPrimitive targetValue){ - return contextValue.equals(targetValue); - } - }, *///must not match any of a list contains{ @Override public boolean evaluate(JsonPrimitive contextValue, List targetValues){ diff --git a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java index 9755aa2..1563603 100644 --- a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java +++ b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java @@ -38,7 +38,7 @@ public void testEvaluateWithUserProvider() throws Exception { .build(); FeatureflowUserProvider userProvider = () -> user; - + featureflowClient = FeatureflowClient.builder(apiKey) //.withConfig(config) .withUserProvider(userProvider) @@ -46,7 +46,8 @@ public void testEvaluateWithUserProvider() throws Exception { new Feature("example-feature"), new Feature("facebook-login"), new Feature("standard-login"), - new Feature("summary-dashboard") + new Feature("summary-dashboard"), + new Feature("unknown-feature", "green") )) .withUpdateCallback(control -> System.out.println("Received a control update event: " + control.getKey())) @@ -55,6 +56,8 @@ public void testEvaluateWithUserProvider() throws Exception { lock.countDown(); }).build(); String evaluatedVariant = featureflowClient.evaluate("example-feature").value(); + String unknown = featureflowClient.evaluate("unknown-feature").value(); + String nonexistant = featureflowClient.evaluate("nonexistent-feature").value(); System.out.println(featureflowClient.evaluate(FeatureKeys.billing.name()).value()); System.out.println(evaluatedVariant); lock.await(500000, TimeUnit.MILLISECONDS); @@ -67,6 +70,7 @@ public void testEvaluate() throws Exception { String apiKey = "srv-env-"; + FeatureflowConfig config = FeatureflowConfig.builder() .withBaseUri(TestConfiguration.LOCAL_BASE_URL) .withStreamBaseUri(TestConfiguration.LOCAL_BASE_STREAM_URL) From 8ced05442a77c493d840021a4410e04f04135c9b Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Feb 2018 21:54:08 +1100 Subject: [PATCH 08/11] Remove unnecessary config --- src/main/java/io/featureflow/client/FeatureflowClient.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/main/java/io/featureflow/client/FeatureflowClient.java b/src/main/java/io/featureflow/client/FeatureflowClient.java index 653c9fd..6c606ff 100644 --- a/src/main/java/io/featureflow/client/FeatureflowClient.java +++ b/src/main/java/io/featureflow/client/FeatureflowClient.java @@ -30,7 +30,6 @@ */ public class FeatureflowClient implements Closeable{ private static final Logger logger = LoggerFactory.getLogger(FeatureflowClient.class); - private final FeatureflowConfig config; private final FeatureControlStreamClient featureControlStreamClient; // manages pubsub events to update a feature control private final FeatureControlCache featureControlCache; //holds the featureControls private final RestClient restClient; //manages retrieving features and pushing updates @@ -52,8 +51,7 @@ public class FeatureflowClient implements Closeable{ FeatureflowUserProvider userProvider, FeatureflowUserLookupProvider userLookupProvider, boolean offline ) { - //set config, use a builder - this.config = config; + this.userProvider = userProvider; this.userLookupProvider = userLookupProvider; this.offline = offline; From 2157108324fd2a4ac4d61ffcdf47343c2a8ab5fd Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Mar 2018 21:13:25 +1100 Subject: [PATCH 09/11] Minor SDK Optimisations --- .../featureflow/client/FeatureflowClient.java | 5 +++-- .../io/featureflow/client/model/Operator.java | 18 ------------------ 2 files changed, 3 insertions(+), 20 deletions(-) diff --git a/src/main/java/io/featureflow/client/FeatureflowClient.java b/src/main/java/io/featureflow/client/FeatureflowClient.java index 6c606ff..4f42f2a 100644 --- a/src/main/java/io/featureflow/client/FeatureflowClient.java +++ b/src/main/java/io/featureflow/client/FeatureflowClient.java @@ -125,13 +125,14 @@ public Map evaluateAll(FeatureflowUser user){ private String eval(String featureKey, FeatureflowUser user) { - String failoverVariant = (featuresMap.get(featureKey)!=null&&featuresMap.get(featureKey).failoverVariant!=null)?featuresMap.get(featureKey).failoverVariant: Variant.off; + boolean featureRegistered = featuresMap.containsKey(featureKey); + String failoverVariant = (featuresMap.containsKey(featureKey)&&featuresMap.get(featureKey).failoverVariant!=null)?featuresMap.get(featureKey).failoverVariant: Variant.off; FeatureControl control = featureControlCache.get(featureKey); if(!offline&&!featureControlStreamClient.initialized()){ logger.warn("FeatureFlow is not initialized yet."); } if(control == null){ - logger.warn("Control does not exist, returning failover variant of " + failoverVariant); + logger.warn("Control {} does not exist, control registered: {}. Returning failover variant of {}", featureKey, featureRegistered, failoverVariant); return failoverVariant; } diff --git a/src/main/java/io/featureflow/client/model/Operator.java b/src/main/java/io/featureflow/client/model/Operator.java index aec95cb..a40822f 100644 --- a/src/main/java/io/featureflow/client/model/Operator.java +++ b/src/main/java/io/featureflow/client/model/Operator.java @@ -27,12 +27,6 @@ public boolean evaluate(JsonPrimitive contextValue, List targetVa return false; } }, - testRuleEquals{ - @Override - public boolean evaluate(JsonPrimitive contextValue, List targetValues){ - return contextValue.isNumber() && targetValues.get(0).isNumber() && contextValue.getAsDouble() > targetValues.get(0).getAsDouble(); - } - }, lessThan{ @Override public boolean evaluate(JsonPrimitive contextValue, List targetValues){ @@ -117,18 +111,6 @@ public boolean evaluate(JsonPrimitive contextValue, List targetVa return true; } }, - /* IN{ - @Override - public boolean evaluate(JsonPrimitive contextValue, JsonPrimitive targetValue){ - return contextValue.equals(targetValue); - } - }, //must match one of a list - NOT_IN{ - @Override - public boolean evaluate(JsonPrimitive contextValue, JsonPrimitive targetValue){ - return contextValue.equals(targetValue); - } - }, *///must not match any of a list contains{ @Override public boolean evaluate(JsonPrimitive contextValue, List targetValues){ From 352a6d05fc56f948bb40241960b4a0a10c59087c Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 6 Mar 2018 21:13:25 +1100 Subject: [PATCH 10/11] Minor SDK Optimisations --- src/main/java/io/featureflow/client/model/Condition.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/java/io/featureflow/client/model/Condition.java b/src/main/java/io/featureflow/client/model/Condition.java index 8ebc80a..1609171 100644 --- a/src/main/java/io/featureflow/client/model/Condition.java +++ b/src/main/java/io/featureflow/client/model/Condition.java @@ -18,7 +18,9 @@ public class Condition { public Operator operator; // = < > like in out public List values = new ArrayList<>(); //some value 1,2,dave,timestamp,2016-01-11-10:10:10:0000UTC - public Condition() {} + public Condition() { + } + public Condition(String target, Operator operator, List values) { this.target = target; this.operator = operator; @@ -27,7 +29,7 @@ public Condition(String target, Operator operator, List values) { public boolean matches(FeatureflowUser user) { //see if context contains target - if(user == null || (user.getAttributes()==null && user.getSessionAttributes() ==null))return false; + if (user == null || (user.getAttributes() == null && user.getSessionAttributes() == null)) return false; Map combined = new HashMap<>(); combined.putAll(user.getAttributes()); combined.putAll(user.getSessionAttributes()); @@ -45,6 +47,7 @@ public boolean matches(FeatureflowUser user) { } return operator.evaluate(contextValue.getAsJsonPrimitive(), values); //if its a single value then just return the eval } + return operator.evaluate(combined.get(target).getAsJsonPrimitive(), values); //if its a single value then just return the eval } return false; From b1a2bf0a663b7481b4d44646190a0927469bad1e Mon Sep 17 00:00:00 2001 From: Oliver Oldfield-Hodge Date: Tue, 12 Mar 2019 00:08:52 +1100 Subject: [PATCH 11/11] Remove Int Test --- .../client/FeatureflowClientImplTestInt.java | 101 ------------------ 1 file changed, 101 deletions(-) delete mode 100644 src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java diff --git a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java b/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java deleted file mode 100644 index 1563603..0000000 --- a/src/test/java/io/featureflow/client/FeatureflowClientImplTestInt.java +++ /dev/null @@ -1,101 +0,0 @@ -package io.featureflow.client; - -import io.featureflow.client.model.Feature; -import org.joda.time.DateTime; -import org.junit.Test; - -import java.util.Arrays; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertTrue; - -/** - * Created by oliver on 26/05/2016. - */ -public class FeatureflowClientImplTestInt { - - FeatureflowClient featureflowClient; - private CountDownLatch lock = new CountDownLatch(100); - - private FeatureflowUser user = new FeatureflowUser("user1") - .withAttribute("tier", "silver") - .withAttribute("age", 32) - .withAttribute("signup_date", new DateTime(2017, 1, 1, 12, 0, 0, 0)) - .withAttribute("name", "Oliver Oldfield-Hodge") - .withAttribute("email", "oliver@featureflow.io") - .withStringAttributes("user_role", Arrays.asList("pvt_tester", "administrator")); - - @Test - public void testEvaluateWithUserProvider() throws Exception { - - String apiKey = "srv-env-d052272ca9e749b18c384837e34518b2"; - - FeatureflowConfig config = FeatureflowConfig.builder() - .withBaseUri(TestConfiguration.LOCAL_BASE_URL) - .withStreamBaseUri(TestConfiguration.LOCAL_BASE_STREAM_URL) - .withWaitForStartup(5000l) - .build(); - - FeatureflowUserProvider userProvider = () -> user; - - featureflowClient = FeatureflowClient.builder(apiKey) - //.withConfig(config) - .withUserProvider(userProvider) - .withFeatures(Arrays.asList( - new Feature("example-feature"), - new Feature("facebook-login"), - new Feature("standard-login"), - new Feature("summary-dashboard"), - new Feature("unknown-feature", "green") - - )) - .withUpdateCallback(control -> System.out.println("Received a control update event: " + control.getKey())) - .withUpdateCallback(control -> { - System.out.println("Feature updated: " + control.getKey() + " - variant: " + control.evaluate(userProvider.getUser()) + "\n"); - lock.countDown(); - }).build(); - String evaluatedVariant = featureflowClient.evaluate("example-feature").value(); - String unknown = featureflowClient.evaluate("unknown-feature").value(); - String nonexistant = featureflowClient.evaluate("nonexistent-feature").value(); - System.out.println(featureflowClient.evaluate(FeatureKeys.billing.name()).value()); - System.out.println(evaluatedVariant); - lock.await(500000, TimeUnit.MILLISECONDS); - - System.out.println(featureflowClient.evaluate("alpha")); - } - - @Test - public void testEvaluate() throws Exception { - - String apiKey = "srv-env-"; - - - FeatureflowConfig config = FeatureflowConfig.builder() - .withBaseUri(TestConfiguration.LOCAL_BASE_URL) - .withStreamBaseUri(TestConfiguration.LOCAL_BASE_STREAM_URL) - .withWaitForStartup(5000l) - .build(); - - featureflowClient = FeatureflowClient.builder(apiKey) - .withConfig(config) - .withFeatures(Arrays.asList( - new Feature("example-feature"), - new Feature("facebook-login"), - new Feature("standard-login"), - new Feature("summary-dashboard") - - )) - .withUpdateCallback(control -> System.out.println("Received a control update event: " + control.getKey())) - .withUpdateCallback(control -> { - System.out.println("Feature updated: " + control.getKey() + " - variant: " + control.evaluate(user) + "\n"); - lock.countDown(); - }).build(); - String evaluatedVariant = featureflowClient.evaluate("example-feature", user).value(); - System.out.println(featureflowClient.evaluate(FeatureKeys.billing.name()).value()); - System.out.println(evaluatedVariant); - lock.await(500000, TimeUnit.MILLISECONDS); - - System.out.println(featureflowClient.evaluate("alpha", user)); - } -} \ No newline at end of file