-
Notifications
You must be signed in to change notification settings - Fork 23
Imp pr client #537
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
Imp pr client #537
Changes from 8 commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
358cbd7
Added client, validation and DTO classes
chillaq 9e38fb9
Replaced JSONObject with JsonObject
chillaq e2c9cfd
polish
chillaq 27d1e3b
Added dedupe logic
chillaq 078ce6a
added tests
chillaq 96a4355
added integration test
chillaq 8521598
Added EvaluationOption class
chillaq 54ac4e0
polish
chillaq a1d546e
Update client/src/main/java/io/split/client/SplitClientImpl.java
chillaq c440a3f
polish
chillaq e570e23
Merge branch 'imp-pr-client' of https://github.com/splitio/java-clien…
chillaq 99188ec
polish
chillaq File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
258 changes: 225 additions & 33 deletions
258
client/src/main/java/io/split/client/SplitClientImpl.java
Large diffs are not rendered by default.
Oops, something went wrong.
14 changes: 14 additions & 0 deletions
14
client/src/main/java/io/split/client/dtos/EvaluationOptions.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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; | ||
| }; | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
83 changes: 83 additions & 0 deletions
83
client/src/main/java/io/split/inputValidation/ImpressionPropertiesValidator.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,83 @@ | ||
| package io.split.inputValidation; | ||
|
|
||
| import io.split.client.dtos.KeyImpression; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| public class ImpressionPropertiesValidator { | ||
| private static final Logger _log = LoggerFactory.getLogger(ImpressionPropertiesValidator.class); | ||
|
|
||
| public static ImpressionPropertiesValidatorResult propertiesAreValid(Map<String, Object> properties) { | ||
| int size = 1024; // We assume 1kb events without properties (750 bytes avg measured) | ||
|
|
||
| if (properties == null) { | ||
| return new ImpressionPropertiesValidatorResult(true); | ||
| } | ||
| if (properties.size() > 300) { | ||
| _log.warn("Impression properties has more than 300 properties. Some of them will be trimmed when processed"); | ||
| } | ||
|
|
||
| Map<String, Object> result = new HashMap<>(); | ||
| for (Map.Entry<String, Object> entry : properties.entrySet()) { | ||
| if (entry.getKey() == null || entry.getKey().isEmpty()) { | ||
| continue; | ||
| } | ||
|
|
||
| size += entry.getKey().length(); | ||
| Object value = entry.getValue(); | ||
|
|
||
| if (!(value instanceof Number) && !(value instanceof Boolean) && !(value instanceof String)) { | ||
| _log.warn(String.format("Property %s is of invalid type. Setting value to null", entry.getKey())); | ||
| value = null; | ||
| } | ||
|
|
||
| if (value instanceof String) { | ||
| size += ((String) value).length(); | ||
| } | ||
|
|
||
| if (size > KeyImpression.MAX_PROPERTIES_LENGTH_BYTES) { | ||
| _log.error(String.format("The maximum size allowed for the properties is 32768 bytes. " | ||
| + "Current one is %s bytes. Properties field is ignored", size)); | ||
|
|
||
| return new ImpressionPropertiesValidatorResult(false); | ||
| } | ||
|
|
||
| result.put(entry.getKey(), value); | ||
| } | ||
|
|
||
| return new ImpressionPropertiesValidatorResult(true, size, result); | ||
| } | ||
|
|
||
| public static class ImpressionPropertiesValidatorResult { | ||
| private final boolean _success; | ||
| private final int _propertySize; | ||
| private final Map<String, Object> _value; | ||
|
|
||
| public ImpressionPropertiesValidatorResult(boolean success, int propertySize, Map<String, Object> value) { | ||
| _success = success; | ||
| _propertySize = propertySize; | ||
| _value = value; | ||
| } | ||
|
|
||
| public ImpressionPropertiesValidatorResult(boolean success) { | ||
| _success = success; | ||
| _propertySize = 0; | ||
| _value = null; | ||
| } | ||
|
|
||
| public boolean getSuccess() { | ||
| return _success; | ||
| } | ||
|
|
||
| public int getSize() { | ||
| return _propertySize; | ||
| } | ||
|
|
||
| public Map<String, Object> getValue() { | ||
| return _value; | ||
| } | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -565,7 +565,7 @@ public void attributesWork() { | |
| ); | ||
|
|
||
| assertEquals("on", client.getTreatment("[email protected]", test)); | ||
| assertEquals("on", client.getTreatment("[email protected]", test, null)); | ||
| assertEquals("on", client.getTreatment("[email protected]", test, new HashMap<>())); | ||
| assertEquals("on", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of())); | ||
| assertEquals("on", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of("age", 10))); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of("age", 9))); | ||
|
|
@@ -599,7 +599,7 @@ public void attributesWork2() { | |
| ); | ||
|
|
||
| assertEquals("off", client.getTreatment("[email protected]", test)); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, null)); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, new HashMap<>())); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of())); | ||
|
|
||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of("age", 10))); | ||
|
|
@@ -634,7 +634,7 @@ public void attributesGreaterThanNegativeNumber() { | |
| ); | ||
|
|
||
| assertEquals("off", client.getTreatment("[email protected]", test)); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, null)); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, new HashMap<>())); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of())); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of("age", 10))); | ||
| assertEquals("on", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of("age", -20))); | ||
|
|
@@ -671,7 +671,7 @@ public void attributesForSets() { | |
| ); | ||
|
|
||
| assertEquals("off", client.getTreatment("[email protected]", test)); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, null)); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, new HashMap<>())); | ||
|
|
||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of())); | ||
| assertEquals("off", client.getTreatment("[email protected]", test, ImmutableMap.<String, Object>of("products", Lists.newArrayList()))); | ||
|
|
@@ -1894,7 +1894,7 @@ public void testTreatmentsByFlagSet() { | |
| Map<String, String> getTreatmentResult; | ||
| for (int i = 0; i < numKeys; i++) { | ||
| String randomKey = RandomStringUtils.random(10); | ||
| getTreatmentResult = client.getTreatmentsByFlagSet(randomKey, "set1", null); | ||
| getTreatmentResult = client.getTreatmentsByFlagSet(randomKey, "set1", new HashMap<>()); | ||
| assertEquals("on", getTreatmentResult.get(test)); | ||
| } | ||
| verify(splitCacheConsumer, times(numKeys)).fetchMany(new ArrayList<>(Arrays.asList(test))); | ||
|
|
@@ -1927,7 +1927,7 @@ public void testTreatmentsByFlagSetInvalid() { | |
| new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer), TELEMETRY_STORAGE, TELEMETRY_STORAGE, | ||
| flagSetsFilter | ||
| ); | ||
| assertTrue(client.getTreatmentsByFlagSet(RandomStringUtils.random(10), "", null).isEmpty()); | ||
| assertTrue(client.getTreatmentsByFlagSet(RandomStringUtils.random(10), "", new HashMap<>()).isEmpty()); | ||
| } | ||
|
|
||
| @Test | ||
|
|
@@ -1974,7 +1974,7 @@ public void testTreatmentsByFlagSets() { | |
| Map<String, String> getTreatmentResult; | ||
| for (int i = 0; i < numKeys; i++) { | ||
| String randomKey = RandomStringUtils.random(10); | ||
| getTreatmentResult = client.getTreatmentsByFlagSets(randomKey, Arrays.asList("set1", "set3"), null); | ||
| getTreatmentResult = client.getTreatmentsByFlagSets(randomKey, Arrays.asList("set1", "set3"), new HashMap<>()); | ||
| assertEquals("on", getTreatmentResult.get(test)); | ||
| assertEquals("on", getTreatmentResult.get(test2)); | ||
| } | ||
|
|
@@ -2081,4 +2081,81 @@ public void treatmentsWorksAndHasConfigFlagSets() { | |
|
|
||
| verify(splitCacheConsumer, times(1)).fetchMany(anyList()); | ||
| } | ||
|
|
||
| @Test | ||
| public void impressionPropertiesTest() { | ||
| String test = "test1"; | ||
|
|
||
| ParsedCondition age_equal_to_0_should_be_on = new ParsedCondition(ConditionType.ROLLOUT, | ||
| CombiningMatcher.of("age", new EqualToMatcher(-20, DataType.NUMBER)), | ||
| Lists.newArrayList(partition("on", 100)), | ||
| "foolabel" | ||
| ); | ||
|
|
||
| List<ParsedCondition> conditions = Lists.newArrayList(age_equal_to_0_should_be_on); | ||
| ParsedSplit parsedSplit = ParsedSplit.createParsedSplitForTests(test, 123, false, Treatments.OFF, conditions, null, 1, 1, new HashSet<>(Arrays.asList("set")), true); | ||
| Map<String, ParsedSplit> parsedSplits = new HashMap<>(); | ||
| parsedSplits.put(test, parsedSplit); | ||
|
|
||
| SplitCacheConsumer splitCacheConsumer = mock(SplitCacheConsumer.class); | ||
| SegmentCacheConsumer segmentCacheConsumer = mock(SegmentCacheConsumer.class); | ||
| when(splitCacheConsumer.get(test)).thenReturn(parsedSplit); | ||
| when(splitCacheConsumer.fetchMany(Arrays.asList(test))).thenReturn(parsedSplits); | ||
| Map<String, HashSet<String>> splits = new HashMap<>(); | ||
| splits.put("set", new HashSet<>(Arrays.asList(test))); | ||
| when(splitCacheConsumer.getNamesByFlagSets(Arrays.asList("set"))).thenReturn(splits); | ||
|
|
||
| SDKReadinessGates gates = mock(SDKReadinessGates.class); | ||
| ImpressionsManager impressionsManager = mock(ImpressionsManager.class); | ||
| SplitClientImpl client = new SplitClientImpl( | ||
| mock(SplitFactory.class), | ||
| splitCacheConsumer, | ||
| impressionsManager, | ||
| NoopEventsStorageImp.create(), | ||
| config, | ||
| gates, | ||
| new EvaluatorImp(splitCacheConsumer, segmentCacheConsumer), TELEMETRY_STORAGE, TELEMETRY_STORAGE, | ||
| new FlagSetsFilterImpl(new HashSet<>()) | ||
| ); | ||
| Map<String, Object> attributes = ImmutableMap.<String, Object>of("age", -20, "acv", "1000000"); | ||
| EvaluationOptions properties = new EvaluationOptions(new HashMap<String, Object>() | ||
| {{ | ||
| put("prop2", "val2"); | ||
| put("prop1", "val1"); | ||
| }}); | ||
| Map<String, String> result = new HashMap<>(); | ||
| result.put(test, Treatments.ON); | ||
| List<String> split_names = Arrays.asList(test); | ||
|
|
||
| assertEquals("on", client.getTreatment("[email protected]", test, attributes, properties)); | ||
| assertEquals("on", client.getTreatmentWithConfig("[email protected]", test, attributes, properties).treatment()); | ||
| assertEquals("on", client.getTreatments("[email protected]", Arrays.asList(test), attributes, properties).get(test)); | ||
| assertEquals("on", client.getTreatmentsWithConfig("[email protected]", Arrays.asList(test), attributes, properties).get(test).treatment()); | ||
| assertEquals("on", client.getTreatmentsByFlagSet("[email protected]", "set", attributes, properties).get(test)); | ||
| assertEquals("on", client.getTreatmentsByFlagSets("[email protected]", Arrays.asList("set"), attributes, properties).get(test)); | ||
| assertEquals("on", client.getTreatmentsWithConfigByFlagSet("[email protected]", "set", attributes, properties).get(test).treatment()); | ||
| assertEquals("on", client.getTreatmentsWithConfigByFlagSets("[email protected]", Arrays.asList("set"), attributes, properties).get(test).treatment()); | ||
| assertEquals("on", client.getTreatment(new Key("[email protected]", "[email protected]"), test, attributes, properties)); | ||
| assertEquals("on", client.getTreatmentWithConfig(new Key("[email protected]", "[email protected]"), test, attributes, properties).treatment()); | ||
| assertEquals("on", client.getTreatments(new Key("[email protected]", "[email protected]"), Arrays.asList(test), attributes, properties).get(test)); | ||
| assertEquals("on", client.getTreatmentsWithConfig(new Key("[email protected]", "[email protected]"), Arrays.asList(test), attributes, properties).get(test).treatment()); | ||
| assertEquals("on", client.getTreatmentsByFlagSet(new Key("[email protected]", "[email protected]"), "set", attributes, properties).get(test)); | ||
| assertEquals("on", client.getTreatmentsByFlagSets(new Key("[email protected]", "[email protected]"), Arrays.asList("set"), attributes, properties).get(test)); | ||
| assertEquals("on", client.getTreatmentsWithConfigByFlagSet(new Key("[email protected]", "[email protected]"), "set", attributes, properties).get(test).treatment()); | ||
| assertEquals("on", client.getTreatmentsWithConfigByFlagSets(new Key("[email protected]", "[email protected]"), Arrays.asList("set"), attributes, properties).get(test).treatment()); | ||
|
|
||
| ArgumentCaptor<List> impressionCaptor = ArgumentCaptor.forClass(List.class); | ||
| verify(impressionsManager, times(16)).track(impressionCaptor.capture()); | ||
| assertNotNull(impressionCaptor.getValue()); | ||
|
|
||
| DecoratedImpression impression = (DecoratedImpression) impressionCaptor.getAllValues().get(0).get(0); | ||
| assertEquals("[email protected]", impression.impression().key()); | ||
| assertEquals("{\"prop2\":\"val2\",\"prop1\":\"val1\"}", impression.impression().properties()); | ||
|
|
||
| for (int i=1; i<=15; i++) { | ||
| impression = (DecoratedImpression) impressionCaptor.getAllValues().get(i).get(0); | ||
| assertEquals("bilal" + i + "@codigo.com", impression.impression().key()); | ||
| assertEquals("{\"prop2\":\"val2\",\"prop1\":\"val1\"}", impression.impression().properties()); | ||
| } | ||
| } | ||
| } | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.