Skip to content

Commit 3a41831

Browse files
authored
Merge pull request #496 from splitio/unsupported-matcher-flow
Unsupported matcher flow
2 parents 8fa0c9c + 8d4bc04 commit 3a41831

File tree

3 files changed

+64
-0
lines changed

3 files changed

+64
-0
lines changed

client/src/main/java/io/split/engine/evaluator/Labels.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ public class Labels {
66
public static final String KILLED = "killed";
77
public static final String DEFINITION_NOT_FOUND = "definition not found";
88
public static final String EXCEPTION = "exception";
9+
public static final String UNSUPPORTED_MATCHER = "unsupported matcher type";
910
}

client/src/main/java/io/split/engine/experiments/SplitParser.java

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import io.split.client.dtos.MatcherGroup;
77
import io.split.client.dtos.Partition;
88
import io.split.client.dtos.Split;
9+
import io.split.client.dtos.ConditionType;
10+
import io.split.client.dtos.MatcherType;
11+
import io.split.engine.evaluator.Labels;
912
import io.split.engine.matchers.AllKeysMatcher;
1013
import io.split.engine.matchers.AttributeMatcher;
1114
import io.split.engine.matchers.BetweenMatcher;
@@ -59,6 +62,12 @@ private ParsedSplit parseWithoutExceptionHandling(Split split) {
5962

6063
for (Condition condition : split.conditions) {
6164
List<Partition> partitions = condition.partitions;
65+
if (checkUnsupportedMatcherExist(condition.matcherGroup.matchers)) {
66+
_log.error("Unsupported matcher type found for feature flag: " + split.name + " , will revert to default template matcher.");
67+
parsedConditionList.clear();
68+
parsedConditionList.add(getTemplateCondition());
69+
break;
70+
}
6271
CombiningMatcher matcher = toMatcher(condition.matcherGroup);
6372
parsedConditionList.add(new ParsedCondition(condition.conditionType, matcher, partitions, condition.label));
6473
}
@@ -67,6 +76,34 @@ private ParsedSplit parseWithoutExceptionHandling(Split split) {
6776
split.changeNumber, split.trafficAllocation, split.trafficAllocationSeed, split.algo, split.configurations, split.sets);
6877
}
6978

79+
private boolean checkUnsupportedMatcherExist(List<io.split.client.dtos.Matcher> matchers) {
80+
MatcherType typeCheck = null;
81+
for (io.split.client.dtos.Matcher matcher : matchers) {
82+
typeCheck = null;
83+
try {
84+
typeCheck = matcher.matcherType;
85+
} catch (NullPointerException e) {
86+
// If the exception is caught, it means unsupported matcher
87+
break;
88+
}
89+
}
90+
if (typeCheck != null) return false;
91+
return true;
92+
}
93+
94+
private ParsedCondition getTemplateCondition() {
95+
List<Partition> templatePartitions = Lists.newArrayList();
96+
Partition partition = new Partition();
97+
partition.treatment = "control";
98+
partition.size = 100;
99+
templatePartitions.add(partition);
100+
return new ParsedCondition(
101+
ConditionType.ROLLOUT,
102+
CombiningMatcher.of(new AllKeysMatcher()),
103+
templatePartitions,
104+
Labels.UNSUPPORTED_MATCHER);
105+
}
106+
70107
private CombiningMatcher toMatcher(MatcherGroup matcherGroup) {
71108
List<io.split.client.dtos.Matcher> matchers = matcherGroup.matchers;
72109
checkArgument(!matchers.isEmpty());

client/src/test/java/io/split/engine/experiments/SplitParserTest.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package io.split.engine.experiments;
22

33
import com.google.common.collect.Lists;
4+
import io.split.client.utils.Json;
45
import io.split.storages.SegmentCache;
56
import io.split.storages.memory.SegmentCacheInMemoryImpl;
67
import io.split.client.dtos.*;
8+
import io.split.engine.evaluator.Labels;
79
import io.split.engine.ConditionsTestUtil;
810
import io.split.engine.SDKReadinessGates;
911
import io.split.engine.matchers.AttributeMatcher;
@@ -39,6 +41,7 @@
3941
import static org.hamcrest.Matchers.equalTo;
4042
import static org.hamcrest.Matchers.is;
4143
import static org.junit.Assert.assertThat;
44+
import static org.junit.Assert.assertTrue;
4245

4346
/**
4447
* Tests for ExperimentParser
@@ -529,6 +532,29 @@ public void contains_string() {
529532
set_matcher_test(c, m);
530533
}
531534

535+
@Test
536+
public void unsupportedMatcher() {
537+
SplitParser parser = new SplitParser();
538+
String splitWithUndefinedMatcher = "{\"since\":-1,\"till\": 1457726098069,\"splits\": [{ \"changeNumber\": 123, \"trafficTypeName\": \"user\", \"name\": \"some_name\","
539+
+ "\"trafficAllocation\": 100, \"trafficAllocationSeed\": 123456, \"seed\": 321654, \"status\": \"ACTIVE\","
540+
+ "\"killed\": false, \"defaultTreatment\": \"off\", \"algo\": 2,\"conditions\": [{ \"partitions\": ["
541+
+ "{\"treatment\": \"on\", \"size\": 50}, {\"treatment\": \"off\", \"size\": 50}], \"contitionType\": \"ROLLOUT\","
542+
+ "\"label\": \"some_label\", \"matcherGroup\": { \"matchers\": [{ \"matcherType\": \"UNKNOWN\", \"negate\": false}],"
543+
+ "\"combiner\": \"AND\"}}], \"sets\": [\"set1\"]}]}";
544+
SplitChange change = Json.fromJson(splitWithUndefinedMatcher, SplitChange.class);
545+
for (Split split : change.splits) {
546+
// should not cause exception
547+
ParsedSplit parsedSplit = parser.parse(split);
548+
for (ParsedCondition parsedCondition : parsedSplit.parsedConditions()) {
549+
assertTrue(parsedCondition.label() == Labels.UNSUPPORTED_MATCHER);
550+
for (AttributeMatcher matcher : parsedCondition.matcher().attributeMatchers()) {
551+
// Check the matcher is ALL_KEYS
552+
assertTrue(matcher.matcher().toString().equals(" in segment all"));
553+
}
554+
}
555+
}
556+
}
557+
532558
public void set_matcher_test(Condition c, io.split.engine.matchers.Matcher m) {
533559

534560
// SegmentSynchronizationTask segmentFetcher = new SegmentSynchronizationTaskImp(fetcherMap);

0 commit comments

Comments
 (0)