diff --git a/client/src/main/java/io/split/client/SplitClientImpl.java b/client/src/main/java/io/split/client/SplitClientImpl.java index 36d0ef03a..e23156c32 100644 --- a/client/src/main/java/io/split/client/SplitClientImpl.java +++ b/client/src/main/java/io/split/client/SplitClientImpl.java @@ -421,7 +421,7 @@ private List filterSetsAreInConfig(Set sets, MethodEnum methodEn FlagSetsFilter flagSetsFilter = new FlagSetsFilterImpl(_config.getSetsFilter()); List setsToReturn = new ArrayList<>(); for (String set : sets) { - if (!flagSetsFilter.Intersect(set)) { + if (!flagSetsFilter.intersect(set)) { _log.warn(String.format("%s: you passed %s which is not part of the configured FlagSetsFilter, " + "ignoring Flag Set.", methodEnum, set)); continue; diff --git a/client/src/main/java/io/split/client/SplitFactoryImpl.java b/client/src/main/java/io/split/client/SplitFactoryImpl.java index bcb032bbb..7a0593838 100644 --- a/client/src/main/java/io/split/client/SplitFactoryImpl.java +++ b/client/src/main/java/io/split/client/SplitFactoryImpl.java @@ -279,7 +279,8 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor Metadata metadata = new Metadata(config.ipAddressEnabled(), SplitClientConfig.splitSdkVersion); _userStorageWrapper = new UserStorageWrapper(customStorageWrapper); UserCustomSegmentAdapterConsumer userCustomSegmentAdapterConsumer= new UserCustomSegmentAdapterConsumer(customStorageWrapper); - UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(customStorageWrapper); + UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(customStorageWrapper, + config.getSetsFilter()); // TODO migrate impressions sender to Task instead manager and not instantiate Producer here. UserCustomImpressionAdapterConsumer userCustomImpressionAdapterConsumer = new UserCustomImpressionAdapterConsumer(); UserCustomImpressionAdapterProducer userCustomImpressionAdapterProducer = new UserCustomImpressionAdapterProducer(customStorageWrapper, diff --git a/client/src/main/java/io/split/client/interceptors/FlagSetsFilter.java b/client/src/main/java/io/split/client/interceptors/FlagSetsFilter.java index 20a7d1449..f571f1342 100644 --- a/client/src/main/java/io/split/client/interceptors/FlagSetsFilter.java +++ b/client/src/main/java/io/split/client/interceptors/FlagSetsFilter.java @@ -4,6 +4,6 @@ public interface FlagSetsFilter { - boolean Intersect(Set sets); - boolean Intersect(String set); + boolean intersect(Set sets); + boolean intersect(String set); } \ No newline at end of file diff --git a/client/src/main/java/io/split/client/interceptors/FlagSetsFilterImpl.java b/client/src/main/java/io/split/client/interceptors/FlagSetsFilterImpl.java index ff6178958..e97da9f6c 100644 --- a/client/src/main/java/io/split/client/interceptors/FlagSetsFilterImpl.java +++ b/client/src/main/java/io/split/client/interceptors/FlagSetsFilterImpl.java @@ -12,7 +12,7 @@ public FlagSetsFilterImpl(Set flagSets) { _flagSets = flagSets; } @Override - public boolean Intersect(Set sets) { + public boolean intersect(Set sets) { if (!_shouldFilter) { return true; } @@ -28,7 +28,7 @@ public boolean Intersect(Set sets) { } @Override - public boolean Intersect(String set) { + public boolean intersect(String set) { if (!_shouldFilter) { return true; } diff --git a/client/src/main/java/io/split/client/utils/FeatureFlagProcessor.java b/client/src/main/java/io/split/client/utils/FeatureFlagProcessor.java index 497f37140..f6e4878a9 100644 --- a/client/src/main/java/io/split/client/utils/FeatureFlagProcessor.java +++ b/client/src/main/java/io/split/client/utils/FeatureFlagProcessor.java @@ -3,7 +3,6 @@ import io.split.client.dtos.Split; import io.split.client.dtos.Status; import io.split.client.interceptors.FlagSetsFilter; -import io.split.client.interceptors.FlagSetsFilterImpl; import io.split.engine.experiments.ParsedSplit; import io.split.engine.experiments.SplitParser; import org.slf4j.Logger; @@ -27,7 +26,7 @@ public static FeatureFlagsToUpdate processFeatureFlagChanges(SplitParser splitPa toRemove.add(split.name); continue; } - if (!flagSetsFilter.Intersect(split.sets)) { + if (!flagSetsFilter.intersect(split.sets)) { toRemove.add(split.name); continue; } diff --git a/client/src/main/java/io/split/storages/memory/InMemoryCacheImp.java b/client/src/main/java/io/split/storages/memory/InMemoryCacheImp.java index 8c688fa1e..7920a6af0 100644 --- a/client/src/main/java/io/split/storages/memory/InMemoryCacheImp.java +++ b/client/src/main/java/io/split/storages/memory/InMemoryCacheImp.java @@ -190,7 +190,7 @@ private void addToFlagSets(ParsedSplit featureFlag) { return; } for (String set: sets) { - if (!_flagSetsFilter.Intersect(set)) { + if (!_flagSetsFilter.intersect(set)) { continue; } HashSet features = _flagSets.get(set); diff --git a/client/src/main/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumer.java b/client/src/main/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumer.java index d15363edc..5cab7bfc6 100644 --- a/client/src/main/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumer.java +++ b/client/src/main/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumer.java @@ -31,10 +31,12 @@ public class UserCustomSplitAdapterConsumer implements SplitCacheConsumer { private final SplitParser _splitParser; private final UserStorageWrapper _userStorageWrapper; + private final HashSet _flagSets; - public UserCustomSplitAdapterConsumer(CustomStorageWrapper customStorageWrapper) { + public UserCustomSplitAdapterConsumer(CustomStorageWrapper customStorageWrapper, HashSet flagSets) { _splitParser = new SplitParser(); _userStorageWrapper = new UserStorageWrapper(checkNotNull(customStorageWrapper)); + _flagSets = flagSets; } @Override @@ -45,25 +47,35 @@ public long getChangeNumber() { @Override public ParsedSplit get(String name) { - String wrapperResponse = _userStorageWrapper.get(PrefixAdapter.buildSplitKey(name)); - if(wrapperResponse == null) { - return null; - } - Split split = Json.fromJson(wrapperResponse, Split.class); - if(split == null) { - _log.warn("Could not parse Split."); - return null; + if (_flagSets.isEmpty() || getFlags().contains(name)){ + String wrapperResponse = _userStorageWrapper.get(PrefixAdapter.buildSplitKey(name)); + if(wrapperResponse == null) { + return null; + } + Split split = Json.fromJson(wrapperResponse, Split.class); + if(split == null) { + _log.warn("Could not parse Split."); + return null; + } + return _splitParser.parse(split); } - return _splitParser.parse(split); + return null; } @Override public Collection getAll() { - Set keys = _userStorageWrapper.getKeysByPrefix(PrefixAdapter.buildGetAllSplit()); - if(keys == null) { - return new ArrayList<>(); + List wrapperResponse; + if (_flagSets.isEmpty()) { + Set keys = _userStorageWrapper.getKeysByPrefix(PrefixAdapter.buildGetAllSplit()); + if(keys == null) { + return new ArrayList<>(); + } + wrapperResponse = _userStorageWrapper.getMany(new ArrayList<>(keys)); + + } else { + HashSet flagNames = getFlags(); + wrapperResponse = _userStorageWrapper.getMany(PrefixAdapter.buildFetchManySplits(new ArrayList<>(flagNames))); } - List wrapperResponse = _userStorageWrapper.getMany(new ArrayList<>(keys)); if(wrapperResponse == null) { return new ArrayList<>(); } @@ -88,10 +100,14 @@ public boolean trafficTypeExists(String trafficTypeName) { @Override public List splitNames() { - Set splitNamesWithPrefix = _userStorageWrapper.getKeysByPrefix(PrefixAdapter.buildGetAllSplit()); - splitNamesWithPrefix = splitNamesWithPrefix.stream().map(key -> key.replace(PrefixAdapter.buildSplitsPrefix(), "")). - collect(Collectors.toSet()); - return new ArrayList<>(splitNamesWithPrefix); + if(_flagSets.isEmpty()) { + Set splitNamesWithPrefix = _userStorageWrapper.getKeysByPrefix(PrefixAdapter.buildGetAllSplit()); + splitNamesWithPrefix = splitNamesWithPrefix.stream().map(key -> key.replace(PrefixAdapter.buildSplitsPrefix(), "")). + collect(Collectors.toSet()); + return new ArrayList<>(splitNamesWithPrefix); + } + HashSet flagNames = getFlags(); + return new ArrayList<>(flagNames); } @Override @@ -149,4 +165,13 @@ private List stringsToParsedSplits(List elements) { } return result; } + + private HashSet getFlags() { + HashSet flagNames = new HashSet<>(); + Map> nameByFlaySets = getNamesByFlagSets(new ArrayList<>(_flagSets)); + for (String set: nameByFlaySets.keySet()) { + flagNames.addAll(nameByFlaySets.get(set)); + } + return flagNames; + } } \ No newline at end of file diff --git a/client/src/test/java/io/split/client/interceptors/FlagSetsFilterImplTest.java b/client/src/test/java/io/split/client/interceptors/FlagSetsFilterImplTest.java index c9f4b384d..c0467e298 100644 --- a/client/src/test/java/io/split/client/interceptors/FlagSetsFilterImplTest.java +++ b/client/src/test/java/io/split/client/interceptors/FlagSetsFilterImplTest.java @@ -11,16 +11,16 @@ public class FlagSetsFilterImplTest { @Test public void testIntersectSetsWithShouldFilter() { FlagSetsFilter flagSetsFilter = new FlagSetsFilterImpl(new HashSet<>(Arrays.asList("a", "b"))); - Assert.assertTrue(flagSetsFilter.Intersect("a")); - Assert.assertTrue(flagSetsFilter.Intersect(new HashSet<>(Arrays.asList("a", "c")))); - Assert.assertFalse(flagSetsFilter.Intersect("c")); - Assert.assertFalse(flagSetsFilter.Intersect(new HashSet<>(Arrays.asList("d", "c")))); + Assert.assertTrue(flagSetsFilter.intersect("a")); + Assert.assertTrue(flagSetsFilter.intersect(new HashSet<>(Arrays.asList("a", "c")))); + Assert.assertFalse(flagSetsFilter.intersect("c")); + Assert.assertFalse(flagSetsFilter.intersect(new HashSet<>(Arrays.asList("d", "c")))); } @Test public void testIntersectSetsWithShouldNotFilter() { FlagSetsFilter flagSetsFilter = new FlagSetsFilterImpl(new HashSet<>()); - Assert.assertTrue(flagSetsFilter.Intersect("a")); - Assert.assertTrue(flagSetsFilter.Intersect(new HashSet<>(Arrays.asList("a", "c")))); + Assert.assertTrue(flagSetsFilter.intersect("a")); + Assert.assertTrue(flagSetsFilter.intersect(new HashSet<>(Arrays.asList("a", "c")))); } } \ No newline at end of file diff --git a/client/src/test/java/io/split/storages/pluggable/CustomStorageWrapperHasPipeline.java b/client/src/test/java/io/split/storages/pluggable/CustomStorageWrapperHasPipeline.java index 4a40061ba..a4f129717 100644 --- a/client/src/test/java/io/split/storages/pluggable/CustomStorageWrapperHasPipeline.java +++ b/client/src/test/java/io/split/storages/pluggable/CustomStorageWrapperHasPipeline.java @@ -1,6 +1,10 @@ package io.split.storages.pluggable; +import com.google.common.collect.Lists; import com.google.common.collect.Maps; +import io.split.client.dtos.Split; +import io.split.client.utils.Json; +import io.split.storages.pluggable.domain.PrefixAdapter; import pluggable.CustomStorageWrapper; import pluggable.HasPipelineSupport; import pluggable.Pipeline; @@ -8,8 +12,10 @@ import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.concurrent.Callable; import java.util.concurrent.ConcurrentMap; @@ -18,6 +24,7 @@ public class CustomStorageWrapperHasPipeline implements CustomStorageWrapper, Ha private static final String COUNTS = "SPLITIO.impressions.count"; private static final String FLAG_SET = "SPLITIO.flagSet"; + private static final String SPLIT = "SPLITIO.split."; private final ConcurrentMap _impressionsCount = Maps.newConcurrentMap(); private final ConcurrentMap> _flagSets = Maps.newConcurrentMap(); @@ -182,8 +189,10 @@ private HashSet getMembersToExecute(String key) { } private String getStorage(String key) { + if(key.startsWith(SPLIT)) + return SPLIT; if(key.startsWith(COUNTS)) - return COUNTS; + return COUNTS; if(key.startsWith(FLAG_SET)) return FLAG_SET; return ""; diff --git a/client/src/test/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumerTest.java b/client/src/test/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumerTest.java index 261147113..a66eb64bf 100644 --- a/client/src/test/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumerTest.java +++ b/client/src/test/java/io/split/storages/pluggable/adapters/UserCustomSplitAdapterConsumerTest.java @@ -23,6 +23,8 @@ import java.lang.reflect.Modifier; import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -41,7 +43,7 @@ public class UserCustomSplitAdapterConsumerTest { public void setUp() throws NoSuchFieldException, IllegalAccessException { _customStorageWrapper = Mockito.mock(CustomStorageWrapper.class); _userStorageWrapper = Mockito.mock(UserStorageWrapper.class); - _userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(_customStorageWrapper); + _userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(_customStorageWrapper, new HashSet<>()); Field userCustomSplitAdapterConsumer = UserCustomSplitAdapterConsumer.class.getDeclaredField("_userStorageWrapper"); userCustomSplitAdapterConsumer.setAccessible(true); Field modifiersField = Field.class.getDeclaredField("modifiers"); @@ -194,7 +196,8 @@ public void testFetchManyNotFound() { @Test public void testGetNamesByFlagSets() { CustomStorageWrapper customStorageWrapper = new CustomStorageWrapperHasPipeline(); - UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(customStorageWrapper); + HashSet sets = new HashSet<>(Arrays.asList("set1")); + UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(customStorageWrapper, sets); Map> flagSets = userCustomSplitAdapterConsumer.getNamesByFlagSets(new ArrayList<>(Arrays.asList("set1"))); Assert.assertEquals(2, flagSets.get("set1").size()); } @@ -202,7 +205,7 @@ public void testGetNamesByFlagSets() { @Test public void testGetSegments() { //NoOp - UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(_customStorageWrapper); + UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(_customStorageWrapper, new HashSet<>()); Assert.assertEquals(0, userCustomSplitAdapterConsumer.getSegments().size()); } diff --git a/pluggable-storage/src/main/java/pluggable/Pipeline.java b/pluggable-storage/src/main/java/pluggable/Pipeline.java index 09b40bbfb..653f9b635 100644 --- a/pluggable-storage/src/main/java/pluggable/Pipeline.java +++ b/pluggable-storage/src/main/java/pluggable/Pipeline.java @@ -4,6 +4,6 @@ public interface Pipeline { List exec() throws Exception; - void hIncrement(String key, String field, long value); + void hIncrement(String key, String field, long value) throws Exception; void getMembers(String key) throws Exception; }