diff --git a/.gitmodules b/.gitmodules index 4ff0518..af07286 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "src/test/java/com/flagsmith/flagengine/enginetestdata"] path = src/test/java/com/flagsmith/flagengine/enginetestdata url = git@github.com:Flagsmith/engine-test-data.git - tag = v2.5.0 \ No newline at end of file + tag = v3.2.1 \ No newline at end of file diff --git a/src/main/java/com/flagsmith/flagengine/Engine.java b/src/main/java/com/flagsmith/flagengine/Engine.java index f886ce2..56f8c61 100644 --- a/src/main/java/com/flagsmith/flagengine/Engine.java +++ b/src/main/java/com/flagsmith/flagengine/Engine.java @@ -2,12 +2,14 @@ import com.flagsmith.flagengine.segments.SegmentEvaluator; import com.flagsmith.flagengine.utils.Hashing; +import java.math.BigDecimal; import java.util.ArrayList; import java.util.HashMap; import java.util.List; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.tuple.ImmutablePair; -public class Engine { +public class Engine { private static class SegmentEvaluationResult { List segments; HashMap> segmentFeatureContexts; @@ -35,6 +37,7 @@ public HashMap> getSegmentFeatureC * @return Evaluation result. */ public static EvaluationResult getEvaluationResult(EvaluationContext context) { + context = getEnrichedEvaluationContext(context); SegmentEvaluationResult segmentEvaluationResult = evaluateSegments(context); Flags flags = evaluateFeatures(context, segmentEvaluationResult.getSegmentFeatureContexts()); @@ -43,6 +46,24 @@ public static EvaluationResult getEvaluationResult(EvaluationContext context) { .withSegments(segmentEvaluationResult.getSegments()); } + /* + * Get a version of the evaluation context enriched with derived data. + * + * @param context Evaluation context. + * @return Enriched evaluation context, or the original if no enrichment was needed. + */ + private static EvaluationContext getEnrichedEvaluationContext(EvaluationContext context) { + IdentityContext identity = context.getIdentity(); + if (identity != null) { + if (StringUtils.isEmpty(identity.getKey())) { + String identityKey = context.getEnvironment().getKey() + "_" + identity.getIdentifier(); + context = new EvaluationContext(context).withIdentity( + new IdentityContext(identity).withKey(identityKey)); + } + } + return context; + } + private static SegmentEvaluationResult evaluateSegments( EvaluationContext context) { List segments = new ArrayList<>(); @@ -53,7 +74,7 @@ private static SegmentEvaluationResult evaluateSegments( if (contextSegments != null) { for (SegmentContext segmentContext : contextSegments.getAdditionalProperties().values()) { if (SegmentEvaluator.isContextInSegment(context, segmentContext)) { - segments.add(new SegmentResult().withKey(segmentContext.getKey()) + segments.add(new SegmentResult() .withName(segmentContext.getName()) .withMetadata(segmentContext.getMetadata())); @@ -61,11 +82,11 @@ private static SegmentEvaluationResult evaluateSegments( if (segmentOverrides != null) { for (FeatureContext featureContext : segmentOverrides) { - String featureKey = featureContext.getFeatureKey(); + String featureName = featureContext.getName(); - if (segmentFeatureContexts.containsKey(featureKey)) { + if (segmentFeatureContexts.containsKey(featureName)) { ImmutablePair existing = segmentFeatureContexts - .get(featureKey); + .get(featureName); FeatureContext existingFeatureContext = existing.getRight(); Double existingPriority = existingFeatureContext.getPriority() == null @@ -79,7 +100,7 @@ private static SegmentEvaluationResult evaluateSegments( continue; } } - segmentFeatureContexts.put(featureKey, + segmentFeatureContexts.put(featureName, new ImmutablePair( segmentContext.getName(), featureContext)); } @@ -103,14 +124,13 @@ private static Flags evaluateFeatures( if (contextFeatures != null) { for (FeatureContext featureContext : contextFeatures.getAdditionalProperties().values()) { - if (segmentFeatureContexts.containsKey(featureContext.getFeatureKey())) { + if (segmentFeatureContexts.containsKey(featureContext.getName())) { ImmutablePair segmentNameFeaturePair = segmentFeatureContexts - .get(featureContext.getFeatureKey()); + .get(featureContext.getName()); featureContext = segmentNameFeaturePair.getRight(); flags.setAdditionalProperty( featureContext.getName(), new FlagResult().withEnabled(featureContext.getEnabled()) - .withFeatureKey(featureContext.getFeatureKey()) .withName(featureContext.getName()) .withValue(featureContext.getValue()) .withReason( @@ -148,10 +168,11 @@ private static FlagResult getFlagResultFromFeatureContext( Float limit = startPercentage + weight.floatValue(); if (startPercentage <= percentageValue && percentageValue < limit) { return new FlagResult().withEnabled(featureContext.getEnabled()) - .withFeatureKey(featureContext.getFeatureKey()) .withName(featureContext.getName()) .withValue(variant.getValue()) - .withReason("SPLIT; weight=" + weight.intValue()) + .withReason("SPLIT; weight=" + BigDecimal.valueOf(weight) + .stripTrailingZeros() + .toPlainString()) .withMetadata(featureContext.getMetadata()); } startPercentage = limit; @@ -160,7 +181,6 @@ private static FlagResult getFlagResultFromFeatureContext( } return new FlagResult().withEnabled(featureContext.getEnabled()) - .withFeatureKey(featureContext.getFeatureKey()) .withName(featureContext.getName()) .withValue(featureContext.getValue()) .withReason("DEFAULT") diff --git a/src/main/java/com/flagsmith/mappers/EngineMappers.java b/src/main/java/com/flagsmith/mappers/EngineMappers.java index 51ec7ee..3beee22 100644 --- a/src/main/java/com/flagsmith/mappers/EngineMappers.java +++ b/src/main/java/com/flagsmith/mappers/EngineMappers.java @@ -80,8 +80,7 @@ public static EvaluationContext mapContextAndIdentityDataToContext( // Create identity context IdentityContext identityContext = new IdentityContext() - .withIdentifier(identifier) - .withKey(context.getEnvironment().getKey() + "_" + identifier); + .withIdentifier(identifier); // Map traits if provided if (traits != null && !traits.isEmpty()) { @@ -196,7 +195,6 @@ private static Map mapIdentityOverridesToSegments( FeatureModel feature = featureState.getFeature(); FeatureContext featureContext = new FeatureContext() .withKey("") - .withFeatureKey(String.valueOf(feature.getId())) .withName(feature.getName()) .withEnabled(featureState.getEnabled()) .withValue(featureState.getValue()) @@ -349,7 +347,6 @@ private static double getMultivariateFeatureValuePriority( private static FeatureContext mapFeatureStateToFeatureContext(FeatureStateModel featureState) { FeatureContext featureContext = new FeatureContext() .withKey(getFeatureStateKey(featureState)) - .withFeatureKey(String.valueOf(featureState.getFeature().getId())) .withName(featureState.getFeature().getName()) .withEnabled(featureState.getEnabled()) .withValue(featureState.getValue()) diff --git a/src/test/java/com/flagsmith/flagengine/enginetestdata b/src/test/java/com/flagsmith/flagengine/enginetestdata index 41c2021..218757f 160000 --- a/src/test/java/com/flagsmith/flagengine/enginetestdata +++ b/src/test/java/com/flagsmith/flagengine/enginetestdata @@ -1 +1 @@ -Subproject commit 41c202145e375c712600e318c439456de5b221d7 +Subproject commit 218757fd23f932760be681a09c686c9d6ef55fad diff --git a/src/test/java/com/flagsmith/flagengine/models/FlagsTest.java b/src/test/java/com/flagsmith/flagengine/models/FlagsTest.java index 11094c3..ed237d6 100644 --- a/src/test/java/com/flagsmith/flagengine/models/FlagsTest.java +++ b/src/test/java/com/flagsmith/flagengine/models/FlagsTest.java @@ -17,14 +17,12 @@ public void testFromEvaluationResult__metadata__expected() throws FlagsmithClien com.flagsmith.flagengine.Flags flagResults = new com.flagsmith.flagengine.Flags() .withAdditionalProperty("feature_1", new FlagResult() .withEnabled(true) - .withFeatureKey("feature_1") .withName("Feature 1") .withValue("value_1") .withReason("DEFAULT") .withMetadata(Map.of("flagsmithId", 1))) .withAdditionalProperty("feature_2", new FlagResult() .withEnabled(false) - .withFeatureKey("feature_2") .withName("Feature 2") .withValue(null) .withReason("DEFAULT")