Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDKS-7788] Some flag set fixes #462

Merged
merged 1 commit into from
Nov 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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