From 14ba8a36a94dc88de1ffacbb251c0c163fa416f7 Mon Sep 17 00:00:00 2001 From: John Kodumal Date: Thu, 29 Jan 2015 17:49:14 -0800 Subject: [PATCH 1/2] Support for user rules --- .../com/launchdarkly/client/FeatureRep.java | 6 +++++ .../com/launchdarkly/client/Variation.java | 22 ++++++++++++++++++ .../launchdarkly/client/FeatureRepTest.java | 23 +++++++++++++++++++ 3 files changed, 51 insertions(+) diff --git a/src/main/java/com/launchdarkly/client/FeatureRep.java b/src/main/java/com/launchdarkly/client/FeatureRep.java index b444c0eed..bb803d18f 100644 --- a/src/main/java/com/launchdarkly/client/FeatureRep.java +++ b/src/main/java/com/launchdarkly/client/FeatureRep.java @@ -63,6 +63,12 @@ public E evaluate(LDUser user) { return null; } else { + for (Variation variation: variations) { + if (variation.matchUser(user)) { + return variation.value; + } + } + for (Variation variation : variations) { if (variation.matchTarget(user)) { return variation.value; diff --git a/src/main/java/com/launchdarkly/client/Variation.java b/src/main/java/com/launchdarkly/client/Variation.java index 556d515b5..c336c29b2 100644 --- a/src/main/java/com/launchdarkly/client/Variation.java +++ b/src/main/java/com/launchdarkly/client/Variation.java @@ -12,6 +12,7 @@ class Variation { E value; int weight; + TargetRule userTarget; List targets; private final Logger logger = LoggerFactory.getLogger(Variation.class); @@ -22,11 +23,25 @@ public Variation() { Variation(Builder b) { this.value = b.value; this.weight = b.weight; + this.userTarget = b.userTarget; this.targets = new ArrayList(b.targets); } + public boolean matchUser(LDUser user) { + // If a userTarget rule is present, apply it + if (userTarget != null && userTarget.matchTarget(user)) { + return true; + } + return false; + } + public boolean matchTarget(LDUser user) { for (TargetRule target: targets) { + // If a userTarget rule is present, nested "key" rules + // are deprecated and should be ignored + if (userTarget != null && target.attribute == "key") { + continue; + } if (target.matchTarget(user)) { return true; } @@ -37,14 +52,21 @@ public boolean matchTarget(LDUser user) { static class Builder { E value; int weight; + TargetRule userTarget; List targets; Builder(E value, int weight) { this.value = value; this.weight = weight; + this.userTarget = new TargetRule("key", "in", new ArrayList()); targets = new ArrayList(); } + Builder userTarget(TargetRule rule) { + this.userTarget = rule; + return this; + } + Builder target(TargetRule rule) { targets.add(rule); return this; diff --git a/src/test/java/com/launchdarkly/client/FeatureRepTest.java b/src/test/java/com/launchdarkly/client/FeatureRepTest.java index c19665263..c0dfa847c 100644 --- a/src/test/java/com/launchdarkly/client/FeatureRepTest.java +++ b/src/test/java/com/launchdarkly/client/FeatureRepTest.java @@ -40,6 +40,29 @@ public class FeatureRepTest { .variation(falseVariation) .build(); + private Variation userRuleVariation = new Variation.Builder(false, 20) + .userTarget(targetUserOn) + .build(); + + private final FeatureRep userRuleFlag = new FeatureRep.Builder("User rule flag", "user.rule.flag") + .on(true) + .salt("feefifofum") + .variation(trueVariation) + .variation(userRuleVariation) + .build(); + + @Test + public void testUserRuleFlagForTargetUserOff() { + + // The trueVariation tries to enable this rule, but the userVariation (with false value) has a userRule + // that's able to override this. This doesn't represent a real LD response-- we'd never have feature reps + // that sometimes contain user rules and sometimes contain embedded 'key' rules + LDUser user = new LDUser.Builder("targetOn@test.com").build(); + Boolean b = userRuleFlag.evaluate(user); + + assertEquals(false, b); + } + @Test public void testFlagForTargetedUserOff() { LDUser user = new LDUser.Builder("targetOff@test.com").build(); From 369cbe572006f57d9908f4b9b2805097e3e496da Mon Sep 17 00:00:00 2001 From: John Kodumal Date: Fri, 30 Jan 2015 14:50:54 -0800 Subject: [PATCH 2/2] Add matching support for new built-in attributes. --- .../com/launchdarkly/client/Variation.java | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/main/java/com/launchdarkly/client/Variation.java b/src/main/java/com/launchdarkly/client/Variation.java index c336c29b2..0d53e4f9c 100644 --- a/src/main/java/com/launchdarkly/client/Variation.java +++ b/src/main/java/com/launchdarkly/client/Variation.java @@ -112,6 +112,31 @@ else if (attribute.equals("country")) { uValue = user.getCountry().getAlpha2(); } } + else if (attribute.equals("email")) { + if (user.getEmail() != null) { + uValue = user.getEmail(); + } + } + else if (attribute.equals("firstName")) { + if (user.getFirstName() != null ) { + uValue = user.getFirstName(); + } + } + else if (attribute.equals("lastName")) { + if (user.getLastName() != null) { + uValue = user.getLastName(); + } + } + else if (attribute.equals("avatar")) { + if (user.getAvatar() != null) { + uValue = user.getAvatar(); + } + } + else if (attribute.equals("name")) { + if (user.getName() != null) { + uValue = user.getName(); + } + } else { // Custom attribute JsonElement custom = user.getCustom(attribute);