Skip to content

Commit e9c4286

Browse files
authored
Merge pull request #537 from splitio/imp-pr-client
Imp pr client
2 parents 07d0ef4 + 99188ec commit e9c4286

22 files changed

+1467
-286
lines changed

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

Lines changed: 501 additions & 18 deletions
Large diffs are not rendered by default.

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

Lines changed: 225 additions & 33 deletions
Large diffs are not rendered by default.
Lines changed: 14 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ 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";
19+
20+
public static int MAX_PROPERTIES_LENGTH_BYTES = 32 * 1024;
1821

1922
public transient String feature; // Non-serializable
2023

@@ -39,6 +42,9 @@ public class KeyImpression {
3942
@SerializedName(FIELD_PREVIOUS_TIME)
4043
public Long previousTime;
4144

45+
@SerializedName(FIELD_PROPERTIES)
46+
public String properties;
47+
4248
@Override
4349
public boolean equals(Object o) {
4450
if (this == o) return true;
@@ -50,6 +56,7 @@ public boolean equals(Object o) {
5056
if (!Objects.equals(feature, that.feature)) return false;
5157
if (!keyName.equals(that.keyName)) return false;
5258
if (!treatment.equals(that.treatment)) return false;
59+
if (properties != null && !properties.equals(that.properties)) return false;
5360

5461
if (bucketingKey == null) {
5562
return that.bucketingKey == null;
@@ -78,6 +85,7 @@ public static KeyImpression fromImpression(Impression i) {
7885
ki.treatment = i.treatment();
7986
ki.label = i.appliedRule();
8087
ki.previousTime = i.pt();
88+
ki.properties = i.properties();
8189
return ki;
8290
}
8391
}

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

Lines changed: 7 additions & 1 deletion
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

Lines changed: 3 additions & 0 deletions
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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ 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+
if (impression.properties() != null) {
36+
impressionsToQueue.add(impression);
37+
continue;
38+
}
3539
impression = impression.withPreviousTime(_impressionObserver.testAndSet(impression));
3640
if(!Objects.isNull(impression.pt()) && impression.pt() != 0){
3741
_impressionCounter.inc(impression.split(), impression.time(), 1);
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package io.split.inputValidation;
2+
3+
import java.util.Map;
4+
5+
public class ImpressionPropertiesValidator {
6+
7+
public static ImpressionPropertiesValidatorResult propertiesAreValid(Map<String, Object> properties) {
8+
EventsValidator.EventValidatorResult result = EventsValidator.propertiesAreValid(properties);
9+
return new ImpressionPropertiesValidatorResult(result.getSuccess(), result.getEventSize(), result.getValue());
10+
}
11+
12+
public static class ImpressionPropertiesValidatorResult extends EventsValidator.EventValidatorResult {
13+
public ImpressionPropertiesValidatorResult(boolean success, int eventSize, Map<String, Object> value) {
14+
super(success, eventSize, value);
15+
}
16+
}
17+
}
18+

client/src/test/java/io/split/client/SplitClientImplTest.java

Lines changed: 84 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -565,7 +565,7 @@ public void attributesWork() {
565565
);
566566

567567
assertEquals("on", client.getTreatment("adil@codigo.com", test));
568-
assertEquals("on", client.getTreatment("adil@codigo.com", test, null));
568+
assertEquals("on", client.getTreatment("adil@codigo.com", test, new HashMap<>()));
569569
assertEquals("on", client.getTreatment("adil@codigo.com", test, ImmutableMap.<String, Object>of()));
570570
assertEquals("on", client.getTreatment("pato@codigo.com", test, ImmutableMap.<String, Object>of("age", 10)));
571571
assertEquals("off", client.getTreatment("pato@codigo.com", test, ImmutableMap.<String, Object>of("age", 9)));
@@ -599,7 +599,7 @@ public void attributesWork2() {
599599
);
600600

601601
assertEquals("off", client.getTreatment("adil@codigo.com", test));
602-
assertEquals("off", client.getTreatment("adil@codigo.com", test, null));
602+
assertEquals("off", client.getTreatment("adil@codigo.com", test, new HashMap<>()));
603603
assertEquals("off", client.getTreatment("adil@codigo.com", test, ImmutableMap.<String, Object>of()));
604604

605605
assertEquals("off", client.getTreatment("pato@codigo.com", test, ImmutableMap.<String, Object>of("age", 10)));
@@ -634,7 +634,7 @@ public void attributesGreaterThanNegativeNumber() {
634634
);
635635

636636
assertEquals("off", client.getTreatment("adil@codigo.com", test));
637-
assertEquals("off", client.getTreatment("adil@codigo.com", test, null));
637+
assertEquals("off", client.getTreatment("adil@codigo.com", test, new HashMap<>()));
638638
assertEquals("off", client.getTreatment("adil@codigo.com", test, ImmutableMap.<String, Object>of()));
639639
assertEquals("off", client.getTreatment("pato@codigo.com", test, ImmutableMap.<String, Object>of("age", 10)));
640640
assertEquals("on", client.getTreatment("pato@codigo.com", test, ImmutableMap.<String, Object>of("age", -20)));
@@ -671,7 +671,7 @@ public void attributesForSets() {
671671
);
672672

673673
assertEquals("off", client.getTreatment("adil@codigo.com", test));
674-
assertEquals("off", client.getTreatment("adil@codigo.com", test, null));
674+
assertEquals("off", client.getTreatment("adil@codigo.com", test, new HashMap<>()));
675675

676676
assertEquals("off", client.getTreatment("adil@codigo.com", test, ImmutableMap.<String, Object>of()));
677677
assertEquals("off", client.getTreatment("pato@codigo.com", test, ImmutableMap.<String, Object>of("products", Lists.newArrayList())));
@@ -1894,7 +1894,7 @@ public void testTreatmentsByFlagSet() {
18941894
Map<String, String> getTreatmentResult;
18951895
for (int i = 0; i < numKeys; i++) {
18961896
String randomKey = RandomStringUtils.random(10);
1897-
getTreatmentResult = client.getTreatmentsByFlagSet(randomKey, "set1", null);
1897+
getTreatmentResult = client.getTreatmentsByFlagSet(randomKey, "set1", new HashMap<>());
18981898
assertEquals("on", getTreatmentResult.get(test));
18991899
}
19001900
verify(splitCacheConsumer, times(numKeys)).fetchMany(new ArrayList<>(Arrays.asList(test)));
@@ -1927,7 +1927,7 @@ public void testTreatmentsByFlagSetInvalid() {
19271927
new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer), TELEMETRY_STORAGE, TELEMETRY_STORAGE,
19281928
flagSetsFilter
19291929
);
1930-
assertTrue(client.getTreatmentsByFlagSet(RandomStringUtils.random(10), "", null).isEmpty());
1930+
assertTrue(client.getTreatmentsByFlagSet(RandomStringUtils.random(10), "", new HashMap<>()).isEmpty());
19311931
}
19321932

19331933
@Test
@@ -1974,7 +1974,7 @@ public void testTreatmentsByFlagSets() {
19741974
Map<String, String> getTreatmentResult;
19751975
for (int i = 0; i < numKeys; i++) {
19761976
String randomKey = RandomStringUtils.random(10);
1977-
getTreatmentResult = client.getTreatmentsByFlagSets(randomKey, Arrays.asList("set1", "set3"), null);
1977+
getTreatmentResult = client.getTreatmentsByFlagSets(randomKey, Arrays.asList("set1", "set3"), new HashMap<>());
19781978
assertEquals("on", getTreatmentResult.get(test));
19791979
assertEquals("on", getTreatmentResult.get(test2));
19801980
}
@@ -2081,4 +2081,81 @@ public void treatmentsWorksAndHasConfigFlagSets() {
20812081

20822082
verify(splitCacheConsumer, times(1)).fetchMany(anyList());
20832083
}
2084+
2085+
@Test
2086+
public void impressionPropertiesTest() {
2087+
String test = "test1";
2088+
2089+
ParsedCondition age_equal_to_0_should_be_on = new ParsedCondition(ConditionType.ROLLOUT,
2090+
CombiningMatcher.of("age", new EqualToMatcher(-20, DataType.NUMBER)),
2091+
Lists.newArrayList(partition("on", 100)),
2092+
"foolabel"
2093+
);
2094+
2095+
List<ParsedCondition> conditions = Lists.newArrayList(age_equal_to_0_should_be_on);
2096+
ParsedSplit parsedSplit = ParsedSplit.createParsedSplitForTests(test, 123, false, Treatments.OFF, conditions, null, 1, 1, new HashSet<>(Arrays.asList("set")), true);
2097+
Map<String, ParsedSplit> parsedSplits = new HashMap<>();
2098+
parsedSplits.put(test, parsedSplit);
2099+
2100+
SplitCacheConsumer splitCacheConsumer = mock(SplitCacheConsumer.class);
2101+
SegmentCacheConsumer segmentCacheConsumer = mock(SegmentCacheConsumer.class);
2102+
when(splitCacheConsumer.get(test)).thenReturn(parsedSplit);
2103+
when(splitCacheConsumer.fetchMany(Arrays.asList(test))).thenReturn(parsedSplits);
2104+
Map<String, HashSet<String>> splits = new HashMap<>();
2105+
splits.put("set", new HashSet<>(Arrays.asList(test)));
2106+
when(splitCacheConsumer.getNamesByFlagSets(Arrays.asList("set"))).thenReturn(splits);
2107+
2108+
SDKReadinessGates gates = mock(SDKReadinessGates.class);
2109+
ImpressionsManager impressionsManager = mock(ImpressionsManager.class);
2110+
SplitClientImpl client = new SplitClientImpl(
2111+
mock(SplitFactory.class),
2112+
splitCacheConsumer,
2113+
impressionsManager,
2114+
NoopEventsStorageImp.create(),
2115+
config,
2116+
gates,
2117+
new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer), TELEMETRY_STORAGE, TELEMETRY_STORAGE,
2118+
new FlagSetsFilterImpl(new HashSet<>())
2119+
);
2120+
Map<String, Object> attributes = ImmutableMap.<String, Object>of("age", -20, "acv", "1000000");
2121+
EvaluationOptions properties = new EvaluationOptions(new HashMap<String, Object>()
2122+
{{
2123+
put("prop2", "val2");
2124+
put("prop1", "val1");
2125+
}});
2126+
Map<String, String> result = new HashMap<>();
2127+
result.put(test, Treatments.ON);
2128+
List<String> split_names = Arrays.asList(test);
2129+
2130+
assertEquals("on", client.getTreatment("pato@codigo.com", test, attributes, properties));
2131+
assertEquals("on", client.getTreatmentWithConfig("bilal1@codigo.com", test, attributes, properties).treatment());
2132+
assertEquals("on", client.getTreatments("bilal2@codigo.com", Arrays.asList(test), attributes, properties).get(test));
2133+
assertEquals("on", client.getTreatmentsWithConfig("bilal3@codigo.com", Arrays.asList(test), attributes, properties).get(test).treatment());
2134+
assertEquals("on", client.getTreatmentsByFlagSet("bilal4@codigo.com", "set", attributes, properties).get(test));
2135+
assertEquals("on", client.getTreatmentsByFlagSets("bilal5@codigo.com", Arrays.asList("set"), attributes, properties).get(test));
2136+
assertEquals("on", client.getTreatmentsWithConfigByFlagSet("bilal6@codigo.com", "set", attributes, properties).get(test).treatment());
2137+
assertEquals("on", client.getTreatmentsWithConfigByFlagSets("bilal7@codigo.com", Arrays.asList("set"), attributes, properties).get(test).treatment());
2138+
assertEquals("on", client.getTreatment(new Key("bilal8@codigo.com", "bilal8@codigo.com"), test, attributes, properties));
2139+
assertEquals("on", client.getTreatmentWithConfig(new Key("bilal9@codigo.com", "bilal9@codigo.com"), test, attributes, properties).treatment());
2140+
assertEquals("on", client.getTreatments(new Key("bilal10@codigo.com", "bilal10@codigo.com"), Arrays.asList(test), attributes, properties).get(test));
2141+
assertEquals("on", client.getTreatmentsWithConfig(new Key("bilal11@codigo.com", "bilal11@codigo.com"), Arrays.asList(test), attributes, properties).get(test).treatment());
2142+
assertEquals("on", client.getTreatmentsByFlagSet(new Key("bilal12@codigo.com", "bilal12@codigo.com"), "set", attributes, properties).get(test));
2143+
assertEquals("on", client.getTreatmentsByFlagSets(new Key("bilal13@codigo.com", "bilal13@codigo.com"), Arrays.asList("set"), attributes, properties).get(test));
2144+
assertEquals("on", client.getTreatmentsWithConfigByFlagSet(new Key("bilal14@codigo.com", "bilal14@codigo.com"), "set", attributes, properties).get(test).treatment());
2145+
assertEquals("on", client.getTreatmentsWithConfigByFlagSets(new Key("bilal15@codigo.com", "bilal15@codigo.com"), Arrays.asList("set"), attributes, properties).get(test).treatment());
2146+
2147+
ArgumentCaptor<List> impressionCaptor = ArgumentCaptor.forClass(List.class);
2148+
verify(impressionsManager, times(16)).track(impressionCaptor.capture());
2149+
assertNotNull(impressionCaptor.getValue());
2150+
2151+
DecoratedImpression impression = (DecoratedImpression) impressionCaptor.getAllValues().get(0).get(0);
2152+
assertEquals("pato@codigo.com", impression.impression().key());
2153+
assertEquals("{\"prop2\":\"val2\",\"prop1\":\"val1\"}", impression.impression().properties());
2154+
2155+
for (int i=1; i<=15; i++) {
2156+
impression = (DecoratedImpression) impressionCaptor.getAllValues().get(i).get(0);
2157+
assertEquals("bilal" + i + "@codigo.com", impression.impression().key());
2158+
assertEquals("{\"prop2\":\"val2\",\"prop1\":\"val1\"}", impression.impression().properties());
2159+
}
2160+
}
20842161
}

0 commit comments

Comments
 (0)