Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
5ca21aa
Linter config
nmayorsplit Jul 10, 2023
19468ee
[SDKS-7280] Add google-java-style and linter workflows
nmayorsplit Jul 11, 2023
2842cd6
[SDKS-7280] Update ci for linter
nmayorsplit Jul 11, 2023
0f02617
[SDKS-7280] Update linter
nmayorsplit Jul 11, 2023
e07503a
[SDKS-7280] Update Linter
nmayorsplit Jul 11, 2023
f401545
Update linter
nmayorsplit Jul 12, 2023
7ac703f
Update linter
nmayorsplit Jul 12, 2023
0bcd59b
[SDKS-7283] Update google-java-style, add supressions and apply style
nmayorsplit Jul 13, 2023
d0bcee2
Merge branch 'development' into SDKS-7200
nmayorsplit Jul 13, 2023
d9fd4e2
[SDKS-7283] Update linter.yml
nmayorsplit Jul 13, 2023
17ef5dd
[SDKS-7283] Update linter file
nmayorsplit Jul 14, 2023
66ccc82
[SDKS-7283] Update linter to check only the changed files
nmayorsplit Jul 14, 2023
ab42858
Update linter.yml
nmayorsplit Jul 14, 2023
b968945
Merge with development
nmayorsplit Jul 19, 2023
f4a5177
[SDKS-7283] Update pom file to use check-style pluging
nmayorsplit Jul 20, 2023
f7b9022
Update pom file
nmayorsplit Jul 20, 2023
a2c1e4d
Add reason to fail linter
nmayorsplit Jul 21, 2023
aa36c6c
Update NotficationProcessorImp
nmayorsplit Jul 21, 2023
d52728b
Merge pull request #421 from splitio/SDKS-7200
nmayorsplit Jul 21, 2023
d4f9893
[SDKS-7334] Update CommonRedis to build key without prefix
nmayorsplit Jul 31, 2023
8882c10
Update pom version for tapps
nmayorsplit Jul 31, 2023
6240fe2
Update redis and client version
nmayorsplit Jul 31, 2023
aa631ae
[SDKS-7334] Update the CHANGES
nmayorsplit Aug 1, 2023
ec03eba
[SDKS-7334] Update client and redis version
nmayorsplit Aug 1, 2023
958347b
Merge pull request #424 from splitio/SDKS-7334
nmayorsplit Aug 1, 2023
33ae09d
Updatee CHANGES
nmayorsplit Aug 1, 2023
d439f75
Merge pull request #426 from splitio/change-log
nmayorsplit Aug 1, 2023
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
9 changes: 9 additions & 0 deletions .github/linter/checkstyle-suppressions.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?xml version="1.0"?>

<!DOCTYPE suppressions PUBLIC
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">

<suppressions>
<suppress checks="LineLength" files=".*(test|it)[\\/]"/>
</suppressions>
380 changes: 380 additions & 0 deletions .github/linter/google-java-style.xml

Large diffs are not rendered by default.

4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ jobs:
if: matrix.jdk == '8' && github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/development'
run: mvn --batch-mode clean install

- name: Linter
if: matrix.jdk == '8' && github.event_name == 'pull_request' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/development'
run: mvn checkstyle::check

- name: Deploy
if: matrix.jdk == '8' && github.event_name == 'push' && github.ref != 'refs/heads/master' && github.ref != 'refs/heads/development'
run: mvn --batch-mode deploy -P test
Expand Down
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
4.8.1 (Aug 1, 2023)
- Applied linting rules to the code.
- Fixed an issue when the prefix is empty for Redis settings.

4.8.0 (Jul 18, 2023)
- Improved streaming architecture implementation to apply feature flag updates from the notification received which is now enhanced, improving efficiency and reliability of the whole update system.
- Updated `com.google.guava` dependence to 32.0.1 for fixing a vulnerability.
Expand Down
2 changes: 1 addition & 1 deletion client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.split.client</groupId>
<artifactId>java-client-parent</artifactId>
<version>4.8.0</version>
<version>4.8.1</version>
</parent>
<artifactId>java-client</artifactId>
<packaging>jar</packaging>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ public final class HttpSegmentChangeFetcher implements SegmentChangeFetcher {
private final URI _target;
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;

public static HttpSegmentChangeFetcher create(CloseableHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer) throws URISyntaxException {
public static HttpSegmentChangeFetcher create(CloseableHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer)
throws URISyntaxException {
return new HttpSegmentChangeFetcher(client, Utils.appendPath(root, "api/segmentChanges"), telemetryRuntimeProducer);
}

Expand Down Expand Up @@ -102,7 +103,8 @@ public SegmentChange fetch(String segmentName, long since, FetchOptions options)
_log.error("factory instantiation: you passed a client side type sdkKey, " +
"please grab an sdk key from the Split user interface that is of type server side");
}
throw new IllegalStateException(String.format("Could not retrieve segment changes for %s, since %s; http return code %s", segmentName, since, statusCode));
throw new IllegalStateException(String.format("Could not retrieve segment changes for %s, since %s; http return code %s",
segmentName, since, statusCode));
}

_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.SEGMENTS, System.currentTimeMillis());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ public final class HttpSplitChangeFetcher implements SplitChangeFetcher {
private final URI _target;
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;

public static HttpSplitChangeFetcher create(CloseableHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer) throws URISyntaxException {
public static HttpSplitChangeFetcher create(CloseableHttpClient client, URI root, TelemetryRuntimeProducer telemetryRuntimeProducer)
throws URISyntaxException {
return new HttpSplitChangeFetcher(client, Utils.appendPath(root, "api/splitChanges"), telemetryRuntimeProducer);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public SplitChange fetch(long since, FetchOptions options) {
_log.warn(String.format("There was no file named %s found. " +
"We created a split client that returns default treatments for all feature flags for all of your users. " +
"If you wish to return a specific treatment for a feature flag, enter the name of that feature flag name and " +
"treatment name separated by whitespace in %s; one pair per line. Empty lines or lines starting with '#' are considered comments",
"treatment name separated by whitespace in %s; one pair per line. Empty lines or lines starting with '#' are " +
"considered comments",
_file.getPath(), _file.getPath()), f);
throw new IllegalStateException("Problem fetching splitChanges: " + f.getMessage(), f);
} catch (Exception e) {
Expand Down
4 changes: 2 additions & 2 deletions client/src/main/java/io/split/client/SplitClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,8 @@ public interface SplitClient {
*
* @param key a unique key of your customer (e.g. user_id, user_email, account_id, etc.) MUST not be null.
* @param featureFlagNames the names of the feature flags we want to evaluate. MUST NOT be null.
* @return Map<String, SplitResult> containing 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.
* @return Map<String, SplitResult> containing 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> getTreatmentsWithConfig(String key, List<String> featureFlagNames);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ public static final class Builder {
private String _authServiceURL = AUTH_ENDPOINT;
private String _streamingServiceURL = STREAMING_ENDPOINT;
private String _telemetryURl = TELEMETRY_ENDPOINT;
private int _telemetryRefreshRate = 3600;
private int _telemetryRefreshRate = 600;
private final int _uniqueKeysRefreshRateInMemory = 900;
private final int _uniqueKeysRefreshRateRedis = 300;
private final int _filterUniqueKeysRefreshRate = 86400;
Expand Down
32 changes: 20 additions & 12 deletions client/src/main/java/io/split/client/SplitClientImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ public Map<String, String> getTreatments(Key key, List<String> featureFlagNames,

@Override
public Map<String, SplitResult> getTreatmentsWithConfig(String key, List<String> featureFlagNames) {
return getTreatmentsWithConfigInternal(key, null, featureFlagNames, Collections.<String, Object>emptyMap(), MethodEnum.TREATMENTS_WITH_CONFIG);
return getTreatmentsWithConfigInternal(key, null, featureFlagNames, Collections.<String, Object>emptyMap(),
MethodEnum.TREATMENTS_WITH_CONFIG);
}

@Override
Expand All @@ -135,7 +136,8 @@ public Map<String, SplitResult> getTreatmentsWithConfig(String key, List<String>

@Override
public Map<String, SplitResult> getTreatmentsWithConfig(Key key, List<String> featureFlagNames, Map<String, Object> attributes) {
return getTreatmentsWithConfigInternal(key.matchingKey(), key.bucketingKey(), featureFlagNames, attributes, MethodEnum.TREATMENTS_WITH_CONFIG);
return getTreatmentsWithConfigInternal(key.matchingKey(), key.bucketingKey(), featureFlagNames, attributes,
MethodEnum.TREATMENTS_WITH_CONFIG);
}

@Override
Expand Down Expand Up @@ -220,7 +222,8 @@ private boolean track(Event event) {
return _eventsStorageProducer.track(event, propertiesResult.getEventSize());
}

private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bucketingKey, String featureFlag, Map<String, Object> attributes, MethodEnum methodEnum) {
private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bucketingKey, String featureFlag, Map<String,
Object> attributes, MethodEnum methodEnum) {
long initTime = System.currentTimeMillis();
try {
checkSDKReady(methodEnum);
Expand Down Expand Up @@ -279,7 +282,8 @@ private SplitResult getTreatmentWithConfigInternal(String matchingKey, String bu
}
}

private Map<String, SplitResult> getTreatmentsWithConfigInternal(String matchingKey, String bucketingKey, List<String> featureFlagNames, Map<String, Object> attributes, MethodEnum methodEnum) {
private Map<String, SplitResult> getTreatmentsWithConfigInternal(String matchingKey, String bucketingKey, List<String> featureFlagNames,
Map<String, Object> attributes, MethodEnum methodEnum) {
long initTime = System.currentTimeMillis();
if (featureFlagNames == null) {
_log.error(String.format("%s: featureFlagNames must be a non-empty array", methodEnum.getMethod()));
Expand All @@ -303,17 +307,20 @@ private Map<String, SplitResult> getTreatmentsWithConfigInternal(String matching
return new HashMap<>();
}
featureFlagNames = SplitNameValidator.areValid(featureFlagNames, methodEnum.getMethod());
Map<String, EvaluatorImp.TreatmentLabelAndChangeNumber> evaluatorResult = _evaluator.evaluateFeatures(matchingKey, bucketingKey, featureFlagNames, attributes);
Map<String, EvaluatorImp.TreatmentLabelAndChangeNumber> evaluatorResult = _evaluator.evaluateFeatures(matchingKey,
bucketingKey, featureFlagNames, attributes);
List<Impression> impressions = new ArrayList<>();
Map<String, SplitResult> result = new HashMap<>();
evaluatorResult.keySet().forEach(t -> {
if (evaluatorResult.get(t).treatment.equals(Treatments.CONTROL) && evaluatorResult.get(t).label.equals(Labels.DEFINITION_NOT_FOUND) && _gates.isSDKReady()) {
_log.warn(String.format(
"%s: you passed \"%s\" that does not exist in this environment please double check what feature flags exist in the Split user interface.", methodEnum.getMethod(), t));
if (evaluatorResult.get(t).treatment.equals(Treatments.CONTROL) && evaluatorResult.get(t).label.
equals(Labels.DEFINITION_NOT_FOUND) && _gates.isSDKReady()) {
_log.warn(String.format("%s: you passed \"%s\" that does not exist in this environment please double check " +
"what feature flags exist in the Split user interface.", methodEnum.getMethod(), t));
result.put(t, SPLIT_RESULT_CONTROL);
} else {
result.put(t, new SplitResult(evaluatorResult.get(t).treatment, evaluatorResult.get(t).configurations));
impressions.add(new Impression(matchingKey, bucketingKey, t, evaluatorResult.get(t).treatment, System.currentTimeMillis(), evaluatorResult.get(t).label, evaluatorResult.get(t).changeNumber, attributes));
impressions.add(new Impression(matchingKey, bucketingKey, t, evaluatorResult.get(t).treatment, System.currentTimeMillis(),
evaluatorResult.get(t).label, evaluatorResult.get(t).changeNumber, attributes));
}
});

Expand All @@ -337,7 +344,8 @@ private Map<String, SplitResult> getTreatmentsWithConfigInternal(String matching
private void recordStats(String matchingKey, String bucketingKey, String featureFlagName, long start, String result,
String operation, String label, Long changeNumber, Map<String, Object> attributes) {
try {
_impressionManager.track(Stream.of(new Impression(matchingKey, bucketingKey, featureFlagName, result, System.currentTimeMillis(), label, changeNumber, attributes)).collect(Collectors.toList()));
_impressionManager.track(Stream.of(new Impression(matchingKey, bucketingKey, featureFlagName, result, System.currentTimeMillis(),
label, changeNumber, attributes)).collect(Collectors.toList()));
} catch (Throwable t) {
_log.error("Exception", t);
}
Expand All @@ -354,8 +362,8 @@ private Event createEvent(String key, String trafficType, String eventType) {

private void checkSDKReady(MethodEnum methodEnum) {
if (!_gates.isSDKReady()) {
_log.warn(String.format(
"%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness before using this method", methodEnum.getMethod()));
_log.warn(String.format("%s: the SDK is not ready, results may be incorrect. Make sure to wait for SDK readiness " +
"before using this method", methodEnum.getMethod()));
_telemetryConfigProducer.recordNonReadyUsage();
}
}
Expand Down
27 changes: 18 additions & 9 deletions client/src/main/java/io/split/client/SplitFactoryImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,8 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
ImpressionsStorage impressionsStorage = new InMemoryImpressionsStorage(config.impressionsQueueSize());
_splitCache = splitCache;
_segmentCache = segmentCache;
_telemetrySynchronizer = new TelemetryInMemorySubmitter(_httpclient, URI.create(config.telemetryURL()), telemetryStorage, splitCache, _segmentCache, telemetryStorage, _startTime);
_telemetrySynchronizer = new TelemetryInMemorySubmitter(_httpclient, URI.create(config.telemetryURL()), telemetryStorage,
splitCache, _segmentCache, telemetryStorage, _startTime);

// Segments
_segmentSynchronizationTaskImp = buildSegments(config, segmentCache, splitCache);
Expand All @@ -200,7 +201,8 @@ public SplitFactoryImpl(String apiToken, SplitClientConfig config) throws URISyn
config.getThreadFactory());

//ImpressionSender
_impressionsSender = HttpImpressionsSender.create(_httpclient, URI.create(config.eventsEndpoint()), config.impressionsMode(), _telemetryStorageProducer);
_impressionsSender = HttpImpressionsSender.create(_httpclient, URI.create(config.eventsEndpoint()), config.impressionsMode(),
_telemetryStorageProducer);

//UniqueKeysTracker
_uniqueKeysTracker = createUniqueKeysTracker(config);
Expand Down Expand Up @@ -267,8 +269,10 @@ protected SplitFactoryImpl(String apiToken, SplitClientConfig config, CustomStor
_userStorageWrapper = new UserStorageWrapper(customStorageWrapper);
UserCustomSegmentAdapterConsumer userCustomSegmentAdapterConsumer= new UserCustomSegmentAdapterConsumer(customStorageWrapper);
UserCustomSplitAdapterConsumer userCustomSplitAdapterConsumer = new UserCustomSplitAdapterConsumer(customStorageWrapper);
UserCustomImpressionAdapterConsumer userCustomImpressionAdapterConsumer = new UserCustomImpressionAdapterConsumer(); // TODO migrate impressions sender to Task instead manager and not instantiate Producer here.
UserCustomImpressionAdapterProducer userCustomImpressionAdapterProducer = new UserCustomImpressionAdapterProducer(customStorageWrapper, metadata);
// TODO migrate impressions sender to Task instead manager and not instantiate Producer here.
UserCustomImpressionAdapterConsumer userCustomImpressionAdapterConsumer = new UserCustomImpressionAdapterConsumer();
UserCustomImpressionAdapterProducer userCustomImpressionAdapterProducer = new UserCustomImpressionAdapterProducer(customStorageWrapper,
metadata);
UserCustomEventAdapterProducer userCustomEventAdapterProducer = new UserCustomEventAdapterProducer(customStorageWrapper, metadata);

_operationMode = config.operationMode();
Expand Down Expand Up @@ -543,7 +547,8 @@ private static HttpClientBuilder setupProxy(HttpClientBuilder httpClientbuilder,
return httpClientbuilder;
}

private SegmentSynchronizationTaskImp buildSegments(SplitClientConfig config, SegmentCacheProducer segmentCacheProducer, SplitCacheConsumer splitCacheConsumer) throws URISyntaxException {
private SegmentSynchronizationTaskImp buildSegments(SplitClientConfig config, SegmentCacheProducer segmentCacheProducer,
SplitCacheConsumer splitCacheConsumer) throws URISyntaxException {
SegmentChangeFetcher segmentChangeFetcher = HttpSegmentChangeFetcher.create(_httpclient, _rootTarget, _telemetryStorageProducer);

return new SegmentSynchronizationTaskImp(segmentChangeFetcher,
Expand All @@ -561,7 +566,8 @@ private SplitFetcher buildSplitFetcher(SplitCacheProducer splitCacheProducer, Sp
return new SplitFetcherImp(splitChangeFetcher, splitParser, splitCacheProducer, _telemetryStorageProducer);
}

private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config, ImpressionsStorageConsumer impressionsStorageConsumer, ImpressionsStorageProducer impressionsStorageProducer) throws URISyntaxException {
private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config, ImpressionsStorageConsumer impressionsStorageConsumer,
ImpressionsStorageProducer impressionsStorageProducer) throws URISyntaxException {
List<ImpressionListener> impressionListeners = new ArrayList<>();
if (config.integrationsConfig() != null) {
config.integrationsConfig().getImpressionsListeners(IntegrationsConfig.Execution.ASYNC).stream()
Expand Down Expand Up @@ -591,7 +597,8 @@ private ImpressionsManagerImpl buildImpressionsManager(SplitClientConfig config,
processImpressionStrategy = new ProcessImpressionNone(listener != null, _uniqueKeysTracker, counter);
break;
}
return ImpressionsManagerImpl.instance(config, _telemetryStorageProducer, impressionsStorageConsumer, impressionsStorageProducer, _impressionsSender, processImpressionStrategy, counter, listener);
return ImpressionsManagerImpl.instance(config, _telemetryStorageProducer, impressionsStorageConsumer, impressionsStorageProducer,
_impressionsSender, processImpressionStrategy, counter, listener);
}

private SDKMetadata createSdkMetadata(boolean ipAddressEnabled, String splitSdkVersion) {
Expand Down Expand Up @@ -622,15 +629,17 @@ private void manageSdkReady(SplitClientConfig config) {
}
}
_gates.sdkInternalReady();
_telemetrySynchronizer.synchronizeConfig(config, System.currentTimeMillis(), ApiKeyCounter.getApiKeyCounterInstance().getFactoryInstances(), new ArrayList<>());
_telemetrySynchronizer.synchronizeConfig(config, System.currentTimeMillis(), ApiKeyCounter.getApiKeyCounterInstance().
getFactoryInstances(), new ArrayList<>());
});
}

private UniqueKeysTracker createUniqueKeysTracker(SplitClientConfig config){
if (config.impressionsMode().equals(ImpressionsManager.Mode.NONE)){
int uniqueKeysRefreshRate = config.operationMode().equals(OperationMode.STANDALONE) ? config.uniqueKeysRefreshRateInMemory()
: config.uniqueKeysRefreshRateRedis();
return new UniqueKeysTrackerImp(_telemetrySynchronizer, uniqueKeysRefreshRate, config.filterUniqueKeysRefreshRate(), config.getThreadFactory());
return new UniqueKeysTrackerImp(_telemetrySynchronizer, uniqueKeysRefreshRate, config.filterUniqueKeysRefreshRate(),
config.getThreadFactory());
}
return null;
}
Expand Down
Loading