Skip to content

Commit

Permalink
Merge pull request #462 from splitio/SDKS-7788
Browse files Browse the repository at this point in the history
[SDKS-7788] Some flag set fixes
  • Loading branch information
nmayorsplit authored Nov 29, 2023
2 parents ef46ef3 + 918d664 commit d5133eb
Show file tree
Hide file tree
Showing 7 changed files with 119 additions and 11 deletions.
65 changes: 63 additions & 2 deletions client/src/main/java/io/split/client/SplitClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ public interface SplitClient {
Map<String, SplitResult> getTreatmentsWithConfig(String key, List<String> featureFlagNames, Map<String, Object> attributes);

/**
* Same as {@link #getTreatments(Key, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* Same as {@link #getTreatments(Key, List, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
*
* @param key the matching and bucketing keys. MUST NOT be null.
Expand All @@ -268,6 +268,21 @@ public interface SplitClient {
*/
Map<String, SplitResult> getTreatmentsWithConfig(Key key, List<String> featureFlagNames, Map<String, Object> attributes);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
* <p/>
* <p/>
* Examples include showing a different treatment to users on trial plan
* vs. premium plan. Another example is to show a different treatment
* to users created after a certain date.
*
* @param key a unique key of your customer (e.g. user_id, user_email, account_id, etc.) MUST not be null or empty.
* @param flagSet the Flag Set name that you want to evaluate. MUST not be null or empty.
* @return for each feature flag the evaluated treatment, the default treatment of this feature flag, or 'control'.
*/
Map<String, String> getTreatmentsByFlagSet(String key, String flagSet);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
Expand Down Expand Up @@ -300,6 +315,21 @@ public interface SplitClient {
*/
Map<String, String> getTreatmentsByFlagSet(Key key, String flagSet, Map<String, Object> attributes);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
* <p/>
* <p/>
* Examples include showing a different treatment to users on trial plan
* vs. premium plan. Another example is to show a different treatment
* to users created after a certain date.
*
* @param key a unique key of your customer (e.g. user_id, user_email, account_id, etc.) MUST not be null or empty.
* @param flagSets the names of Flag Sets that you want to evaluate. MUST not be null or empty.
* @return for each feature flag the evaluated treatment, the default treatment of this feature flag, or 'control'.
*/
Map<String, String> getTreatmentsByFlagSets(String key, List<String> flagSets);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
Expand Down Expand Up @@ -332,6 +362,22 @@ public interface SplitClient {
*/
Map<String, String> getTreatmentsByFlagSets(Key key, List<String> flagSets, Map<String, Object> attributes);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
* <p/>
* <p/>
* Examples include showing a different treatment to users on trial plan
* vs. premium plan. Another example is to show a different treatment
* to users created after a certain date.
*
* @param key a unique key of your customer (e.g. user_id, user_email, account_id, etc.) MUST not be null or empty.
* @param flagSet the Flag Set name that you want to evaluate. MUST not be null or empty.
* @return for each feature flag the evaluated treatment (the default treatment of this feature flag, or 'control') and a configuration
* associated to this treatment if set.
*/
Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(String key, String flagSet);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
Expand Down Expand Up @@ -366,6 +412,22 @@ public interface SplitClient {
*/
Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(Key key, String flagSet, Map<String, Object> attributes);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
* <p/>
* <p/>
* Examples include showing a different treatment to users on trial plan
* vs. premium plan. Another example is to show a different treatment
* to users created after a certain date.
*
* @param key a unique key of your customer (e.g. user_id, user_email, account_id, etc.) MUST not be null or empty.
* @param flagSets the names of Flag Sets that you want to evaluate. MUST not be null or empty.
* @return for each feature flag the evaluated treatment (the default treatment of this feature flag, or 'control') and a configuration
* associated to this treatment if set.
*/
Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(String key, List<String> flagSets);

/**
* Same as {@link #getTreatments(String, List<String>, Map)} but it returns for each feature flag the configuration associated to the
* matching treatment if any. Otherwise {@link SplitResult.configurations()} will be null.
Expand Down Expand Up @@ -444,7 +506,6 @@ public interface SplitClient {
* @param key the identifier of the entity
* @param trafficType the type of the event
* @param eventType the type of the event
* @param value the value of the event
*
* @return true if the track was successful, false otherwise
*/
Expand Down
33 changes: 30 additions & 3 deletions client/src/main/java/io/split/client/SplitClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ public Map<String, SplitResult> getTreatmentsWithConfig(Key key, List<String> fe
MethodEnum.TREATMENTS_WITH_CONFIG);
}

@Override
public Map<String, String> getTreatmentsByFlagSet(String key, String flagSet) {
return getTreatmentsBySetsWithConfigInternal(key, null, new ArrayList<>(Arrays.asList(flagSet)),
null, MethodEnum.TREATMENTS_BY_FLAG_SET).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().treatment()));
}

@Override
public Map<String, String> getTreatmentsByFlagSet(String key, String flagSet, Map<String, Object> attributes) {
return getTreatmentsBySetsWithConfigInternal(key, null, new ArrayList<>(Arrays.asList(flagSet)),
Expand All @@ -164,6 +171,13 @@ public Map<String, String> getTreatmentsByFlagSet(Key key, String flagSet, Map<S
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().treatment()));
}

@Override
public Map<String, String> getTreatmentsByFlagSets(String key, List<String> flagSets) {
return getTreatmentsBySetsWithConfigInternal(key, null, flagSets,
null, MethodEnum.TREATMENTS_BY_FLAG_SETS).entrySet().stream()
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().treatment()));
}

@Override
public Map<String, String> getTreatmentsByFlagSets(String key, List<String> flagSets, Map<String, Object> attributes) {
return getTreatmentsBySetsWithConfigInternal(key, null, flagSets,
Expand All @@ -178,6 +192,12 @@ public Map<String, String> getTreatmentsByFlagSets(Key key, List<String> flagSet
.collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().treatment()));
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(String key, String flagSet) {
return getTreatmentsBySetsWithConfigInternal(key, null, new ArrayList<>(Arrays.asList(flagSet)),
null, MethodEnum.TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(String key, String flagSet, Map<String, Object> attributes) {
return getTreatmentsBySetsWithConfigInternal(key, null, new ArrayList<>(Arrays.asList(flagSet)),
Expand All @@ -190,6 +210,12 @@ public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(Key key, String
attributes, MethodEnum.TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(String key, List<String> flagSets) {
return getTreatmentsBySetsWithConfigInternal(key, null, flagSets,
null, MethodEnum.TREATMENTS_WITH_CONFIG_BY_FLAG_SETS);
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(String key, List<String> flagSets, Map<String, Object> attributes) {
return getTreatmentsBySetsWithConfigInternal(key, null, flagSets,
Expand Down Expand Up @@ -381,7 +407,8 @@ private Map<String, SplitResult> getTreatmentsBySetsWithConfigInternal(String ma
return new HashMap<>();
}
Set cleanFlagSets = cleanup(sets);
if (filterSetsAreInConfig(cleanFlagSets, methodEnum).isEmpty()) {
cleanFlagSets = filterSetsAreInConfig(cleanFlagSets, methodEnum);
if (cleanFlagSets.isEmpty()) {
return new HashMap<>();
}
List<String> featureFlagNames = new ArrayList<>();
Expand Down Expand Up @@ -447,8 +474,8 @@ private Map<String, SplitResult> validateBeforeEvaluate(List<String> featureFlag
}
return null;
}
private List<String> filterSetsAreInConfig(Set<String> sets, MethodEnum methodEnum) {
List<String> setsToReturn = new ArrayList<>();
private Set<String> filterSetsAreInConfig(Set<String> sets, MethodEnum methodEnum) {
Set<String> setsToReturn = new HashSet<>();
for (String set : sets) {
if (!_flagSetsFilter.intersect(set)) {
_log.warn(String.format("%s: you passed %s which is not part of the configured FlagSetsFilter, " +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static Set<String> cleanup(List<String> flagSets) {
}
if (!Pattern.matches(FLAG_SET_REGEX, flagSet)) {
_log.warn(String.format("you passed %s, Flag Set must adhere to the regular expressions %s. This means a Flag Set must be " +
"start with a letter, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.",
"start with a letter or number, be in lowercase, alphanumeric and have a max length of 50 characters. %s was discarded.",
flagSet, FLAG_SET_REGEX, flagSet));
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,7 @@ public Map<String, HashSet<String>> getNamesByFlagSets(List<String> flagSets) {
Map<String, HashSet<String>> toReturn = new HashMap<>();
for (String set: flagSets) {
HashSet<String> keys = _flagSets.get(set);
if(keys != null){
toReturn.put(set, keys);
}
toReturn.put(set, keys);
}
return toReturn;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1955,7 +1955,7 @@ public void testTreatmentsByFlagSets() {
fetchManyResult.put(test2, parsedSplit2);
when(splitCacheConsumer.fetchMany(new ArrayList<>(Arrays.asList(test2, test)))).thenReturn(fetchManyResult);

List<String> sets = new ArrayList<>(Arrays.asList("set1", "set3"));
List<String> sets = new ArrayList<>(Arrays.asList("set3", "set1"));
Map<String, HashSet<String>> flagsBySets = new HashMap<>();
flagsBySets.put("set1", new HashSet<>(Arrays.asList(test)));
flagsBySets.put("set3", new HashSet<>(Arrays.asList(test2)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.util.stream.Stream;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

public class InMemoryCacheTest {
Expand Down Expand Up @@ -229,7 +230,8 @@ public void testGetNamesByFlagSets() {
assertTrue(namesByFlagSets.get("set1").contains("splitName_2"));
assertFalse(namesByFlagSets.get("set1").contains("splitName_3"));
assertFalse(namesByFlagSets.get("set1").contains("splitName_4"));
assertFalse(namesByFlagSets.keySet().contains("set3"));
assertTrue(namesByFlagSets.keySet().contains("set3"));
assertNull(namesByFlagSets.get("set3"));

_cache.remove("splitName_2");
namesByFlagSets = _cache.getNamesByFlagSets(new ArrayList<>(Arrays.asList("set1", "set2", "set3")));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,11 @@ public Map<String, SplitResult> getTreatmentsWithConfig(Key key, List<String> fe
return treatments;
}

@Override
public Map<String, String> getTreatmentsByFlagSet(String key, String flagSet) {
return null;
}

@Override
public Map<String, String> getTreatmentsByFlagSet(String key, String flagSet, Map<String, Object> attributes) {
return new HashMap<>();
Expand All @@ -142,6 +147,11 @@ public Map<String, String> getTreatmentsByFlagSet(Key key, String flagSet, Map<S
return new HashMap<>();
}

@Override
public Map<String, String> getTreatmentsByFlagSets(String key, List<String> flagSets) {
return null;
}

@Override
public Map<String, String> getTreatmentsByFlagSets(String key, List<String> flagSets, Map<String, Object> attributes) {
return new HashMap<>();
Expand All @@ -152,6 +162,11 @@ public Map<String, String> getTreatmentsByFlagSets(Key key, List<String> flagSet
return new HashMap<>();
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(String key, String flagSet) {
return null;
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(String key, String flagSet, Map<String, Object> attributes) {
return new HashMap<>();
Expand All @@ -162,6 +177,11 @@ public Map<String, SplitResult> getTreatmentsWithConfigByFlagSet(Key key, String
return new HashMap<>();
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(String key, List<String> flagSets) {
return null;
}

@Override
public Map<String, SplitResult> getTreatmentsWithConfigByFlagSets(String key, List<String> flagSets, Map<String, Object> attributes) {
return new HashMap<>();
Expand Down

0 comments on commit d5133eb

Please sign in to comment.