From 535f7b5633415ce8565c43cc3235894599218c2b Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Fri, 1 Sep 2023 12:53:18 -0300 Subject: [PATCH 1/3] Evaluation by sets in SplitClient interface --- .../io/split/android/client/SplitClient.java | 143 +++++++++++------- 1 file changed, 89 insertions(+), 54 deletions(-) diff --git a/src/main/java/io/split/android/client/SplitClient.java b/src/main/java/io/split/android/client/SplitClient.java index bd2fb1473..7214ffcc6 100644 --- a/src/main/java/io/split/android/client/SplitClient.java +++ b/src/main/java/io/split/android/client/SplitClient.java @@ -1,5 +1,8 @@ package io.split.android.client; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import java.util.List; import java.util.Map; @@ -50,8 +53,8 @@ public interface SplitClient extends AttributesManager { * vs. premium plan. Another example is to show a different treatment * to users created after a certain date. * - * @param featureFlagName the feature flag we want to evaluate. MUST NOT be null. - * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. + * @param featureFlagName the feature flag we want to evaluate. MUST NOT be null. + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. * @return the evaluated treatment, the default treatment of this feature flag, or 'control'. */ String getTreatment(String featureFlagName, Map attributes); @@ -67,10 +70,10 @@ public interface SplitClient extends AttributesManager { * vs. premium plan. Another example is to show a different treatment * to users created after a certain date. * - * @param featureFlagName the feature flag we want to evaluate. MUST NOT be null. - * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. + * @param featureFlagName the feature flag we want to evaluate. MUST NOT be null. + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. * @return the evaluated treatment, the default treatment of this feature flag, or 'control' - * with its corresponding configurations if it has one. + * with its corresponding configurations if it has one. */ SplitResult getTreatmentWithConfig(String featureFlagName, Map attributes); @@ -81,8 +84,8 @@ public interface SplitClient extends AttributesManager { *

* It can be used to cache treatments you know it won't change very often. * - * @param featureFlagNames the feature flags you want to evaluate. MUST NOT be null. - * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. + * @param featureFlagNames the feature flags you want to evaluate. MUST NOT be null. + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. * @return the evaluated treatments, the default treatment of a feature, or 'control'. */ Map getTreatments(List featureFlagNames, Map attributes); @@ -95,13 +98,53 @@ public interface SplitClient extends AttributesManager { *

* It can be used to cache treatments you know it won't change very often. * - * @param featureFlagNames the feature flags you want to evaluate. MUST NOT be null. - * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. + * @param featureFlagNames the feature flags you want to evaluate. MUST NOT be null. + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty. * @return the evaluated treatments, the default treatment of a feature flag, or 'control' * with its corresponding configurations if it has one. */ Map getTreatmentsWithConfig(List featureFlagNames, Map attributes); + /** + * This method is useful when you want to determine the treatment of several feature flags + * belonging to a specific Flag Set at the same time. + * + * @param flagSet the Flag Set name that you want to evaluate. Must not be null or empty + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty + * @return a {@link Map} containing for each feature flag the evaluated treatment, the default treatment of this feature flag, or 'control' + */ + Map getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map attributes); + + /** + * This method is useful when you want to determine the treatment of several feature flags + * belonging to a specific list of Flag Sets at the same time. + * + * @param flagSets the Flag Sets names that you want to evaluate. Must not be null or empty + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty + * @return a {@link Map} containing for each feature flag the evaluated treatment, the default treatment of this feature flag, or 'control' + */ + Map getTreatmentsByFlagSets(@NonNull List flagSets, @Nullable Map attributes); + + /** + * This method is useful when you want to determine the treatment of several feature flags + * belonging to a specific Flag Set + * + * @param flagSet the Flag Set name that you want to evaluate. Must not be null or empty + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty + * @return a {@link Map} containing for each feature flag the evaluated treatment, the default treatment of this feature flag, or 'control' + */ + Map getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map attributes); + + /** + * This method is useful when you want to determine the treatment of several feature flags + * belonging to a specific list of Flag Sets + * + * @param flagSets the Flag Sets names that you want to evaluate. Must not be null or empty + * @param attributes of the customer (user, account etc.) to use in evaluation. Can be null or empty + * @return a {@link Map} containing for each feature flag the evaluated treatment, the default treatment of this feature flag, or 'control' + */ + Map getTreatmentsWithConfigByFlagSets(@NonNull List flagSets, @Nullable Map attributes); + /** * Destroys the background processes and clears the cache, releasing the resources used by * any instances of SplitClient or SplitManager generated by the client's parent SplitFactory @@ -115,6 +158,7 @@ public interface SplitClient extends AttributesManager { /** * Checks if cached data is ready to perform treatment evaluations + * * @return true if the sdk is ready, if false, calls to getTreatment will return control */ boolean isReady(); @@ -123,118 +167,109 @@ public interface SplitClient extends AttributesManager { /** * Enqueue a new event to be sent to Split data collection services. - * + *

* The traffic type used is the one set by trafficType() in SplitClientConfig. - * + *

* Example: - * client.track(“checkout”) + * client.track(“checkout”) * * @param eventType the type of the event - * * @return true if the track was successful, false otherwise */ boolean track(String eventType); /** * Enqueue a new event to be sent to Split data collection services - * + *

* Example: - * client.track(“account”, “checkout”, 200.00) + * client.track(“account”, “checkout”, 200.00) * * @param trafficType the type of the event - * @param eventType the type of the event - * @param value the value 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 */ boolean track(String trafficType, String eventType, double value); /** * Enqueue a new event to be sent to Split data collection services - * + *

* Example: - * client.track(“account”, “checkout”) + * client.track(“account”, “checkout”) * * @param trafficType the type of the event - * @param eventType the type of the event - * + * @param eventType the type of the event * @return true if the track was successful, false otherwise */ boolean track(String trafficType, String eventType); /** * Enqueue a new event to be sent to Split data collection services - * + *

* The traffic type used is the one set by trafficType() in SplitClientConfig. - + *

* Example: - * client.track(“checkout”, 200.00) + * client.track(“checkout”, 200.00) * * @param eventType the type of the event - * @param value the value of the event - * + * @param value the value of the event * @return true if the track was successful, false otherwise */ boolean track(String eventType, double value); /** * Enqueue a new event to be sent to Split data collection services. - * + *

* The traffic type used is the one set by trafficType() in SplitClientConfig. - * + *

* Example: - * client.track(“checkout”) + * client.track(“checkout”) * - * @param eventType the type of the event + * @param eventType the type of the event * @param properties custom user data map - * * @return true if the track was successful, false otherwise */ - boolean track(String eventType, Map properties); + boolean track(String eventType, Map properties); /** * Enqueue a new event to be sent to Split data collection services - * + *

* Example: - * client.track(“account”, “checkout”, 200.00) + * client.track(“account”, “checkout”, 200.00) * * @param trafficType the type of the event - * @param eventType the type of the event - * @param value the value of the event - * @param properties custom user data map - * + * @param eventType the type of the event + * @param value the value of the event + * @param properties custom user data map * @return true if the track was successful, false otherwise */ - boolean track(String trafficType, String eventType, double value, Map properties); + boolean track(String trafficType, String eventType, double value, Map properties); /** * Enqueue a new event to be sent to split data collection services - * + *

* Example: - * client.track(“account”, “checkout”) + * client.track(“account”, “checkout”) * * @param trafficType the type of the event - * @param eventType the type of the event - * @param properties custom user data map - * + * @param eventType the type of the event + * @param properties custom user data map * @return true if the track was successful, false otherwise */ - boolean track(String trafficType, String eventType, Map properties); + boolean track(String trafficType, String eventType, Map properties); /** * Enqueue a new event to be sent to Split data collection services - * + *

* The traffic type used is the one set by trafficType() in SplitClientConfig. - + *

* Example: - * client.track(“checkout”, 200.00) + * client.track(“checkout”, 200.00) * - * @param eventType the type of the event - * @param value the value of the event + * @param eventType the type of the event + * @param value the value of the event * @param properties custom user data map - * * @return true if the track was successful, false otherwise */ - boolean track(String eventType, double value, Map properties); - + boolean track(String eventType, double value, Map properties); } From 0ae7326ba180bce6e618378f526f56d809eac4fc Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Fri, 1 Sep 2023 15:31:39 -0300 Subject: [PATCH 2/3] Setup for new client methods --- .../java/fake/SplitClientStub.java | 20 +++++++++++ .../AlwaysReturnControlSplitClient.java | 24 +++++++++++-- .../split/android/client/FilterBuilder.java | 2 +- .../client/SplitClientFactoryImpl.java | 8 +++-- .../split/android/client/SplitClientImpl.java | 36 +++++++++++++++++++ .../android/client/SplitFactoryImpl.java | 2 +- .../localhost/LocalhostSplitClient.java | 26 ++++++++++++-- .../localhost/LocalhostSplitFactory.java | 18 +++++++++- .../LocalhostSplitClientContainerImpl.java | 10 ++++-- .../shared/SplitClientContainerImpl.java | 7 ++-- .../TreatmentManagerFactoryImpl.java | 11 ++++-- .../validators/TreatmentManagerImpl.java | 6 +++- .../client/TreatmentManagerTelemetryTest.java | 7 ++-- .../android/client/TreatmentManagerTest.java | 9 ++--- ...LocalhostSplitClientContainerImplTest.java | 15 +++++++- .../client/utils/SplitClientImplFactory.java | 12 +++---- 16 files changed, 182 insertions(+), 31 deletions(-) diff --git a/src/androidTest/java/fake/SplitClientStub.java b/src/androidTest/java/fake/SplitClientStub.java index b20df3182..d500ef366 100644 --- a/src/androidTest/java/fake/SplitClientStub.java +++ b/src/androidTest/java/fake/SplitClientStub.java @@ -38,6 +38,26 @@ public Map getTreatmentsWithConfig(List featureFlag return null; } + @Override + public Map getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + return null; + } + + @Override + public Map getTreatmentsByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + return null; + } + + @Override + public Map getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + return null; + } + + @Override + public Map getTreatmentsWithConfigByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + return null; + } + @Override public void destroy() { diff --git a/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java b/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java index 70b6356f2..8ec6576f8 100644 --- a/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java +++ b/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java @@ -6,6 +6,8 @@ import io.split.android.client.events.SplitEvent; import io.split.android.client.events.SplitEventTask; import io.split.android.grammar.Treatments; + +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -58,6 +60,26 @@ public SplitResult getTreatmentWithConfig(String featureFlagName, Map getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + return Collections.singletonMap(flagSet, Treatments.CONTROL); //TODO + } + + @Override + public Map getTreatmentsByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + return Collections.singletonMap(flagSets.get(0), Treatments.CONTROL); //TODO + } + + @Override + public Map getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + return Collections.singletonMap(flagSet, new SplitResult(Treatments.CONTROL)); //TODO + } + + @Override + public Map getTreatmentsWithConfigByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + return Collections.singletonMap(flagSets.get(0), new SplitResult(Treatments.CONTROL)); //TODO + } + @Override public boolean setAttribute(String attributeName, Object value) { return true; @@ -149,6 +171,4 @@ public boolean track(String eventType, Map properties) { public boolean track(String eventType, double value, Map properties) { return false; } - - } diff --git a/src/main/java/io/split/android/client/FilterBuilder.java b/src/main/java/io/split/android/client/FilterBuilder.java index 2892d0a42..335fcb841 100644 --- a/src/main/java/io/split/android/client/FilterBuilder.java +++ b/src/main/java/io/split/android/client/FilterBuilder.java @@ -63,7 +63,7 @@ public String buildQueryString() { } @NonNull - public ArrayList getGroupedFilter() { + public List getGroupedFilter() { return new ArrayList<>(mFilterGrouper.group(mFilters)); } diff --git a/src/main/java/io/split/android/client/SplitClientFactoryImpl.java b/src/main/java/io/split/android/client/SplitClientFactoryImpl.java index ea104754e..eb03d36b2 100644 --- a/src/main/java/io/split/android/client/SplitClientFactoryImpl.java +++ b/src/main/java/io/split/android/client/SplitClientFactoryImpl.java @@ -4,6 +4,8 @@ import androidx.annotation.NonNull; +import java.util.Set; + import io.split.android.client.api.Key; import io.split.android.client.attributes.AttributesManagerFactory; import io.split.android.client.attributes.AttributesManagerFactoryImpl; @@ -55,7 +57,8 @@ public SplitClientFactoryImpl(@NonNull SplitFactory splitFactory, @NonNull ValidationMessageLogger validationLogger, @NonNull KeyValidator keyValidator, @NonNull EventsTracker eventsTracker, - @NonNull ImpressionListener customerImpressionListener) { + @NonNull ImpressionListener customerImpressionListener, + @NonNull Set configuredFlagSets) { mSplitFactory = checkNotNull(splitFactory); mClientContainer = checkNotNull(clientContainer); mConfig = checkNotNull(config); @@ -79,7 +82,8 @@ public SplitClientFactoryImpl(@NonNull SplitFactory splitFactory, config.labelsEnabled(), new AttributesMergerImpl(), mStorageContainer.getTelemetryStorage(), - new EvaluatorImpl(mStorageContainer.getSplitsStorage(), mSplitParser) + new EvaluatorImpl(mStorageContainer.getSplitsStorage(), mSplitParser), + configuredFlagSets ); } diff --git a/src/main/java/io/split/android/client/SplitClientImpl.java b/src/main/java/io/split/android/client/SplitClientImpl.java index 00f4feaf7..08bbabd76 100644 --- a/src/main/java/io/split/android/client/SplitClientImpl.java +++ b/src/main/java/io/split/android/client/SplitClientImpl.java @@ -188,6 +188,42 @@ public Map getTreatmentsWithConfig(List featureFlag } } + @Override + public Map getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + try { + return Collections.emptyMap(); //TODO + } catch (Exception exception) { + return null; + } + } + + @Override + public Map getTreatmentsByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + try { + return Collections.emptyMap(); //TODO + } catch (Exception exception) { + return null; + } + } + + @Override + public Map getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + try { + return Collections.emptyMap(); //TODO + } catch (Exception exception) { + return null; + } + } + + @Override + public Map getTreatmentsWithConfigByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + try { + return Collections.emptyMap(); //TODO + } catch (Exception exception) { + return null; + } + } + public void on(SplitEvent event, SplitEventTask task) { checkNotNull(event); checkNotNull(task); diff --git a/src/main/java/io/split/android/client/SplitFactoryImpl.java b/src/main/java/io/split/android/client/SplitFactoryImpl.java index e693aca8d..a6404513a 100644 --- a/src/main/java/io/split/android/client/SplitFactoryImpl.java +++ b/src/main/java/io/split/android/client/SplitFactoryImpl.java @@ -269,7 +269,7 @@ public void taskExecuted(@NonNull SplitTaskExecutionInfo taskInfo) { telemetrySynchronizer, mStorageContainer, splitTaskExecutor, splitApiFacade, validationLogger, keyValidator, customerImpressionListener, streamingComponents.getPushNotificationManager(), componentsRegister, workManagerWrapper, - eventsTracker); + eventsTracker, configuredFlagSets); mDestroyer = new Runnable() { public void run() { Logger.w("Shutdown called for split"); diff --git a/src/main/java/io/split/android/client/localhost/LocalhostSplitClient.java b/src/main/java/io/split/android/client/localhost/LocalhostSplitClient.java index 4023e0060..d01393122 100644 --- a/src/main/java/io/split/android/client/localhost/LocalhostSplitClient.java +++ b/src/main/java/io/split/android/client/localhost/LocalhostSplitClient.java @@ -9,6 +9,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import io.split.android.client.Evaluator; import io.split.android.client.EvaluatorImpl; @@ -58,7 +59,8 @@ public LocalhostSplitClient(@NonNull LocalhostSplitFactory container, @NonNull SplitParser splitParser, @NonNull AttributesManager attributesManager, @NonNull AttributesMerger attributesMerger, - @NonNull TelemetryStorageProducer telemetryStorageProducer) { + @NonNull TelemetryStorageProducer telemetryStorageProducer, + @NonNull Set configuredFlagSets) { mFactoryRef = new WeakReference<>(checkNotNull(container)); mClientContainer = new WeakReference<>(checkNotNull(clientContainer)); @@ -68,7 +70,7 @@ public LocalhostSplitClient(@NonNull LocalhostSplitFactory container, mTreatmentManager = new TreatmentManagerImpl(mKey.matchingKey(), mKey.bucketingKey(), mEvaluator, new KeyValidatorImpl(), new SplitValidatorImpl(), getImpressionsListener(splitClientConfig), - splitClientConfig.labelsEnabled(), eventsManager, attributesManager, attributesMerger, telemetryStorageProducer); + splitClientConfig.labelsEnabled(), eventsManager, attributesManager, attributesMerger, telemetryStorageProducer, configuredFlagSets); } @Override @@ -138,6 +140,26 @@ public Map getTreatmentsWithConfig(List featureFlag } } + @Override + public Map getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + return null; + } + + @Override + public Map getTreatmentsByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + return null; + } + + @Override + public Map getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { + return null; + } + + @Override + public Map getTreatmentsWithConfigByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { + return null; + } + @Override public void destroy() { mIsClientDestroyed = true; diff --git a/src/main/java/io/split/android/client/localhost/LocalhostSplitFactory.java b/src/main/java/io/split/android/client/localhost/LocalhostSplitFactory.java index ba942771c..e0ece35ca 100644 --- a/src/main/java/io/split/android/client/localhost/LocalhostSplitFactory.java +++ b/src/main/java/io/split/android/client/localhost/LocalhostSplitFactory.java @@ -6,11 +6,16 @@ import androidx.annotation.VisibleForTesting; import java.io.IOException; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; import io.split.android.client.FilterBuilder; import io.split.android.client.SplitClient; import io.split.android.client.SplitClientConfig; import io.split.android.client.SplitFactory; +import io.split.android.client.SplitFilter; import io.split.android.client.SplitManager; import io.split.android.client.SplitManagerImpl; import io.split.android.client.SyncConfig; @@ -69,6 +74,16 @@ public LocalhostSplitFactory(String key, Context context, mManager = new SplitManagerImpl(splitsStorage, new SplitValidatorImpl(), splitParser); + Set configuredSets = new HashSet<>(); + if (config.syncConfig() != null) { + List groupedFilters = new FilterBuilder(config.syncConfig().getFilters()) + .getGroupedFilter(); + + if (!groupedFilters.isEmpty() && groupedFilters.get(0).getType() == SplitFilter.Type.BY_SET) { + configuredSets.addAll(groupedFilters.get(0).getValues()); + } + } + mClientContainer = new LocalhostSplitClientContainerImpl(this, config, splitsStorage, @@ -77,7 +92,8 @@ public LocalhostSplitFactory(String key, Context context, new AttributesMergerImpl(), new NoOpTelemetryStorage(), eventsManagerCoordinator, - taskExecutor); + taskExecutor, + configuredSets); mSynchronizer = new LocalhostSynchronizer(taskExecutor, config, splitsStorage, buildQueryString(config.syncConfig())); mSynchronizer.start(); diff --git a/src/main/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImpl.java b/src/main/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImpl.java index ba9775e37..e4a6d2a69 100644 --- a/src/main/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImpl.java +++ b/src/main/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImpl.java @@ -1,5 +1,7 @@ package io.split.android.client.localhost.shared; +import java.util.Set; + import io.split.android.client.SplitClient; import io.split.android.client.SplitClientConfig; import io.split.android.client.api.Key; @@ -29,6 +31,7 @@ public class LocalhostSplitClientContainerImpl extends BaseSplitClientContainer private final TelemetryStorageProducer mTelemetryStorageProducer; private final EventsManagerCoordinator mEventsManagerCoordinator; private final SplitTaskExecutor mSplitTaskExecutor; + private final Set mConfiguredSets; public LocalhostSplitClientContainerImpl(LocalhostSplitFactory splitFactory, SplitClientConfig config, @@ -38,7 +41,8 @@ public LocalhostSplitClientContainerImpl(LocalhostSplitFactory splitFactory, AttributesMerger attributesMerger, TelemetryStorageProducer telemetryStorageProducer, EventsManagerCoordinator eventsManagerCoordinator, - SplitTaskExecutor taskExecutor) { + SplitTaskExecutor taskExecutor, + Set configuredSets) { mSplitFactory = splitFactory; mConfig = config; mSplitStorage = splitsStorage; @@ -48,6 +52,7 @@ public LocalhostSplitClientContainerImpl(LocalhostSplitFactory splitFactory, mTelemetryStorageProducer = telemetryStorageProducer; mEventsManagerCoordinator = eventsManagerCoordinator; mSplitTaskExecutor = taskExecutor; + mConfiguredSets = configuredSets; } @Override @@ -70,7 +75,8 @@ protected void createNewClient(Key key) { mSplitParser, attributesManager, mAttributesMerger, - mTelemetryStorageProducer + mTelemetryStorageProducer, + mConfiguredSets ); eventsManager.getExecutorResources().setSplitClient(client); diff --git a/src/main/java/io/split/android/client/shared/SplitClientContainerImpl.java b/src/main/java/io/split/android/client/shared/SplitClientContainerImpl.java index 742c85c68..a23d5e73c 100644 --- a/src/main/java/io/split/android/client/shared/SplitClientContainerImpl.java +++ b/src/main/java/io/split/android/client/shared/SplitClientContainerImpl.java @@ -6,6 +6,7 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import java.util.Set; import java.util.concurrent.atomic.AtomicBoolean; import io.split.android.client.EventsTracker; @@ -70,7 +71,8 @@ public SplitClientContainerImpl(@NonNull String defaultMatchingKey, @Nullable PushNotificationManager pushNotificationManager, @NonNull ClientComponentsRegister clientComponentsRegister, @NonNull MySegmentsWorkManagerWrapper workManagerWrapper, - @NonNull EventsTracker eventsTracker) { + @NonNull EventsTracker eventsTracker, + @NonNull Set configuredFlagSets) { mDefaultMatchingKey = checkNotNull(defaultMatchingKey); mPushNotificationManager = pushNotificationManager; mStreamingEnabled = config.streamingEnabled(); @@ -88,7 +90,8 @@ public SplitClientContainerImpl(@NonNull String defaultMatchingKey, validationLogger, keyValidator, eventsTracker, - customerImpressionListener + customerImpressionListener, + configuredFlagSets ); mClientComponentsRegister = checkNotNull(clientComponentsRegister); mSplitTaskExecutor = checkNotNull(splitTaskExecutor); diff --git a/src/main/java/io/split/android/client/validators/TreatmentManagerFactoryImpl.java b/src/main/java/io/split/android/client/validators/TreatmentManagerFactoryImpl.java index be6309fb0..ce95d1441 100644 --- a/src/main/java/io/split/android/client/validators/TreatmentManagerFactoryImpl.java +++ b/src/main/java/io/split/android/client/validators/TreatmentManagerFactoryImpl.java @@ -4,11 +4,12 @@ import androidx.annotation.NonNull; +import java.util.Set; + import io.split.android.client.Evaluator; import io.split.android.client.api.Key; import io.split.android.client.attributes.AttributesManager; import io.split.android.client.attributes.AttributesMerger; -import io.split.android.client.events.ISplitEventsManager; import io.split.android.client.events.ListenableEventsManager; import io.split.android.client.impressions.ImpressionListener; import io.split.android.client.telemetry.storage.TelemetryStorageProducer; @@ -22,6 +23,7 @@ public class TreatmentManagerFactoryImpl implements TreatmentManagerFactory { private final AttributesMerger mAttributesMerger; private final TelemetryStorageProducer mTelemetryStorageProducer; private final Evaluator mEvaluator; + private final Set mConfiguredFlagSets; public TreatmentManagerFactoryImpl(@NonNull KeyValidator keyValidator, @NonNull SplitValidator splitValidator, @@ -29,7 +31,8 @@ public TreatmentManagerFactoryImpl(@NonNull KeyValidator keyValidator, boolean labelsEnabled, @NonNull AttributesMerger attributesMerger, @NonNull TelemetryStorageProducer telemetryStorageProducer, - @NonNull Evaluator evaluator) { + @NonNull Evaluator evaluator, + @NonNull Set configuredFlagSets) { mKeyValidator = checkNotNull(keyValidator); mSplitValidator = checkNotNull(splitValidator); mCustomerImpressionListener = checkNotNull(customerImpressionListener); @@ -37,6 +40,7 @@ public TreatmentManagerFactoryImpl(@NonNull KeyValidator keyValidator, mAttributesMerger = checkNotNull(attributesMerger); mTelemetryStorageProducer = checkNotNull(telemetryStorageProducer); mEvaluator = checkNotNull(evaluator); + mConfiguredFlagSets = configuredFlagSets; } @Override @@ -52,7 +56,8 @@ public TreatmentManager getTreatmentManager(Key key, ListenableEventsManager eve eventsManager, attributesManager, mAttributesMerger, - mTelemetryStorageProducer + mTelemetryStorageProducer, + mConfiguredFlagSets ); } } diff --git a/src/main/java/io/split/android/client/validators/TreatmentManagerImpl.java b/src/main/java/io/split/android/client/validators/TreatmentManagerImpl.java index 8cc4b55b4..ae52d9377 100644 --- a/src/main/java/io/split/android/client/validators/TreatmentManagerImpl.java +++ b/src/main/java/io/split/android/client/validators/TreatmentManagerImpl.java @@ -7,6 +7,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import io.split.android.client.EvaluationResult; import io.split.android.client.Evaluator; @@ -48,6 +49,7 @@ private static class ValidationTag { @NonNull private final AttributesMerger mAttributesMerger; private final TelemetryStorageProducer mTelemetryStorageProducer; + private final Set mConfiguredFlagSets; public TreatmentManagerImpl(String matchingKey, String bucketingKey, @@ -59,7 +61,8 @@ public TreatmentManagerImpl(String matchingKey, ListenableEventsManager eventsManager, @NonNull AttributesManager attributesManager, @NonNull AttributesMerger attributesMerger, - @NonNull TelemetryStorageProducer telemetryStorageProducer) { + @NonNull TelemetryStorageProducer telemetryStorageProducer, + @NonNull Set configuredFlagSets) { mEvaluator = evaluator; mKeyValidator = keyValidator; mSplitValidator = splitValidator; @@ -72,6 +75,7 @@ public TreatmentManagerImpl(String matchingKey, mAttributesManager = checkNotNull(attributesManager); mAttributesMerger = checkNotNull(attributesMerger); mTelemetryStorageProducer = checkNotNull(telemetryStorageProducer); + mConfiguredFlagSets = checkNotNull(configuredFlagSets); } @Override diff --git a/src/test/java/io/split/android/client/TreatmentManagerTelemetryTest.java b/src/test/java/io/split/android/client/TreatmentManagerTelemetryTest.java index 86b8230d0..b93f59aa2 100644 --- a/src/test/java/io/split/android/client/TreatmentManagerTelemetryTest.java +++ b/src/test/java/io/split/android/client/TreatmentManagerTelemetryTest.java @@ -15,6 +15,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; import io.split.android.client.attributes.AttributesManager; import io.split.android.client.attributes.AttributesMerger; @@ -46,6 +48,7 @@ public class TreatmentManagerTelemetryTest { @Mock TelemetryStorageProducer telemetryStorageProducer; + private Set mConfiguredFlagSets = new HashSet<>(); private TreatmentManagerImpl treatmentManager; @Before @@ -63,8 +66,8 @@ public void setUp() { eventsManager, attributesManager, attributesMerger, - telemetryStorageProducer - ); + telemetryStorageProducer, + mConfiguredFlagSets); when(evaluator.getTreatment(anyString(), anyString(), anyString(), anyMap())).thenReturn(new EvaluationResult("test", "label")); } diff --git a/src/test/java/io/split/android/client/TreatmentManagerTest.java b/src/test/java/io/split/android/client/TreatmentManagerTest.java index 02ab324e9..43959f5d6 100644 --- a/src/test/java/io/split/android/client/TreatmentManagerTest.java +++ b/src/test/java/io/split/android/client/TreatmentManagerTest.java @@ -28,7 +28,6 @@ import io.split.android.client.attributes.AttributesManager; import io.split.android.client.attributes.AttributesMerger; import io.split.android.client.dtos.Split; -import io.split.android.client.events.ISplitEventsManager; import io.split.android.client.events.ListenableEventsManager; import io.split.android.client.events.SplitEvent; import io.split.android.client.impressions.ImpressionListener; @@ -56,10 +55,12 @@ public class TreatmentManagerTest { ListenableEventsManager eventsManagerStub; AttributesManager attributesManager = mock(AttributesManager.class); TelemetryStorageProducer telemetryStorageProducer = mock(TelemetryStorageProducer.class); + private Set mConfiguredFlagSets; TreatmentManagerImpl treatmentManager = initializeTreatmentManager(); @Before public void loadSplitsFromFile() { + mConfiguredFlagSets = new HashSet<>(); if (evaluator == null) { FileHelper fileHelper = new FileHelper(); MySegmentsStorageContainer mySegmentsStorageContainer = mock(MySegmentsStorageContainer.class); @@ -320,7 +321,7 @@ private TreatmentManager createTreatmentManager(String matchingKey, String bucke return new TreatmentManagerImpl( matchingKey, bucketingKey, evaluator, new KeyValidatorImpl(), new SplitValidatorImpl(), - new ImpressionListenerMock(), config.labelsEnabled(), eventsManagerStub, mock(AttributesManager.class), mock(AttributesMerger.class), mock(TelemetryStorageProducer.class)); + new ImpressionListenerMock(), config.labelsEnabled(), eventsManagerStub, mock(AttributesManager.class), mock(AttributesMerger.class), mock(TelemetryStorageProducer.class), mConfiguredFlagSets); } private TreatmentManagerImpl initializeTreatmentManager() { @@ -347,8 +348,8 @@ private TreatmentManagerImpl initializeTreatmentManager(Evaluator evaluator) { eventsManager, attributesManager, mock(AttributesMerger.class), - telemetryStorageProducer - ); + telemetryStorageProducer, + mConfiguredFlagSets); } private Map splitsMap(List splits) { diff --git a/src/test/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImplTest.java b/src/test/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImplTest.java index 7a557cfff..9d855de66 100644 --- a/src/test/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImplTest.java +++ b/src/test/java/io/split/android/client/localhost/shared/LocalhostSplitClientContainerImplTest.java @@ -16,6 +16,8 @@ import org.mockito.MockitoAnnotations; import java.util.Collection; +import java.util.HashSet; +import java.util.Set; import io.split.android.client.SplitClient; import io.split.android.client.SplitClientConfig; @@ -50,12 +52,14 @@ public class LocalhostSplitClientContainerImplTest { private SplitClientConfig mConfig; @Mock private SplitTaskExecutor mTaskExecutor; + private Set mConfiguredSets; private LocalhostSplitClientContainerImpl mClientContainer; @Before public void setUp() { MockitoAnnotations.openMocks(this); when(mAttributesManagerFactory.getManager(any(), any())).thenReturn(mock(AttributesManager.class)); + mConfiguredSets = new HashSet<>(); mClientContainer = getClientContainer(); } @@ -95,6 +99,15 @@ public void gettingNewClientRegistersEventManager() { @NonNull private LocalhostSplitClientContainerImpl getClientContainer() { - return new LocalhostSplitClientContainerImpl(mFactory, mConfig, mSplitsStorage, mSplitParser, mAttributesManagerFactory, mAttributesMerger, mTelemetryStorageProducer, mEventsManagerCoordinator, mTaskExecutor); + return new LocalhostSplitClientContainerImpl(mFactory, + mConfig, + mSplitsStorage, + mSplitParser, + mAttributesManagerFactory, + mAttributesMerger, + mTelemetryStorageProducer, + mEventsManagerCoordinator, + mTaskExecutor, + mConfiguredSets); } } diff --git a/src/test/java/io/split/android/client/utils/SplitClientImplFactory.java b/src/test/java/io/split/android/client/utils/SplitClientImplFactory.java index ad91b25a0..3a8cb6388 100644 --- a/src/test/java/io/split/android/client/utils/SplitClientImplFactory.java +++ b/src/test/java/io/split/android/client/utils/SplitClientImplFactory.java @@ -2,6 +2,8 @@ import static org.mockito.Mockito.mock; +import java.util.Collections; + import io.split.android.client.EvaluatorImpl; import io.split.android.client.EventsTracker; import io.split.android.client.SplitClientConfig; @@ -13,7 +15,6 @@ import io.split.android.client.events.SplitEventsManager; import io.split.android.client.events.SplitInternalEvent; import io.split.android.client.impressions.ImpressionListener; -import io.split.android.client.service.synchronizer.SyncManager; import io.split.android.client.shared.SplitClientContainer; import io.split.android.client.storage.mysegments.MySegmentsStorageContainer; import io.split.android.client.storage.splits.SplitsStorage; @@ -27,10 +28,7 @@ import io.split.android.engine.experiments.SplitParser; import io.split.android.fake.SplitTaskExecutorStub; -/** - * Created by fernandomartin on 2/17/18. - */ - +@Deprecated public class SplitClientImplFactory { public static SplitClientImpl get(Key key, SplitsStorage splitsStorage) { @@ -40,8 +38,8 @@ public static SplitClientImpl get(Key key, SplitsStorage splitsStorage) { TelemetryStorage telemetryStorage = mock(TelemetryStorage.class); TreatmentManagerFactory treatmentManagerFactory = new TreatmentManagerFactoryImpl( new KeyValidatorImpl(), new SplitValidatorImpl(), new ImpressionListener.NoopImpressionListener(), - false, new AttributesMergerImpl(), telemetryStorage, new EvaluatorImpl(splitsStorage, splitParser) - ); + false, new AttributesMergerImpl(), telemetryStorage, new EvaluatorImpl(splitsStorage, splitParser), + Collections.emptySet()); AttributesManager attributesManager = mock(AttributesManager.class); SplitClientImpl c = new SplitClientImpl( From b2cf6882625fb110edad8d785242012f8e17289c Mon Sep 17 00:00:00 2001 From: Gaston Thea Date: Fri, 1 Sep 2023 15:42:57 -0300 Subject: [PATCH 3/3] Fixes --- .../android/client/AlwaysReturnControlSplitClient.java | 8 ++++---- .../io/split/android/client/SplitClientFactoryImpl.java | 2 +- .../io/split/android/client/TreatmentManagerTest.java | 3 ++- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java b/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java index 8ec6576f8..59a8ddca4 100644 --- a/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java +++ b/src/main/java/io/split/android/client/AlwaysReturnControlSplitClient.java @@ -62,22 +62,22 @@ public SplitResult getTreatmentWithConfig(String featureFlagName, Map getTreatmentsByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { - return Collections.singletonMap(flagSet, Treatments.CONTROL); //TODO + return Collections.emptyMap(); //TODO } @Override public Map getTreatmentsByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { - return Collections.singletonMap(flagSets.get(0), Treatments.CONTROL); //TODO + return Collections.emptyMap(); //TODO } @Override public Map getTreatmentsWithConfigByFlagSet(@NonNull String flagSet, @Nullable Map attributes) { - return Collections.singletonMap(flagSet, new SplitResult(Treatments.CONTROL)); //TODO + return Collections.emptyMap(); //TODO } @Override public Map getTreatmentsWithConfigByFlagSets(@NonNull List flagSets, @Nullable Map attributes) { - return Collections.singletonMap(flagSets.get(0), new SplitResult(Treatments.CONTROL)); //TODO + return Collections.emptyMap(); //TODO } @Override diff --git a/src/main/java/io/split/android/client/SplitClientFactoryImpl.java b/src/main/java/io/split/android/client/SplitClientFactoryImpl.java index eb03d36b2..22a4195d6 100644 --- a/src/main/java/io/split/android/client/SplitClientFactoryImpl.java +++ b/src/main/java/io/split/android/client/SplitClientFactoryImpl.java @@ -83,7 +83,7 @@ public SplitClientFactoryImpl(@NonNull SplitFactory splitFactory, new AttributesMergerImpl(), mStorageContainer.getTelemetryStorage(), new EvaluatorImpl(mStorageContainer.getSplitsStorage(), mSplitParser), - configuredFlagSets + checkNotNull(configuredFlagSets) ); } diff --git a/src/test/java/io/split/android/client/TreatmentManagerTest.java b/src/test/java/io/split/android/client/TreatmentManagerTest.java index 43959f5d6..d1e8794a1 100644 --- a/src/test/java/io/split/android/client/TreatmentManagerTest.java +++ b/src/test/java/io/split/android/client/TreatmentManagerTest.java @@ -56,11 +56,12 @@ public class TreatmentManagerTest { AttributesManager attributesManager = mock(AttributesManager.class); TelemetryStorageProducer telemetryStorageProducer = mock(TelemetryStorageProducer.class); private Set mConfiguredFlagSets; - TreatmentManagerImpl treatmentManager = initializeTreatmentManager(); + TreatmentManagerImpl treatmentManager; @Before public void loadSplitsFromFile() { mConfiguredFlagSets = new HashSet<>(); + treatmentManager = initializeTreatmentManager(); if (evaluator == null) { FileHelper fileHelper = new FileHelper(); MySegmentsStorageContainer mySegmentsStorageContainer = mock(MySegmentsStorageContainer.class);