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

FlagSetsFilter component #542

Merged
merged 8 commits into from
Sep 21, 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
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

import fake.HttpClientMock;
import fake.HttpResponseMock;
Expand Down Expand Up @@ -46,6 +48,7 @@ public class FlagSetsPollingTest {
private CountDownLatch secondChangeLatch;
private CountDownLatch thirdChangeLatch;
private SplitRoomDatabase mRoomDb;
private volatile String mSplitChangesUri;

@Before
public void setUp() throws Exception {
Expand Down Expand Up @@ -157,6 +160,18 @@ public void featureFlagSetsAreIgnoredWhenSetsAreNotConfigured() throws IOExcepti
assertTrue(awaitHits);
}

@Test
public void queryStringIsBuiltCorrectlyWhenSetsAreConfigured() throws IOException, InterruptedException {
createFactory(mContext, mRoomDb, "set_x", "set_x", "set_3", "set_2", "set_3", "set_ww", "invalid+");

boolean awaitFirst = firstChangeLatch.await(5, TimeUnit.SECONDS);

String uri = mSplitChangesUri;

assertTrue(awaitFirst);
assertEquals("https://sdk.split.io/api/splitChanges?since=-1&sets=set_2,set_3,set_ww,set_x", uri);
}

private SplitFactory createFactory(
Context mContext,
SplitRoomDatabase splitRoomDatabase,
Expand All @@ -169,6 +184,8 @@ private SplitFactory createFactory(
.impressionsCountersRefreshRate(1000)
.syncConfig(SyncConfig.builder()
.addSplitFilter(SplitFilter.bySet(Arrays.asList(sets)))
.addSplitFilter(SplitFilter.byName(Arrays.asList("workm", "workm_set_3"))) // added to test that this filter is ignored
.addSplitFilter(SplitFilter.byPrefix(Collections.singletonList("pref"))) // added to test that this filter is ignored
.build())
.featuresRefreshRate(2)
.streamingEnabled(false)
Expand All @@ -177,8 +194,8 @@ private SplitFactory createFactory(

Map<String, IntegrationHelper.ResponseClosure> responses = new HashMap<>();
responses.put("splitChanges", (uri, httpMethod, body) -> {
mSplitChangesUri = uri.toString();
String since = getSinceFromUri(uri);

hitsLatch.countDown();
if (since.equals("-1")) {
firstChangeLatch.countDown();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ class UserConsentModeDebugTest {
} else if (uri.path.contains("/splitChanges")) {
if (mChangeHit == 0) {
mChangeHit+=1
return getSplitsMockResponse("", "")
return getSplitsMockResponse("")
}
return HttpResponseMock(200, IntegrationHelper.emptySplitChanges(99999999, 99999999))
} else if (uri.path.contains("/testImpressions/bulk")) {
Expand Down Expand Up @@ -259,7 +259,7 @@ class UserConsentModeDebugTest {
}
}

private fun getSplitsMockResponse(since: String, till: String): HttpResponseMock {
private fun getSplitsMockResponse(since: String): HttpResponseMock {
return HttpResponseMock(200, loadSplitChanges())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ class UserConsentModeNoneTest {
} else if (uri.path.contains("/splitChanges")) {
if (mChangeHit == 0) {
mChangeHit+=1
return getSplitsMockResponse("", "")
return getSplitsMockResponse("")
}
return HttpResponseMock(200, IntegrationHelper.emptySplitChanges(99999999, 99999999))
} else if (uri.path.contains("/testImpressions/bulk")) {
Expand Down Expand Up @@ -260,7 +260,7 @@ class UserConsentModeNoneTest {
}
}

private fun getSplitsMockResponse(since: String, till: String): HttpResponseMock {
private fun getSplitsMockResponse(since: String): HttpResponseMock {
return HttpResponseMock(200, loadSplitChanges())
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ class UserConsentModeOptimizedTest {
} else if (uri.path.contains("/splitChanges")) {
if (mChangeHit == 0) {
mChangeHit+=1
return getSplitsMockResponse("", "")
return getSplitsMockResponse("")
}
return HttpResponseMock(200, IntegrationHelper.emptySplitChanges(99999999, 99999999))
} else if (uri.path.contains("/testImpressions/bulk")) {
Expand Down Expand Up @@ -270,7 +270,7 @@ class UserConsentModeOptimizedTest {
}
}

private fun getSplitsMockResponse(since: String, till: String): HttpResponseMock {
private fun getSplitsMockResponse(since: String): HttpResponseMock {
return HttpResponseMock(200, loadSplitChanges())
}

Expand Down
10 changes: 10 additions & 0 deletions src/main/java/io/split/android/client/FeatureFlagFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.split.android.client;

import java.util.Set;

interface FeatureFlagFilter {

boolean intersect(Set<String> values);

boolean intersect(String values);
}
6 changes: 6 additions & 0 deletions src/main/java/io/split/android/client/FlagSetsFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package io.split.android.client;

import java.util.Set;

public interface FlagSetsFilter extends FeatureFlagFilter {
}
48 changes: 48 additions & 0 deletions src/main/java/io/split/android/client/FlagSetsFilterImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.split.android.client;

import java.util.Collection;
import java.util.HashSet;
import java.util.Set;

public class FlagSetsFilterImpl implements FlagSetsFilter {

private final boolean mShouldFilter;
private final Set<String> mFlagSets;

public FlagSetsFilterImpl(Collection<String> flagSets) {
mFlagSets = new HashSet<>(flagSets);
mShouldFilter = !mFlagSets.isEmpty();
}

@Override
public boolean intersect(Set<String> sets) {
if (!mShouldFilter) {
return true;
}

if (sets == null) {
return false;
}

for (String set : sets) {
if (mFlagSets.contains(set)) {
return true;
}
}

return false;
}

@Override
public boolean intersect(String set) {
if (!mShouldFilter) {
return true;
}

if (set == null) {
return false;
}

return mFlagSets.contains(set);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import static com.google.common.base.Preconditions.checkNotNull;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.util.Set;

Expand Down Expand Up @@ -59,7 +60,7 @@ public SplitClientFactoryImpl(@NonNull SplitFactory splitFactory,
@NonNull KeyValidator keyValidator,
@NonNull EventsTracker eventsTracker,
@NonNull ImpressionListener customerImpressionListener,
@NonNull Set<String> configuredFlagSets) {
@Nullable FlagSetsFilter flagSetsFilter) {
mSplitFactory = checkNotNull(splitFactory);
mClientContainer = checkNotNull(clientContainer);
mConfig = checkNotNull(config);
Expand All @@ -85,7 +86,7 @@ public SplitClientFactoryImpl(@NonNull SplitFactory splitFactory,
new AttributesMergerImpl(),
mStorageContainer.getTelemetryStorage(),
mSplitParser,
configuredFlagSets,
flagSetsFilter,
splitsStorage
);
}
Expand Down
17 changes: 6 additions & 11 deletions src/main/java/io/split/android/client/SplitFactoryHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;

Expand Down Expand Up @@ -429,16 +427,13 @@ Pair<Map<SplitFilter.Type, SplitFilter>, String> getFilterConfiguration(SyncConf
return new Pair<>(groupedFilters, splitsFilterQueryString);
}

@NonNull
Set<String> getConfiguredFlagSets(Map<SplitFilter.Type, SplitFilter> filters) {
Set<String> configuredFlagSets;
SplitFilter flagSetSplitFilter = filters.get(SplitFilter.Type.BY_SET);
if (flagSetSplitFilter != null) {
configuredFlagSets = new HashSet<>(flagSetSplitFilter.getValues());
} else {
configuredFlagSets = new HashSet<>();
@Nullable
FlagSetsFilter getFlagSetsFilter(Map<SplitFilter.Type, SplitFilter> filters) {
if (filters.get(SplitFilter.Type.BY_SET) != null) {
return new FlagSetsFilterImpl(filters.get(SplitFilter.Type.BY_SET).getValues());
}
return configuredFlagSets;

return null;
}

private TelemetryStorage getTelemetryStorage(boolean shouldRecordTelemetry, TelemetryStorage telemetryStorage) {
Expand Down
8 changes: 4 additions & 4 deletions src/main/java/io/split/android/client/SplitFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,8 @@

import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import io.split.android.client.api.Key;
import io.split.android.client.common.CompressionUtilProvider;
Expand Down Expand Up @@ -180,9 +178,11 @@ public void taskExecuted(@NonNull SplitTaskExecutionInfo taskInfo) {
SplitApiFacade splitApiFacade = factoryHelper.buildApiFacade(
config, defaultHttpClient, splitsFilterQueryStringFromConfig);

FlagSetsFilter flagSetsFilter = factoryHelper.getFlagSetsFilter(filters);

SplitTaskFactory splitTaskFactory = new SplitTaskFactoryImpl(
config, splitApiFacade, mStorageContainer, splitsFilterQueryStringFromConfig, mEventsManagerCoordinator,
filters, testingConfig);
filters, flagSetsFilter, testingConfig);

cleanUpDabase(splitTaskExecutor, splitTaskFactory);
WorkManagerWrapper workManagerWrapper = factoryHelper.buildWorkManagerWrapper(context, config, apiToken, databaseName, filters);
Expand Down Expand Up @@ -270,7 +270,7 @@ public void taskExecuted(@NonNull SplitTaskExecutionInfo taskInfo) {
telemetrySynchronizer, mStorageContainer, splitTaskExecutor, splitApiFacade,
validationLogger, keyValidator, customerImpressionListener,
streamingComponents.getPushNotificationManager(), componentsRegister, workManagerWrapper,
eventsTracker, factoryHelper.getConfiguredFlagSets(filters));
eventsTracker, flagSetsFilter);
mDestroyer = new Runnable() {
public void run() {
Logger.w("Shutdown called for split");
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/io/split/android/client/SplitFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ public static SplitFilter bySet(@NonNull List<String> values) {

SplitFilter(Type type, List<String> values, SplitFilterValidator validator) {
mType = type;
SplitFilterValidator.ValidationResult validationResult = validator.cleanup(values);
SplitFilterValidator.ValidationResult validationResult = validator.cleanup("SDK config", values);
mValues = validationResult.getValues();
mInvalidValueCount = validationResult.getInvalidValueCount();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
import java.util.Map;
import java.util.Set;

import io.split.android.client.Evaluator;
import io.split.android.client.EvaluatorImpl;
import io.split.android.client.FlagSetsFilter;
import io.split.android.client.SplitClient;
import io.split.android.client.SplitClientConfig;
import io.split.android.client.SplitFactory;
Expand Down Expand Up @@ -61,7 +61,7 @@ public LocalhostSplitClient(@NonNull LocalhostSplitFactory container,
@NonNull AttributesManager attributesManager,
@NonNull AttributesMerger attributesMerger,
@NonNull TelemetryStorageProducer telemetryStorageProducer,
@NonNull Set<String> configuredFlagSets) {
@Nullable FlagSetsFilter flagSetsFilter) {

mFactoryRef = new WeakReference<>(checkNotNull(container));
mClientContainer = new WeakReference<>(checkNotNull(clientContainer));
Expand All @@ -72,7 +72,7 @@ public LocalhostSplitClient(@NonNull LocalhostSplitFactory container,
new EvaluatorImpl(splitsStorage, splitParser), new KeyValidatorImpl(),
new SplitValidatorImpl(), getImpressionsListener(splitClientConfig),
splitClientConfig.labelsEnabled(), eventsManager, attributesManager, attributesMerger,
telemetryStorageProducer, configuredFlagSets, splitsStorage);
telemetryStorageProducer, flagSetsFilter, splitsStorage);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
import java.util.Set;

import io.split.android.client.FilterBuilder;
import io.split.android.client.FlagSetsFilter;
import io.split.android.client.FlagSetsFilterImpl;
import io.split.android.client.SplitClient;
import io.split.android.client.SplitClientConfig;
import io.split.android.client.SplitFactory;
Expand Down Expand Up @@ -75,15 +77,15 @@ public LocalhostSplitFactory(String key, Context context,

mManager = new SplitManagerImpl(splitsStorage, new SplitValidatorImpl(), splitParser);

Set<String> configuredSets = new HashSet<>();
FlagSetsFilter flagSetsFilter = null;
if (config.syncConfig() != null) {
Map<SplitFilter.Type, SplitFilter> groupedFilters = new FilterBuilder(config.syncConfig().getFilters())
.getGroupedFilter();

if (!groupedFilters.isEmpty()) {
SplitFilter bySetFilter = groupedFilters.get(SplitFilter.Type.BY_SET);
if (bySetFilter != null) {
configuredSets.addAll(bySetFilter.getValues());
flagSetsFilter = new FlagSetsFilterImpl(bySetFilter.getValues());
}
}
}
Expand All @@ -97,7 +99,7 @@ public LocalhostSplitFactory(String key, Context context,
new NoOpTelemetryStorage(),
eventsManagerCoordinator,
taskExecutor,
configuredSets);
flagSetsFilter);

mSynchronizer = new LocalhostSynchronizer(taskExecutor, config, splitsStorage, buildQueryString(config.syncConfig()));
mSynchronizer.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -126,7 +127,7 @@ public void clear() {

@NonNull
@Override
public Set<String> getNamesByFlagSets(List<String> sets) {
public Set<String> getNamesByFlagSets(Collection<String> sets) {
Set<String> namesToReturn = new HashSet<>();
if (sets == null || sets.isEmpty()) {
return namesToReturn;
Expand Down
Loading