Skip to content

Commit 5130220

Browse files
authored
Merge pull request #546 from splitio/development
Release 4.15.0
2 parents 07d0ef4 + 3d9d592 commit 5130220

34 files changed

+1569
-303
lines changed

CHANGES.txt

+4
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
4.15.0 (Apr 18, 2025)
2+
- Prevent polling threads from starting when the SDK calls destroy method.
3+
- 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+
15
4.14.0 (Jan 17, 2025)
26
- 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.
37
- Cleaned unused imports to fix a collision issue.

client/pom.xml

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
<parent>
66
<groupId>io.split.client</groupId>
77
<artifactId>java-client-parent</artifactId>
8-
<version>4.14.0</version>
8+
<version>4.15.0</version>
99
</parent>
10-
<version>4.14.0</version>
10+
<version>4.15.0</version>
1111
<artifactId>java-client</artifactId>
1212
<packaging>jar</packaging>
1313
<name>Java Client</name>

client/src/main/java/io/split/client/JsonLocalhostSplitChangeFetcher.java

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ private SplitChange processSplitChange(SplitChange splitChange, long changeNumbe
4747
return null;
4848
}
4949
String splitJson = splitChange.splits.toString();
50-
MessageDigest digest = MessageDigest.getInstance("SHA-1");
50+
MessageDigest digest = MessageDigest.getInstance("SHA-256");
5151
digest.reset();
5252
digest.update(splitJson.getBytes());
5353
// calculate the json sha
5454
byte [] currHash = digest.digest();
5555
//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
56-
if (Arrays.equals(lastHash, currHash) || splitChangeToProcess.till == -1) {
56+
if (java.security.MessageDigest.isEqual(lastHash, currHash) || splitChangeToProcess.till == -1) {
5757
splitChangeToProcess.till = changeNumber;
5858
}
5959
lastHash = currHash;

client/src/main/java/io/split/client/SplitClient.java

+501-18
Large diffs are not rendered by default.

client/src/main/java/io/split/client/SplitClientImpl.java

+222-33
Large diffs are not rendered by default.

client/src/main/java/io/split/client/SplitFactoryImpl.java

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

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package io.split.client.dtos;
2+
3+
import java.util.Map;
4+
5+
public class EvaluationOptions {
6+
private Map<String, Object> _properties;
7+
8+
public EvaluationOptions(Map<String, Object> properties) {
9+
_properties = properties;
10+
}
11+
public Map<String, Object> getProperties() {
12+
return _properties;
13+
}
14+
}

client/src/main/java/io/split/client/dtos/KeyImpression.java

+6
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ public class KeyImpression {
1515
/* package private */ static final String FIELD_TIME = "m";
1616
/* package private */ static final String FIELD_CHANGE_NUMBER = "c";
1717
/* package private */ static final String FIELD_PREVIOUS_TIME = "pt";
18+
/* package private */ static final String FIELD_PROPERTIES = "properties";
1819

1920
public transient String feature; // Non-serializable
2021

@@ -39,6 +40,9 @@ public class KeyImpression {
3940
@SerializedName(FIELD_PREVIOUS_TIME)
4041
public Long previousTime;
4142

43+
@SerializedName(FIELD_PROPERTIES)
44+
public String properties;
45+
4246
@Override
4347
public boolean equals(Object o) {
4448
if (this == o) return true;
@@ -50,6 +54,7 @@ public boolean equals(Object o) {
5054
if (!Objects.equals(feature, that.feature)) return false;
5155
if (!keyName.equals(that.keyName)) return false;
5256
if (!treatment.equals(that.treatment)) return false;
57+
if (properties != null && !properties.equals(that.properties)) return false;
5358

5459
if (bucketingKey == null) {
5560
return that.bucketingKey == null;
@@ -78,6 +83,7 @@ public static KeyImpression fromImpression(Impression i) {
7883
ki.treatment = i.treatment();
7984
ki.label = i.appliedRule();
8085
ki.previousTime = i.pt();
86+
ki.properties = i.properties();
8187
return ki;
8288
}
8389
}

client/src/main/java/io/split/client/impressions/Impression.java

+7-1
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ public class Impression {
1616
private final Long _changeNumber;
1717
private Long _pt;
1818
private final Map<String, Object> _attributes;
19+
private final String _properties;
1920

2021

2122
public Impression(String key, String bucketingKey, String featureFlag, String treatment, long time, String appliedRule,
22-
Long changeNumber, Map<String, Object> atributes) {
23+
Long changeNumber, Map<String, Object> atributes, String properties) {
2324
_key = key;
2425
_bucketingKey = bucketingKey;
2526
_split = featureFlag;
@@ -28,6 +29,7 @@ public Impression(String key, String bucketingKey, String featureFlag, String tr
2829
_appliedRule = appliedRule;
2930
_changeNumber = changeNumber;
3031
_attributes = atributes;
32+
_properties = properties;
3133
}
3234

3335
public String key() {
@@ -67,4 +69,8 @@ public Long pt() {
6769
}
6870

6971
public Impression withPreviousTime(Long pt) { _pt = pt; return this; }
72+
73+
public String properties() {
74+
return _properties;
75+
}
7076
}

client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionDebug.java

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ public ProcessImpressionDebug(boolean listenerEnabled, ImpressionObserver impres
1919
@Override
2020
public ImpressionsResult process(List<Impression> impressions) {
2121
for(Impression impression : impressions) {
22+
if (impression.properties() != null) {
23+
continue;
24+
}
2225
impression.withPreviousTime(_impressionObserver.testAndSet(impression));
2326
}
2427
List<Impression> impressionForListener = this._listenerEnabled ? impressions : null;

client/src/main/java/io/split/client/impressions/strategy/ProcessImpressionOptimized.java

+8-6
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,14 @@ public ProcessImpressionOptimized(boolean listenerEnabled, ImpressionObserver im
3232
public ImpressionsResult process(List<Impression> impressions) {
3333
List<Impression> impressionsToQueue = new ArrayList<>();
3434
for(Impression impression : impressions) {
35-
impression = impression.withPreviousTime(_impressionObserver.testAndSet(impression));
36-
if(!Objects.isNull(impression.pt()) && impression.pt() != 0){
37-
_impressionCounter.inc(impression.split(), impression.time(), 1);
38-
}
39-
if(shouldntQueueImpression(impression)) {
40-
continue;
35+
if (impression.properties() == null) {
36+
impression = impression.withPreviousTime(_impressionObserver.testAndSet(impression));
37+
if (!Objects.isNull(impression.pt()) && impression.pt() != 0) {
38+
_impressionCounter.inc(impression.split(), impression.time(), 1);
39+
}
40+
if (shouldntQueueImpression(impression)) {
41+
continue;
42+
}
4143
}
4244
impressionsToQueue.add(impression);
4345
}

client/src/main/java/io/split/engine/common/SyncManagerImp.java

+5
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,11 @@ private void startPollingMode() {
212212
case STREAMING_DOWN:
213213
_log.info("Streaming service temporarily unavailable, working in polling mode.");
214214
_pushManager.stopWorkers();
215+
// if the whole SDK is being shutdown, don't start polling,
216+
// in case the polling threads are not terminated and a graceful shutdown will fail.
217+
if(_shuttedDown.get()) {
218+
break;
219+
}
215220
_synchronizer.startPeriodicFetching();
216221
break;
217222
case STREAMING_BACKOFF:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package io.split.inputValidation;
2+
3+
import java.util.Map;
4+
5+
public class ImpressionPropertiesValidator {
6+
ImpressionPropertiesValidator() {
7+
throw new IllegalStateException("Utility class");
8+
}
9+
10+
public static ImpressionPropertiesValidatorResult propertiesAreValid(Map<String, Object> properties) {
11+
EventsValidator.EventValidatorResult result = EventsValidator.propertiesAreValid(properties);
12+
return new ImpressionPropertiesValidatorResult(result.getSuccess(), result.getEventSize(), result.getValue());
13+
}
14+
15+
public static class ImpressionPropertiesValidatorResult extends EventsValidator.EventValidatorResult {
16+
public ImpressionPropertiesValidatorResult(boolean success, int eventSize, Map<String, Object> value) {
17+
super(success, eventSize, value);
18+
}
19+
}
20+
}
21+

0 commit comments

Comments
 (0)