Skip to content

Release 4.15.0 #546

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

Merged
merged 30 commits into from
Apr 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
478ccb8
fix medium level vulnerability
Jan 27, 2025
8097860
Merge pull request #534 from splitio/fix-vulnerability
chillaq Jan 27, 2025
53f3898
added check to avoid start periodic sync if shutdown is in request
Feb 11, 2025
d5c83ac
polish
Feb 11, 2025
6ef1e32
polish
Feb 12, 2025
7644adb
polish
Feb 12, 2025
9b31b4a
Merge branch 'development' into fix-sdk-9395
chillaq Feb 12, 2025
69e44f8
Merge pull request #536 from splitio/fix-sdk-9395
chillaq Feb 12, 2025
358cbd7
Added client, validation and DTO classes
chillaq Mar 27, 2025
9e38fb9
Replaced JSONObject with JsonObject
chillaq Mar 27, 2025
e2c9cfd
polish
chillaq Mar 27, 2025
27d1e3b
Added dedupe logic
chillaq Mar 28, 2025
078ce6a
added tests
chillaq Mar 28, 2025
96a4355
added integration test
chillaq Mar 31, 2025
8521598
Added EvaluationOption class
chillaq Mar 31, 2025
54ac4e0
polish
chillaq Mar 31, 2025
a1d546e
Update client/src/main/java/io/split/client/SplitClientImpl.java
chillaq Apr 1, 2025
c440a3f
polish
chillaq Apr 1, 2025
e570e23
Merge branch 'imp-pr-client' of https://github.com/splitio/java-clien…
chillaq Apr 1, 2025
99188ec
polish
chillaq Apr 4, 2025
e9c4286
Merge pull request #537 from splitio/imp-pr-client
chillaq Apr 4, 2025
a904ef4
polish
chillaq Apr 7, 2025
58f5957
updated test coverage
chillaq Apr 7, 2025
64bdb43
polish
chillaq Apr 7, 2025
31ddbb3
fix test run
chillaq Apr 7, 2025
09285f3
polish tests
chillaq Apr 8, 2025
db60cec
Merge branch 'development' into feature/impression-properties
chillaq Apr 8, 2025
0bfe5cf
Merge pull request #542 from splitio/feature/impression-properties
chillaq Apr 8, 2025
6279f27
updated changes
chillaq Apr 17, 2025
3d9d592
Merge pull request #545 from splitio/prepare-release
chillaq Apr 17, 2025
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
4 changes: 4 additions & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
4.15.0 (Apr 18, 2025)
- Prevent polling threads from starting when the SDK calls destroy method.
- Added a new optional argument to the client `getTreatment` methods to allow passing additional evaluation options, such as a map of properties to append to the generated impressions sent to Split backend. Read more in our docs.

4.14.0 (Jan 17, 2025)
- Added support for the new impressions tracking toggle available on feature flags, both respecting the setting and including the new field being returned on SplitView type objects. Read more in our docs.
- Cleaned unused imports to fix a collision issue.
Expand Down
4 changes: 2 additions & 2 deletions client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@
<parent>
<groupId>io.split.client</groupId>
<artifactId>java-client-parent</artifactId>
<version>4.14.0</version>
<version>4.15.0</version>
</parent>
<version>4.14.0</version>
<version>4.15.0</version>
<artifactId>java-client</artifactId>
<packaging>jar</packaging>
<name>Java Client</name>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ private SplitChange processSplitChange(SplitChange splitChange, long changeNumbe
return null;
}
String splitJson = splitChange.splits.toString();
MessageDigest digest = MessageDigest.getInstance("SHA-1");
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.reset();
digest.update(splitJson.getBytes());
// calculate the json sha
byte [] currHash = digest.digest();
//if sha exist and is equal to before sha, or if till is equal to default till returns the same segmentChange with till equals to storage CN
if (Arrays.equals(lastHash, currHash) || splitChangeToProcess.till == -1) {
if (java.security.MessageDigest.isEqual(lastHash, currHash) || splitChangeToProcess.till == -1) {
splitChangeToProcess.till = changeNumber;
}
lastHash = currHash;
Expand Down
519 changes: 501 additions & 18 deletions client/src/main/java/io/split/client/SplitClient.java

Large diffs are not rendered by default.

255 changes: 222 additions & 33 deletions client/src/main/java/io/split/client/SplitClientImpl.java

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public class SplitFactoryImpl implements SplitFactory {
private static final org.slf4j.Logger _log = LoggerFactory.getLogger(SplitFactoryImpl.class);
private static final String LEGACY_LOG_MESSAGE = "The sdk initialize in localhost mode using Legacy file. The splitFile or "
+
"inputStream doesn't add it to the config.";
"inputStream are not added to the config.";
private final static long SSE_CONNECT_TIMEOUT = 30000;
private final static long SSE_SOCKET_TIMEOUT = 70000;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.split.client.dtos;

import java.util.Map;

public class EvaluationOptions {
private Map<String, Object> _properties;

public EvaluationOptions(Map<String, Object> properties) {
_properties = properties;
}
public Map<String, Object> getProperties() {
return _properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ public class KeyImpression {
/* package private */ static final String FIELD_TIME = "m";
/* package private */ static final String FIELD_CHANGE_NUMBER = "c";
/* package private */ static final String FIELD_PREVIOUS_TIME = "pt";
/* package private */ static final String FIELD_PROPERTIES = "properties";

public transient String feature; // Non-serializable

Expand All @@ -39,6 +40,9 @@ public class KeyImpression {
@SerializedName(FIELD_PREVIOUS_TIME)
public Long previousTime;

@SerializedName(FIELD_PROPERTIES)
public String properties;

@Override
public boolean equals(Object o) {
if (this == o) return true;
Expand All @@ -50,6 +54,7 @@ public boolean equals(Object o) {
if (!Objects.equals(feature, that.feature)) return false;
if (!keyName.equals(that.keyName)) return false;
if (!treatment.equals(that.treatment)) return false;
if (properties != null && !properties.equals(that.properties)) return false;

if (bucketingKey == null) {
return that.bucketingKey == null;
Expand Down Expand Up @@ -78,6 +83,7 @@ public static KeyImpression fromImpression(Impression i) {
ki.treatment = i.treatment();
ki.label = i.appliedRule();
ki.previousTime = i.pt();
ki.properties = i.properties();
return ki;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@ public class Impression {
private final Long _changeNumber;
private Long _pt;
private final Map<String, Object> _attributes;
private final String _properties;


public Impression(String key, String bucketingKey, String featureFlag, String treatment, long time, String appliedRule,
Long changeNumber, Map<String, Object> atributes) {
Long changeNumber, Map<String, Object> atributes, String properties) {
_key = key;
_bucketingKey = bucketingKey;
_split = featureFlag;
Expand All @@ -28,6 +29,7 @@ public Impression(String key, String bucketingKey, String featureFlag, String tr
_appliedRule = appliedRule;
_changeNumber = changeNumber;
_attributes = atributes;
_properties = properties;
}

public String key() {
Expand Down Expand Up @@ -67,4 +69,8 @@ public Long pt() {
}

public Impression withPreviousTime(Long pt) { _pt = pt; return this; }

public String properties() {
return _properties;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ public ProcessImpressionDebug(boolean listenerEnabled, ImpressionObserver impres
@Override
public ImpressionsResult process(List<Impression> impressions) {
for(Impression impression : impressions) {
if (impression.properties() != null) {
continue;
}
impression.withPreviousTime(_impressionObserver.testAndSet(impression));
}
List<Impression> impressionForListener = this._listenerEnabled ? impressions : null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ public ProcessImpressionOptimized(boolean listenerEnabled, ImpressionObserver im
public ImpressionsResult process(List<Impression> impressions) {
List<Impression> impressionsToQueue = new ArrayList<>();
for(Impression impression : impressions) {
impression = impression.withPreviousTime(_impressionObserver.testAndSet(impression));
if(!Objects.isNull(impression.pt()) && impression.pt() != 0){
_impressionCounter.inc(impression.split(), impression.time(), 1);
}
if(shouldntQueueImpression(impression)) {
continue;
if (impression.properties() == null) {
impression = impression.withPreviousTime(_impressionObserver.testAndSet(impression));
if (!Objects.isNull(impression.pt()) && impression.pt() != 0) {
_impressionCounter.inc(impression.split(), impression.time(), 1);
}
if (shouldntQueueImpression(impression)) {
continue;
}
}
impressionsToQueue.add(impression);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,11 @@ private void startPollingMode() {
case STREAMING_DOWN:
_log.info("Streaming service temporarily unavailable, working in polling mode.");
_pushManager.stopWorkers();
// if the whole SDK is being shutdown, don't start polling,
// in case the polling threads are not terminated and a graceful shutdown will fail.
if(_shuttedDown.get()) {
break;
}
_synchronizer.startPeriodicFetching();
break;
case STREAMING_BACKOFF:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package io.split.inputValidation;

import java.util.Map;

public class ImpressionPropertiesValidator {
ImpressionPropertiesValidator() {
throw new IllegalStateException("Utility class");
}

public static ImpressionPropertiesValidatorResult propertiesAreValid(Map<String, Object> properties) {
EventsValidator.EventValidatorResult result = EventsValidator.propertiesAreValid(properties);
return new ImpressionPropertiesValidatorResult(result.getSuccess(), result.getEventSize(), result.getValue());
}

public static class ImpressionPropertiesValidatorResult extends EventsValidator.EventValidatorResult {
public ImpressionPropertiesValidatorResult(boolean success, int eventSize, Map<String, Object> value) {
super(success, eventSize, value);
}
}
}

Loading