diff --git a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/Operator.java b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/Operator.java index 13352c698..88d2e42b1 100644 --- a/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/Operator.java +++ b/providers/flagd/src/main/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/Operator.java @@ -1,11 +1,14 @@ package dev.openfeature.contrib.providers.flagd.resolver.process.targeting; +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; + import dev.openfeature.sdk.EvaluationContext; import io.github.jamsesso.jsonlogic.JsonLogic; import io.github.jamsesso.jsonlogic.JsonLogicException; import lombok.Getter; -import java.util.Map; /** * Targeting operator wraps JsonLogic handlers and expose a simple API for external layers. @@ -13,7 +16,8 @@ */ public class Operator { - static final String FLAG_KEY = "$flagKey"; + static final String FLAGD_PROPS_KEY = "$flagd"; + static final String FLAG_KEY = "flagKey"; static final String TARGET_KEY = "targetingKey"; private final JsonLogic jsonLogicHandler; @@ -34,8 +38,10 @@ public Operator() { */ public Object apply(final String flagKey, final String targetingRule, final EvaluationContext ctx) throws TargetingRuleException { + final Map flagdProperties = new HashMap<>(); + flagdProperties.put(FLAG_KEY, flagKey); final Map valueMap = ctx.asObjectMap(); - valueMap.put(FLAG_KEY, flagKey); + valueMap.put(FLAGD_PROPS_KEY, flagdProperties); try { return jsonLogicHandler.apply(targetingRule, valueMap); @@ -53,7 +59,10 @@ static class FlagProperties { if (from instanceof Map) { Map dataMap = (Map) from; - Object flagKey = dataMap.get(FLAG_KEY); + final Object flagKey = Optional.ofNullable(dataMap.get(FLAGD_PROPS_KEY)) + .filter(flagdProps -> flagdProps instanceof Map) + .map(flagdProps -> ((Map)flagdProps).get(FLAG_KEY)) + .orElse(null); if (flagKey instanceof String) { this.flagKey = (String) flagKey; @@ -61,7 +70,7 @@ static class FlagProperties { this.flagKey = null; } - Object targetKey = dataMap.get(TARGET_KEY); + final Object targetKey = dataMap.get(TARGET_KEY); if (targetKey instanceof String) { targetingKey = (String) targetKey; diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/FractionalTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/FractionalTest.java index b3220e1e0..fd3e38c69 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/FractionalTest.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/FractionalTest.java @@ -1,17 +1,19 @@ package dev.openfeature.contrib.providers.flagd.resolver.process.targeting; -import io.github.jamsesso.jsonlogic.evaluator.JsonLogicEvaluationException; -import org.junit.jupiter.api.Test; +import static dev.openfeature.contrib.providers.flagd.resolver.process.targeting.Operator.FLAGD_PROPS_KEY; +import static dev.openfeature.contrib.providers.flagd.resolver.process.targeting.Operator.FLAG_KEY; +import static dev.openfeature.contrib.providers.flagd.resolver.process.targeting.Operator.TARGET_KEY; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import static dev.openfeature.contrib.providers.flagd.resolver.process.targeting.Operator.FLAG_KEY; -import static dev.openfeature.contrib.providers.flagd.resolver.process.targeting.Operator.TARGET_KEY; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; + +import io.github.jamsesso.jsonlogic.evaluator.JsonLogicEvaluationException; class FractionalTest { @@ -48,8 +50,10 @@ void selfContainedFractionalA() throws JsonLogicEvaluationException { rule.add(bucket1); rule.add(bucket2); - Map data = new HashMap<>(); - data.put(FLAG_KEY, "flagA"); + Map flagdProperties = new HashMap<>(); + flagdProperties.put(FLAG_KEY, "flagA"); + Map data = new HashMap<>(); + data.put(FLAGD_PROPS_KEY, flagdProperties); // when Object evaluate = fractional.evaluate(rule, data); @@ -91,8 +95,10 @@ void selfContainedFractionalB() throws JsonLogicEvaluationException { rule.add(bucket1); rule.add(bucket2); - Map data = new HashMap<>(); - data.put(FLAG_KEY, "flagA"); + Map flagdProperties = new HashMap<>(); + flagdProperties.put(FLAG_KEY, "flagA"); + Map data = new HashMap<>(); + data.put(FLAGD_PROPS_KEY, flagdProperties); // when Object evaluate = fractional.evaluate(rule, data); diff --git a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/OperatorTest.java b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/OperatorTest.java index a6a1fe2e3..c3f8e92eb 100644 --- a/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/OperatorTest.java +++ b/providers/flagd/src/test/java/dev/openfeature/contrib/providers/flagd/resolver/process/targeting/OperatorTest.java @@ -1,14 +1,15 @@ package dev.openfeature.contrib.providers.flagd.resolver.process.targeting; -import dev.openfeature.sdk.ImmutableContext; -import dev.openfeature.sdk.Value; -import org.junit.jupiter.api.BeforeAll; -import org.junit.jupiter.api.Test; +import static org.junit.jupiter.api.Assertions.assertEquals; import java.util.HashMap; import java.util.Map; -import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import dev.openfeature.sdk.ImmutableContext; +import dev.openfeature.sdk.Value; class OperatorTest { private static Operator OPERATOR; @@ -18,6 +19,20 @@ static void setUp() { OPERATOR = new Operator(); } + @Test + void flagKeyPresent() throws TargetingRuleException { + // given + + // rule asserting $flagd.flagKey equals the flag key + final String targetingRule = "{\"===\":[{\"var\":[\"$flagd.flagKey\"]},\"some-key\"]}"; + + // when + Object evalVariant = OPERATOR.apply("some-key", targetingRule, new ImmutableContext()); + + // then + assertEquals(true, evalVariant); + } + @Test void fractionalTestA() throws TargetingRuleException { // given