Skip to content

Commit

Permalink
Sets config telemetry (#535)
Browse files Browse the repository at this point in the history
  • Loading branch information
gthea authored Sep 7, 2023
2 parents bb66c9f + c9662a3 commit eafcc26
Show file tree
Hide file tree
Showing 12 changed files with 143 additions and 56 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,7 @@ Pair<Pair<List<SplitFilter>, String>, Set<String>> getFilterConfiguration(SyncCo
SplitFilter splitFilter = groupedFilters.get(0);

// In the case of BY_SET, all filters will be grouped into one with the {@link SplitFilter.Type#BY_SET} type
if (splitFilter.getType() == SplitFilter.Type.BY_SET) {
if (splitFilter != null && splitFilter.getType() == SplitFilter.Type.BY_SET) {
configuredFlagSets.addAll(splitFilter.getValues());
}
}
Expand Down
11 changes: 9 additions & 2 deletions src/main/java/io/split/android/client/SplitFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public int maxValuesCount() {

private final SplitFilter.Type mType;
private final List<String> mValues;
private int mInvalidValueCount;

public static SplitFilter byName(@NonNull List<String> values) {
return new SplitFilter(Type.BY_NAME, values);
Expand All @@ -74,7 +75,7 @@ public static SplitFilter bySet(@NonNull List<String> values) {
}

// This constructor is not private (but default) to allow Split Sync Config builder be agnostic when creating filters
// Also is not public to force SDK users to use static functions "byName" and "byPrefix"
// Also is not public to force SDK users to use static functions "byName", "byPrefix", "bySet"
SplitFilter(Type type, List<String> values) {
if (values == null) {
throw new IllegalArgumentException("Values can't be null for " + type.toString() + " filter");
Expand All @@ -85,7 +86,9 @@ public static SplitFilter bySet(@NonNull List<String> values) {

SplitFilter(Type type, List<String> values, SplitFilterValidator validator) {
mType = type;
mValues = validator.cleanup(values);
SplitFilterValidator.ValidationResult validationResult = validator.cleanup(values);
mValues = validationResult.getValues();
mInvalidValueCount = validationResult.getInvalidValueCount();
}

public Type getType() {
Expand All @@ -95,4 +98,8 @@ public Type getType() {
public List<String> getValues() {
return mValues;
}

public int getInvalidValueCount() {
return mInvalidValueCount;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public LocalhostSplitFactory(String key, Context context,
List<SplitFilter> groupedFilters = new FilterBuilder(config.syncConfig().getFilters())
.getGroupedFilter();

if (!groupedFilters.isEmpty() && groupedFilters.get(0).getType() == SplitFilter.Type.BY_SET) {
if (!groupedFilters.isEmpty() && groupedFilters.get(0) != null && groupedFilters.get(0).getType() == SplitFilter.Type.BY_SET) {
configuredSets.addAll(groupedFilters.get(0).getValues());
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,23 @@ public SplitTaskFactoryImpl(@NonNull SplitClientConfig splitClientConfig,
mTelemetryRuntimeProducer);
}

mFilters = (filters == null) ? new ArrayList<>() : filters;

int flagSetCount = 0;
int invalidFlagSetCount = 0;
if (!mFilters.isEmpty() && mFilters.get(0) != null && mFilters.get(0).getType() == SplitFilter.Type.BY_SET) {
flagSetCount = mFilters.get(0).getValues().size();
invalidFlagSetCount = mFilters.get(0).getInvalidValueCount();
}

mTelemetryTaskFactory = new TelemetryTaskFactoryImpl(mSplitApiFacade.getTelemetryConfigRecorder(),
mSplitApiFacade.getTelemetryStatsRecorder(),
telemetryStorage,
splitClientConfig,
mSplitsStorageContainer.getSplitsStorage(),
mSplitsStorageContainer.getMySegmentsStorageContainer());

mFilters = (filters == null) ? new ArrayList<>() : filters;
mSplitsStorageContainer.getMySegmentsStorageContainer(),
flagSetCount,
invalidFlagSetCount);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@

import androidx.annotation.NonNull;

import java.util.List;

import io.split.android.client.SplitClientConfig;
import io.split.android.client.SplitFilter;
import io.split.android.client.service.http.HttpRecorder;
import io.split.android.client.storage.mysegments.MySegmentsStorage;
import io.split.android.client.storage.mysegments.MySegmentsStorageContainer;
import io.split.android.client.storage.splits.SplitsStorage;
import io.split.android.client.telemetry.model.Config;
Expand All @@ -15,7 +17,6 @@
import io.split.android.client.telemetry.storage.TelemetryStatsProvider;
import io.split.android.client.telemetry.storage.TelemetryStatsProviderImpl;
import io.split.android.client.telemetry.storage.TelemetryStorage;
import io.split.android.client.telemetry.storage.TelemetryStorageConsumer;

public class TelemetryTaskFactoryImpl implements TelemetryTaskFactory {

Expand All @@ -30,9 +31,11 @@ public TelemetryTaskFactoryImpl(@NonNull HttpRecorder<Config> telemetryConfigRec
@NonNull TelemetryStorage telemetryStorage,
@NonNull SplitClientConfig splitClientConfig,
@NonNull SplitsStorage splitsStorage,
@NonNull MySegmentsStorageContainer mySegmentsStorageContainer) {
@NonNull MySegmentsStorageContainer mySegmentsStorageContainer,
int flagSetCount,
int invalidFlagSetCount) {
mTelemetryConfigRecorder = telemetryConfigRecorder;
mTelemetryConfigProvider = new TelemetryConfigProviderImpl(telemetryStorage, splitClientConfig);
mTelemetryConfigProvider = new TelemetryConfigProviderImpl(telemetryStorage, splitClientConfig, flagSetCount, invalidFlagSetCount);
mTelemetryStatsRecorder = telemetryStatsRecorder;
mTelemetryStatsProvider = new TelemetryStatsProviderImpl(telemetryStorage, splitsStorage, mySegmentsStorageContainer);
mTelemetryRuntimeProducer = telemetryStorage;
Expand Down
22 changes: 22 additions & 0 deletions src/main/java/io/split/android/client/telemetry/model/Config.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ public class Config {
@SerializedName("i")
private List<String> integrations;

@SerializedName("fsT")
private int flagSetsTotal;

@SerializedName("fsI")
private int flagSetsInvalid;

public int getOperationMode() {
return operationMode;
}
Expand Down Expand Up @@ -195,4 +201,20 @@ public List<String> getIntegrations() {
public void setIntegrations(List<String> integrations) {
this.integrations = integrations;
}

public int getFlagSetsTotal() {
return flagSetsTotal;
}

public void setFlagSetsTotal(int flagSetsTotal) {
this.flagSetsTotal = flagSetsTotal;
}

public int getFlagSetsInvalid() {
return flagSetsInvalid;
}

public void setFlagSetsInvalid(int flagSetsInvalid) {
this.flagSetsInvalid = flagSetsInvalid;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@ public class TelemetryConfigProviderImpl implements TelemetryConfigProvider {

private final TelemetryStorageConsumer mTelemetryConsumer;
private final SplitClientConfig mSplitClientConfig;
private final int mValidFlagSetCount;
private final int mInvalidFlagSetCount;

public TelemetryConfigProviderImpl(@NonNull TelemetryStorageConsumer telemetryConsumer,
@NonNull SplitClientConfig splitClientConfig) {
@NonNull SplitClientConfig splitClientConfig,
int validFlagSetCount,
int invalidFlagSetCount) {
mTelemetryConsumer = checkNotNull(telemetryConsumer);
mSplitClientConfig = checkNotNull(splitClientConfig);
mValidFlagSetCount = validFlagSetCount;
mInvalidFlagSetCount = invalidFlagSetCount;
}

@Override
Expand All @@ -44,6 +50,8 @@ public Config getConfigTelemetry() {
config.setImpressionsQueueSize(mSplitClientConfig.impressionsQueueSize());
config.setEventsQueueSize(mSplitClientConfig.eventsQueueSize());
config.setUserConsent(mSplitClientConfig.userConsent().intValue());
config.setFlagSetsTotal(mValidFlagSetCount + mInvalidFlagSetCount);
config.setFlagSetsInvalid(mInvalidFlagSetCount);
if (mSplitClientConfig.impressionsMode() == ImpressionsMode.DEBUG) {
config.setImpressionsMode(io.split.android.client.telemetry.model.ImpressionsMode.DEBUG.intValue());
} else if (mSplitClientConfig.impressionsMode() == ImpressionsMode.OPTIMIZED) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ public class FlagSetsValidatorImpl implements SplitFilterValidator {
* @return list of unique alphanumerically ordered valid flag sets
*/
@Override
public List<String> cleanup(List<String> values) {
public ValidationResult cleanup(List<String> values) {
if (values == null || values.isEmpty()) {
return Collections.emptyList();
return new ValidationResult(Collections.emptyList(), 0);
}

int invalidValueCount = 0;

TreeSet<String> cleanedUpSets = new TreeSet<>();
for (String set : values) {
if (set == null || set.isEmpty()) {
invalidValueCount++;
continue;
}

Expand All @@ -43,11 +46,12 @@ public List<String> cleanup(List<String> values) {
if (set.matches(FLAG_SET_REGEX)) {
cleanedUpSets.add(set);
} else {
invalidValueCount++;
Logger.w("SDK config: you passed "+ set +", Flag Set must adhere to the regular expressions "+ FLAG_SET_REGEX +". This means a Flag Set must be start with a letter, be in lowercase, alphanumeric and have a max length of 50 characters. "+ set +" was discarded.");
}
}

return new ArrayList<>(cleanedUpSets);
return new ValidationResult(new ArrayList<>(cleanedUpSets), invalidValueCount);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,27 @@

public interface SplitFilterValidator {

List<String> cleanup(List<String> values);
ValidationResult cleanup(List<String> values);

boolean isValid(String value);

class ValidationResult {

private final List<String> mValues;

private final int mInvalidValueCount;

public ValidationResult(List<String> values, int invalidValueCount) {
mValues = values;
mInvalidValueCount = invalidValueCount;
}

public List<String> getValues() {
return mValues;
}

public int getInvalidValueCount() {
return mInvalidValueCount;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public void setUp() {
@Test
public void jsonIsBuiltAsExpected() {

final String expectedJson = "{\"oM\":0,\"st\":\"memory\",\"sE\":true,\"rR\":{\"sp\":4000,\"ms\":5000,\"im\":3000,\"ev\":2000,\"te\":1000},\"uO\":{\"s\":true,\"e\":true,\"a\":true,\"st\":true,\"t\":true},\"iQ\":4000,\"eQ\":3000,\"iM\":1,\"iL\":true,\"hP\":true,\"aF\":1,\"rF\":0,\"tR\":300,\"tC\":0,\"nR\":3,\"uC\":1,\"t\":[\"tag1\",\"tag2\"],\"i\":[\"integration1\",\"integration2\"]}";
final String expectedJson = "{\"oM\":0,\"st\":\"memory\",\"sE\":true,\"rR\":{\"sp\":4000,\"ms\":5000,\"im\":3000,\"ev\":2000,\"te\":1000},\"uO\":{\"s\":true,\"e\":true,\"a\":true,\"st\":true,\"t\":true},\"iQ\":4000,\"eQ\":3000,\"iM\":1,\"iL\":true,\"hP\":true,\"aF\":1,\"rF\":0,\"tR\":300,\"tC\":0,\"nR\":3,\"uC\":1,\"t\":[\"tag1\",\"tag2\"],\"i\":[\"integration1\",\"integration2\"],\"fsT\":4,\"fsI\":2}";
final String serializedConfig = telemetryConfigBodySerializer.serialize(buildMockConfig());

assertEquals(expectedJson, serializedConfig);
Expand All @@ -33,7 +33,7 @@ public void jsonIsBuiltAsExpected() {
@Test
public void nullValuesAreIgnoredForJson() {

final String expectedJson = "{\"oM\":0,\"st\":\"memory\",\"sE\":true,\"iQ\":4000,\"eQ\":3000,\"iM\":1,\"iL\":true,\"hP\":true,\"aF\":1,\"rF\":0,\"tR\":300,\"tC\":0,\"nR\":3,\"uC\":0,\"t\":[\"tag1\",\"tag2\"],\"i\":[\"integration1\",\"integration2\"]}";
final String expectedJson = "{\"oM\":0,\"st\":\"memory\",\"sE\":true,\"iQ\":4000,\"eQ\":3000,\"iM\":1,\"iL\":true,\"hP\":true,\"aF\":1,\"rF\":0,\"tR\":300,\"tC\":0,\"nR\":3,\"uC\":0,\"t\":[\"tag1\",\"tag2\"],\"i\":[\"integration1\",\"integration2\"],\"fsT\":0,\"fsI\":0}";
final String serializedConfig = telemetryConfigBodySerializer.serialize(buildMockConfigWithNulls());

assertEquals(expectedJson, serializedConfig);
Expand Down Expand Up @@ -71,6 +71,8 @@ private Config buildMockConfig() {
config.setUserConsent(1);
config.setTags(Arrays.asList("tag1", "tag2"));
config.setIntegrations(Arrays.asList("integration1", "integration2"));
config.setFlagSetsTotal(4);
config.setFlagSetsInvalid(2);

return config;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public void close() {
}
})
.build();
mTelemetryConfigProvider = new TelemetryConfigProviderImpl(mTelemetryStorageConsumer, mSplitClientConfig);
mTelemetryConfigProvider = new TelemetryConfigProviderImpl(mTelemetryStorageConsumer, mSplitClientConfig, 4, 2);

Config configTelemetry = mTelemetryConfigProvider.getConfigTelemetry();

Expand All @@ -81,5 +81,7 @@ public void close() {
assertTrue(configTelemetry.getUrlOverrides().isEvents());
assertTrue(configTelemetry.getUrlOverrides().isAuth());
assertTrue(configTelemetry.getUrlOverrides().isStream());
assertEquals(6, configTelemetry.getFlagSetsTotal());
assertEquals(2, configTelemetry.getFlagSetsInvalid());
}
}
Loading

0 comments on commit eafcc26

Please sign in to comment.