Skip to content

Commit

Permalink
chore: Use client spec 5.1.5 instead of 5.0.2 (#242)
Browse files Browse the repository at this point in the history
* chore: Use client spec 5.1.5 instead of 5.0.2

* fix: inherit strategy stickiness setting for variants
  • Loading branch information
chriswk committed May 8, 2024
1 parent a773b77 commit 5fddde5
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 8 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<version.junit5>5.10.0</version.junit5>
<version.okhttp>4.10.0</version.okhttp>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<version.unleash.specification>5.0.2</version.unleash.specification>
<version.unleash.specification>5.1.5</version.unleash.specification>
<arguments />
<version.jackson>2.14.3</version.jackson>
</properties>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,4 @@ public boolean isEnabled(Map<String, String> parameters, UnleashContext unleashC
.map(norm -> percentage > 0 && norm <= percentage)
.orElse(false);
}

private String getStickiness(Map<String, String> parameters) {
return parameters.getOrDefault("stickiness", "default");
}
}
13 changes: 12 additions & 1 deletion src/main/java/io/getunleash/strategy/Strategy.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@ default FeatureEvaluationResult getResult(
List<Constraint> constraints,
@Nullable List<VariantDefinition> variants) {
boolean enabled = isEnabled(parameters, unleashContext, constraints);
String strategyStickiness = getStickiness(parameters);
return new FeatureEvaluationResult(
enabled,
enabled ? VariantUtil.selectVariant(parameters, variants, unleashContext) : null);
enabled
? VariantUtil.selectVariant(
parameters, variants, unleashContext, strategyStickiness)
: null);
}

/**
Expand Down Expand Up @@ -61,4 +65,11 @@ default boolean isEnabled(
return ConstraintUtil.validate(constraints, unleashContext)
&& isEnabled(parameters, unleashContext);
}

default String getStickiness(@Nullable Map<String, String> parameters) {
if (parameters != null) {
return parameters.getOrDefault("stickiness", "default");
}
return null;
}
}
20 changes: 18 additions & 2 deletions src/main/java/io/getunleash/variant/VariantUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ public static Variant selectVariant(
public static @Nullable Variant selectVariant(
Map<String, String> parameters,
@Nullable List<VariantDefinition> variants,
UnleashContext context) {
UnleashContext context,
@Nullable String strategyStickiness) {
if (variants != null) {
int totalWeight = variants.stream().mapToInt(VariantDefinition::getWeight).sum();
if (totalWeight <= 0) {
Expand All @@ -106,14 +107,22 @@ public static Variant selectVariant(
return variantOverride.get().toVariant();
}

Optional<String> customStickiness =
Optional<String> variantCustomStickiness =
variants.stream()
.filter(
f ->
f.getStickiness() != null
&& !"default".equals(f.getStickiness()))
.map(VariantDefinition::getStickiness)
.findFirst();
Optional<String> customStickiness;
if (!variantCustomStickiness.isPresent()) {
customStickiness =
Optional.ofNullable(strategyStickiness)
.filter(stickiness -> !stickiness.equalsIgnoreCase("default"));
} else {
customStickiness = variantCustomStickiness;
}
int target =
StrategyUtils.getNormalizedNumber(
getSeed(context, customStickiness),
Expand All @@ -134,6 +143,13 @@ public static Variant selectVariant(
return null;
}

public static @Nullable Variant selectVariant(
Map<String, String> parameters,
@Nullable List<VariantDefinition> variants,
UnleashContext context) {
return selectVariant(parameters, variants, context, null);
}

/**
* Uses the old pre 9.0.0 way of hashing for finding the Variant to return
*
Expand Down
128 changes: 128 additions & 0 deletions src/test/java/io/getunleash/strategy/StrategyVariantTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
package io.getunleash.strategy;

import static org.assertj.core.api.Assertions.assertThat;

import io.getunleash.FeatureEvaluationResult;
import io.getunleash.UnleashContext;
import io.getunleash.Variant;
import io.getunleash.variant.Payload;
import io.getunleash.variant.VariantDefinition;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import org.junit.jupiter.api.Test;

public class StrategyVariantTest {

@Test
public void should_inherit_stickiness_from_the_strategy_first_variant() {
HashMap<String, String> params = new HashMap<>();
params.put("rollout", "100");
params.put("stickiness", "clientId");
params.put("groupId", "a");
FlexibleRolloutStrategy strategy = new FlexibleRolloutStrategy();
VariantDefinition varA =
new VariantDefinition(
"variantNameA",
1,
new Payload("string", "variantValueA"),
Collections.emptyList());
VariantDefinition varB =
new VariantDefinition(
"variantNameB",
1,
new Payload("string", "variantValueB"),
Collections.emptyList());

UnleashContext context = UnleashContext.builder().addProperty("clientId", "1").build();
FeatureEvaluationResult result =
strategy.getResult(
params, context, Collections.emptyList(), Arrays.asList(varA, varB));
Variant selectedVariant = result.getVariant();
assert selectedVariant != null;
assertThat(selectedVariant.getName()).isEqualTo("variantNameA");
}

@Test
public void should_inherit_stickiness_from_the_strategy_second_variant() {
HashMap<String, String> params = new HashMap<>();
params.put("rollout", "100");
params.put("stickiness", "clientId");
params.put("groupId", "a");
FlexibleRolloutStrategy strategy = new FlexibleRolloutStrategy();
VariantDefinition varA =
new VariantDefinition(
"variantNameA",
1,
new Payload("string", "variantValueA"),
Collections.emptyList());
VariantDefinition varB =
new VariantDefinition(
"variantNameB",
1,
new Payload("string", "variantValueB"),
Collections.emptyList());

UnleashContext context = UnleashContext.builder().addProperty("clientId", "2").build();
FeatureEvaluationResult result =
strategy.getResult(
params, context, Collections.emptyList(), Arrays.asList(varA, varB));
Variant selectedVariant = result.getVariant();
assert selectedVariant != null;
assertThat(selectedVariant.getName()).isEqualTo("variantNameB");
}

@Test
public void multiple_variants_should_choose_first_variant() {
HashMap<String, String> params = new HashMap<>();
params.put("rollout", "100");
params.put("groupId", "a");
params.put("stickiness", "default");
FlexibleRolloutStrategy strategy = new FlexibleRolloutStrategy();
VariantDefinition varA =
new VariantDefinition(
"variantNameA",
1,
new Payload("string", "variantValueA"),
Collections.emptyList());
VariantDefinition varB =
new VariantDefinition(
"variantNameB",
1,
new Payload("string", "variantValueB"),
Collections.emptyList());
UnleashContext context = UnleashContext.builder().userId("5").build();
FeatureEvaluationResult result =
strategy.getResult(
params, context, Collections.emptyList(), Arrays.asList(varA, varB));
Variant selectedVariant = result.getVariant();
assertThat(selectedVariant.getName()).isEqualTo("variantNameA");
}

@Test
public void multiple_variants_should_choose_second_variant() {
HashMap<String, String> params = new HashMap<>();
params.put("rollout", "100");
params.put("groupId", "a");
params.put("stickiness", "default");
FlexibleRolloutStrategy strategy = new FlexibleRolloutStrategy();
VariantDefinition varA =
new VariantDefinition(
"variantNameA",
1,
new Payload("string", "variantValueA"),
Collections.emptyList());
VariantDefinition varB =
new VariantDefinition(
"variantNameB",
1,
new Payload("string", "variantValueB"),
Collections.emptyList());
UnleashContext context = UnleashContext.builder().userId("0").build();
FeatureEvaluationResult result =
strategy.getResult(
params, context, Collections.emptyList(), Arrays.asList(varA, varB));
Variant selectedVariant = result.getVariant();
assertThat(selectedVariant.getName()).isEqualTo("variantNameB");
}
}

0 comments on commit 5fddde5

Please sign in to comment.