Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion client/src/main/java/io/split/client/dtos/Excluded.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

public class Excluded {
public List<String> keys;
public List<String> segments;
public List<ExcludedSegments> segments;
}
12 changes: 12 additions & 0 deletions client/src/main/java/io/split/client/dtos/ExcludedSegments.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package io.split.client.dtos;

public class ExcludedSegments {
public ExcludedSegments() {}
public ExcludedSegments(String type, String name) {
this.type = type;
this.name = name;
}

public String type;
public String name;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.split.engine.experiments;

import com.google.common.collect.ImmutableList;
import io.split.client.dtos.ExcludedSegments;
import io.split.engine.matchers.AttributeMatcher;
import io.split.engine.matchers.UserDefinedSegmentMatcher;

Expand All @@ -15,15 +16,15 @@ public class ParsedRuleBasedSegment {
private final String _trafficTypeName;
private final long _changeNumber;
private final List<String> _excludedKeys;
private final List<String> _excludedSegments;
private final List<ExcludedSegments> _excludedSegments;

public static ParsedRuleBasedSegment createParsedRuleBasedSegmentForTests(
String ruleBasedSegment,
List<ParsedCondition> matcherAndSplits,
String trafficTypeName,
long changeNumber,
List<String> excludedKeys,
List<String> excludedSegments
List<ExcludedSegments> excludedSegments
) {
return new ParsedRuleBasedSegment(
ruleBasedSegment,
Expand All @@ -41,7 +42,7 @@ public ParsedRuleBasedSegment(
String trafficTypeName,
long changeNumber,
List<String> excludedKeys,
List<String> excludedSegments
List<ExcludedSegments> excludedSegments
) {
_ruleBasedSegment = ruleBasedSegment;
_parsedCondition = ImmutableList.copyOf(matcherAndSplits);
Expand All @@ -64,7 +65,7 @@ public List<ParsedCondition> parsedConditions() {
public long changeNumber() {return _changeNumber;}

public List<String> excludedKeys() {return _excludedKeys;}
public List<String> excludedSegments() {return _excludedSegments;}
public List<ExcludedSegments> excludedSegments() {return _excludedSegments;}

@Override
public int hashCode() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.split.engine.matchers;

import io.split.client.dtos.ExcludedSegments;
import io.split.engine.evaluator.EvaluationContext;
import io.split.engine.experiments.ParsedCondition;
import io.split.engine.experiments.ParsedRuleBasedSegment;
Expand All @@ -17,6 +18,8 @@
* @author adil
*/
public class RuleBasedSegmentMatcher implements Matcher {
private final String standardType = "standard";

private final String _segmentName;

public RuleBasedSegmentMatcher(String segmentName) {
Expand All @@ -37,8 +40,8 @@ public boolean match(Object matchValue, String bucketingKey, Map<String, Object>
return false;
}

for (String segmentName: parsedRuleBasedSegment.excludedSegments()) {
if (evaluationContext.getSegmentCache().isInSegment(segmentName, (String) matchValue)) {
for (ExcludedSegments segment: parsedRuleBasedSegment.excludedSegments()) {
if (segment.type.equals(standardType) && evaluationContext.getSegmentCache().isInSegment(segment.name, (String) matchValue)) {
return false;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import io.split.client.dtos.ConditionType;
import io.split.client.dtos.ExcludedSegments;
import io.split.client.dtos.MatcherCombiner;
import io.split.client.dtos.SplitChange;
import io.split.client.utils.Json;
Expand All @@ -15,18 +16,23 @@
import org.junit.Test;

import java.util.ArrayList;
import java.util.List;

import static io.split.client.utils.RuleBasedSegmentProcessor.processRuleBasedSegmentChanges;

public class ParsedRuleBasedSegmentTest {

@Test
public void works() {
List<ExcludedSegments> excludedSegments = new ArrayList<>();
excludedSegments.add(new ExcludedSegments("standard","segment1"));
excludedSegments.add(new ExcludedSegments("standard","segment2"));

AttributeMatcher segmentMatcher = AttributeMatcher.vanilla(new UserDefinedSegmentMatcher("employees"));
CombiningMatcher segmentCombiningMatcher = new CombiningMatcher(MatcherCombiner.AND, Lists.newArrayList(segmentMatcher));
ParsedRuleBasedSegment parsedRuleBasedSegment = new ParsedRuleBasedSegment("another_rule_based_segment",
Lists.newArrayList(new ParsedCondition(ConditionType.WHITELIST, segmentCombiningMatcher, null, "label")),"user",
123, Lists.newArrayList("mauro@test.io","gaston@test.io"), Lists.newArrayList("segment1", "segment2"));
Lists.newArrayList(new ParsedCondition(ConditionType.WHITELIST, segmentCombiningMatcher, null, "label")), "user",
123, Lists.newArrayList("mauro@test.io", "gaston@test.io"), excludedSegments);

Assert.assertEquals(Sets.newHashSet("employees"), parsedRuleBasedSegment.getSegmentsNames());
Assert.assertEquals("another_rule_based_segment", parsedRuleBasedSegment.ruleBasedSegment());
Expand All @@ -48,15 +54,15 @@ public void worksWithoutExcluded() {
Assert.assertTrue(toUpdate.getToAdd().get(0).excludedSegments().isEmpty());

load = "{\"ff\":{\"s\":-1,\"t\":-1,\"d\":[]},\"rbs\":{\"s\":-1,\"t\":1457726098069,\"d\":[{ \"changeNumber\": 123, \"trafficTypeName\": \"user\", \"name\": \"some_name\","
+ "\"status\": \"ACTIVE\",\"excluded\":{\"segments\":[\"segment1\"]},\"conditions\": [{\"contitionType\": \"ROLLOUT\","
+ "\"status\": \"ACTIVE\",\"excluded\":{\"segments\":[{\"type\": \"standard\",\"name\":\"segment1\"}]},\"conditions\": [{\"contitionType\": \"ROLLOUT\","
+ "\"label\": \"some_label\", \"matcherGroup\": { \"matchers\": [{ \"matcherType\": \"ALL_KEYS\", \"negate\": false}],"
+ "\"combiner\": \"AND\"}}]}]}}";
change = Json.fromJson(load, SplitChange.class);
toUpdate = processRuleBasedSegmentChanges(parser, change.ruleBasedSegments.d);
Assert.assertTrue(toUpdate.getToAdd().get(0).excludedKeys().isEmpty());

load = "{\"ff\":{\"s\":-1,\"t\":-1,\"d\":[]},\"rbs\":{\"s\":-1,\"t\":1457726098069,\"d\":[{ \"changeNumber\": 123, \"trafficTypeName\": \"user\", \"name\": \"some_name\","
+ "\"status\": \"ACTIVE\",\"excluded\":{\"segments\":[\"segment1\"], \"keys\":null},\"conditions\": [{\"contitionType\": \"ROLLOUT\","
+ "\"status\": \"ACTIVE\",\"excluded\":{\"segments\":[{\"type\": \"standard\",\"name\":\"segment1\"}], \"keys\":null},\"conditions\": [{\"contitionType\": \"ROLLOUT\","
+ "\"label\": \"some_label\", \"matcherGroup\": { \"matchers\": [{ \"matcherType\": \"ALL_KEYS\", \"negate\": false}],"
+ "\"combiner\": \"AND\"}}]}]}}";
change = Json.fromJson(load, SplitChange.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.split.storages.memory;

import com.google.common.collect.Sets;
import io.split.client.dtos.ExcludedSegments;
import io.split.client.dtos.MatcherCombiner;
import io.split.engine.experiments.ParsedRuleBasedSegment;
import io.split.engine.experiments.ParsedCondition;
Expand All @@ -14,6 +15,9 @@
import org.junit.Test;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.List;

public class RuleBasedSegmentCacheInMemoryImplTest extends TestCase {

@Test
Expand All @@ -35,18 +39,25 @@ public void testAddAndDeleteSegment(){

@Test
public void testMultipleSegment(){
List<ExcludedSegments> excludedSegments = new ArrayList<>();
excludedSegments.add(new ExcludedSegments("standard","segment1"));
excludedSegments.add(new ExcludedSegments("standard","segment3"));

RuleBasedSegmentCacheInMemoryImp ruleBasedSegmentCache = new RuleBasedSegmentCacheInMemoryImp();
AttributeMatcher whiteListMatcher = AttributeMatcher.vanilla(new WhitelistMatcher(Lists.newArrayList("test_1", "admin")));
CombiningMatcher whitelistCombiningMatcher = new CombiningMatcher(MatcherCombiner.AND, Lists.newArrayList(whiteListMatcher));
ParsedRuleBasedSegment parsedRuleBasedSegment1 = new ParsedRuleBasedSegment("sample_rule_based_segment",
Lists.newArrayList(new ParsedCondition(ConditionType.WHITELIST, whitelistCombiningMatcher, null, "label")),"user",
123, Lists.newArrayList("mauro@test.io","gaston@test.io"), Lists.newArrayList(Lists.newArrayList("segment1", "segment3")));
123, Lists.newArrayList("mauro@test.io","gaston@test.io"), excludedSegments);

excludedSegments.clear();
excludedSegments.add(new ExcludedSegments("standard","segment1"));
excludedSegments.add(new ExcludedSegments("standard","segment2"));
AttributeMatcher segmentMatcher = AttributeMatcher.vanilla(new UserDefinedSegmentMatcher("employees"));
CombiningMatcher segmentCombiningMatcher = new CombiningMatcher(MatcherCombiner.AND, Lists.newArrayList(segmentMatcher));
ParsedRuleBasedSegment parsedRuleBasedSegment2 = new ParsedRuleBasedSegment("another_rule_based_segment",
Lists.newArrayList(new ParsedCondition(ConditionType.WHITELIST, segmentCombiningMatcher, null, "label")),"user",
123, Lists.newArrayList("mauro@test.io","gaston@test.io"), Lists.newArrayList("segment1", "segment2"));
123, Lists.newArrayList("mauro@test.io","gaston@test.io"), excludedSegments);

ruleBasedSegmentCache.update(Lists.newArrayList(parsedRuleBasedSegment1, parsedRuleBasedSegment2), null, 123);
assertEquals(Lists.newArrayList("another_rule_based_segment", "sample_rule_based_segment"), ruleBasedSegmentCache.ruleBasedSegmentNames());
Expand Down