Skip to content

Commit 4abdc3e

Browse files
authored
Merge pull request #501 from splitio/semver-inlist-matcher
Semver inlist matcher
2 parents e3ff49c + a75b063 commit 4abdc3e

File tree

8 files changed

+199
-5
lines changed

8 files changed

+199
-5
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,7 @@ public enum MatcherType {
3434

3535
/* Semver matchers */
3636
EQUAL_TO_SEMVER,
37-
GREATER_THAN_OR_EQUAL_TO_SEMVER
37+
GREATER_THAN_OR_EQUAL_TO_SEMVER,
38+
LESS_THAN_OR_EQUAL_TO_SEMVER,
39+
IN_LIST_SEMVER
3840
}

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import io.split.engine.matchers.strings.StartsWithAnyOfMatcher;
3131
import io.split.engine.matchers.strings.WhitelistMatcher;
3232
import io.split.engine.matchers.GreaterThanOrEqualToSemverMatcher;
33+
import io.split.engine.matchers.LessThanOrEqualToSemverMatcher;
34+
import io.split.engine.matchers.InListSemverMatcher;
3335

3436
import org.slf4j.Logger;
3537
import org.slf4j.LoggerFactory;
@@ -197,13 +199,21 @@ private AttributeMatcher toMatcher(Matcher matcher) {
197199
delegate = new BooleanMatcher(matcher.booleanMatcherData);
198200
break;
199201
case EQUAL_TO_SEMVER:
200-
checkNotNull(matcher.stringMatcherData);
202+
checkNotNull(matcher.stringMatcherData, "stringMatcherData is required for EQUAL_TO_SEMVER matcher type");
201203
delegate = new EqualToSemverMatcher(matcher.stringMatcherData);
202204
break;
203205
case GREATER_THAN_OR_EQUAL_TO_SEMVER:
204-
checkNotNull(matcher.stringMatcherData);
206+
checkNotNull(matcher.stringMatcherData, "stringMatcherData is required for GREATER_THAN_OR_EQUAL_TO_SEMVER matcher type");
205207
delegate = new GreaterThanOrEqualToSemverMatcher(matcher.stringMatcherData);
206208
break;
209+
case LESS_THAN_OR_EQUAL_TO_SEMVER:
210+
checkNotNull(matcher.stringMatcherData, "stringMatcherData is required for LESS_THAN_OR_EQUAL_SEMVER matcher type");
211+
delegate = new LessThanOrEqualToSemverMatcher(matcher.stringMatcherData);
212+
break;
213+
case IN_LIST_SEMVER:
214+
checkNotNull(matcher.whitelistMatcherData, "whitelistMatcherData is required for IN_LIST_SEMVER matcher type");
215+
delegate = new InListSemverMatcher(matcher.whitelistMatcherData.whitelist);
216+
break;
207217
default:
208218
throw new IllegalArgumentException("Unknown matcher type: " + matcher.matcherType);
209219
}

client/src/main/java/io/split/engine/matchers/EqualToSemverMatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public boolean match(Object matchValue, String bucketingKey, Map<String, Object>
2929
public String toString() {
3030
StringBuilder bldr = new StringBuilder();
3131
bldr.append("== ");
32-
bldr.append(_semVer);
32+
bldr.append(_semVer.Version());
3333
return bldr.toString();
3434
}
3535

client/src/main/java/io/split/engine/matchers/GreaterThanOrEqualToSemverMatcher.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public boolean match(Object matchValue, String bucketingKey, Map<String, Object>
2929
public String toString() {
3030
StringBuilder bldr = new StringBuilder();
3131
bldr.append("== ");
32-
bldr.append(_semVer);
32+
bldr.append(_semVer.Version());
3333
return bldr.toString();
3434
}
3535

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package io.split.engine.matchers;
2+
3+
import io.split.engine.evaluator.EvaluationContext;
4+
5+
import java.util.Collection;
6+
import java.util.HashSet;
7+
import java.util.Map;
8+
import java.util.Set;
9+
10+
public class InListSemverMatcher implements Matcher {
11+
12+
private final Set<Semver> _semverlist = new HashSet<>();
13+
14+
public InListSemverMatcher(Collection<String> whitelist) {
15+
for (String item : whitelist) {
16+
Semver semver = Semver.build(item);
17+
if (semver == null) continue;
18+
19+
_semverlist.add(semver);
20+
}
21+
}
22+
23+
@Override
24+
public boolean match(Object matchValue, String bucketingKey, Map<String, Object> attributes, EvaluationContext evaluationContext) {
25+
if (matchValue == null || _semverlist.isEmpty()) {
26+
return false;
27+
}
28+
Semver matchSemver = Semver.build(matchValue.toString());
29+
if (matchSemver == null) {
30+
return false;
31+
}
32+
33+
for (Semver semverItem : _semverlist) {
34+
if (semverItem.Version().equals(matchSemver.Version())) return true;
35+
36+
}
37+
return false;
38+
}
39+
40+
@Override
41+
public String toString() {
42+
StringBuilder bldr = new StringBuilder();
43+
bldr.append("in semver list ");
44+
boolean first = true;
45+
46+
for (Semver item : _semverlist) {
47+
if (!first) {
48+
bldr.append(',');
49+
}
50+
bldr.append('"');
51+
bldr.append(item.Version());
52+
bldr.append('"');
53+
first = false;
54+
}
55+
56+
bldr.append("]");
57+
return bldr.toString();
58+
}
59+
60+
@Override
61+
public int hashCode() {
62+
int result = 17;
63+
result = 31 * result + _semverlist.hashCode();
64+
return result;
65+
}
66+
67+
@Override
68+
public boolean equals(Object obj) {
69+
if (obj == null) return false;
70+
if (this == obj) return true;
71+
if (!(obj instanceof InListSemverMatcher)) return false;
72+
73+
InListSemverMatcher other = (InListSemverMatcher) obj;
74+
75+
return _semverlist == other._semverlist;
76+
}
77+
78+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package io.split.engine.matchers;
2+
3+
import io.split.engine.evaluator.EvaluationContext;
4+
5+
import java.util.Map;
6+
7+
public class LessThanOrEqualToSemverMatcher implements Matcher {
8+
9+
private final Semver _semVer;
10+
11+
public LessThanOrEqualToSemverMatcher(String semVer) {
12+
_semVer = Semver.build(semVer);
13+
}
14+
15+
@Override
16+
public boolean match(Object matchValue, String bucketingKey, Map<String, Object> attributes, EvaluationContext evaluationContext) {
17+
if (matchValue == null) {
18+
return false;
19+
}
20+
Semver matchSemver = Semver.build(matchValue.toString());
21+
if (matchSemver == null) {
22+
return false;
23+
}
24+
25+
return _semVer != null && matchSemver.Compare(_semVer) <= 0;
26+
}
27+
28+
@Override
29+
public String toString() {
30+
StringBuilder bldr = new StringBuilder();
31+
bldr.append("== ");
32+
bldr.append(_semVer.Version());
33+
return bldr.toString();
34+
}
35+
36+
@Override
37+
public int hashCode() {
38+
int result = 17;
39+
result = 31 * result + _semVer.hashCode();
40+
return result;
41+
}
42+
43+
@Override
44+
public boolean equals(Object obj) {
45+
if (obj == null) return false;
46+
if (this == obj) return true;
47+
if (!(obj instanceof LessThanOrEqualToSemverMatcher)) return false;
48+
49+
LessThanOrEqualToSemverMatcher other = (LessThanOrEqualToSemverMatcher) obj;
50+
51+
return _semVer == other._semVer;
52+
}
53+
54+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package io.split.engine.matchers;
2+
3+
import com.google.common.collect.Lists;
4+
import org.junit.Test;
5+
6+
import java.util.List;
7+
8+
import static org.junit.Assert.assertTrue;
9+
10+
/**
11+
* Tests for EqualToSemverMatcher
12+
*/
13+
14+
public class InListSemverMatcherTest {
15+
16+
@Test
17+
public void works() {
18+
List<String> whitelist = Lists.newArrayList("2.1.8", "3.4.0");
19+
InListSemverMatcher inListSemverMatcher = new InListSemverMatcher(whitelist);
20+
21+
assertTrue( inListSemverMatcher.match("2.1.8", null, null, null) == true);
22+
assertTrue( inListSemverMatcher.match("2.1.9", null, null, null) == false);
23+
assertTrue( inListSemverMatcher.match("2.1.8-rc", null, null, null) == false);
24+
assertTrue( inListSemverMatcher.match("3.4.0", null, null, null) == true);
25+
assertTrue( inListSemverMatcher.match("3.4.0+build", null, null, null) == false);
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package io.split.engine.matchers;
2+
3+
import org.junit.Test;
4+
5+
import static org.junit.Assert.assertTrue;
6+
7+
/**
8+
* Tests for EqualToSemverMatcher
9+
*/
10+
11+
public class LessThanOrEqualToSemverMatcherTest {
12+
13+
@Test
14+
public void works() {
15+
LessThanOrEqualToSemverMatcher lessThanOrEqualToSemverMatcher = new LessThanOrEqualToSemverMatcher("2.1.8");
16+
17+
assertTrue( lessThanOrEqualToSemverMatcher.match("2.1.8", null, null, null) == true);
18+
assertTrue( lessThanOrEqualToSemverMatcher.match("2.1.9", null, null, null) == false);
19+
assertTrue( lessThanOrEqualToSemverMatcher.match("2.1.8-rc", null, null, null) == true);
20+
assertTrue( lessThanOrEqualToSemverMatcher.match("2.0.10", null, null, null) == true);
21+
assertTrue( lessThanOrEqualToSemverMatcher.match("2.1.8+build", null, null, null) == true);
22+
}
23+
}

0 commit comments

Comments
 (0)