1 package io.getunleash.strategy;
2
3 import io.getunleash.UnleashContext;
4 import java.util.Map;
5 import java.util.Optional;
6 import java.util.function.Supplier;
7
8 public class FlexibleRolloutStrategy implements Strategy {
9     protected static final String PERCENTAGE = "rollout";
10     protected static final String GROUP_ID = "groupId";
11
12     private Supplier<String> randomGenerator;
13
14     public FlexibleRolloutStrategy() {
15         this.randomGenerator = () -> Math.random() * 10000 + "";
16     }
17
18     public FlexibleRolloutStrategy(Supplier<String> randomGenerator) {
19         this.randomGenerator = randomGenerator;
20     }
21
22     @Override
23     public String getName() {
24         return "flexibleRollout";
25     }
26
27     @Override
28     public boolean isEnabled(Map<String, String> parameters) {
29         return false;
30     }
31
32     private Optional<String> resolveStickiness(String stickiness, UnleashContext context) {
33         switch (stickiness) {
34             case "userId":
35                 return context.getUserId();
36             case "sessionId":
37                 return context.getSessionId();
38             case "random":
39                 return Optional.of(randomGenerator.get());
40             case "default":
41                 String value =
42                         context.getUserId()
43                                 .orElse(context.getSessionId().orElse(this.randomGenerator.get()));
44                 return Optional.of(value);
45             default:
46                 return context.getByName(stickiness);
47         }
48     }
49
50     @Override
51     public boolean isEnabled(Map<String, String> parameters, UnleashContext unleashContext) {
52         final String stickiness = getStickiness(parameters);
53         final Optional<String> stickinessId = resolveStickiness(stickiness, unleashContext);
54         final int percentage = StrategyUtils.getPercentage(parameters.get(PERCENTAGE));
55         final String groupId = parameters.getOrDefault(GROUP_ID, "");
56
57         return stickinessId
58                 .map(stick -> StrategyUtils.getNormalizedNumber(stick, groupId, 0))
59                 .map(norm -> percentage > 0 && norm <= percentage)
60                 .orElse(false);
61     }
62 }
63