Skip to content

Commit

Permalink
Merge pull request #504 from splitio/Feature/Semver
Browse files Browse the repository at this point in the history
Merge semver to dev
  • Loading branch information
mmelograno authored May 15, 2024
2 parents 7506116 + b754a5d commit 426ea5a
Show file tree
Hide file tree
Showing 37 changed files with 1,506 additions and 26 deletions.
8 changes: 6 additions & 2 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
4.12.0 (XXX XX, 2024)
- Added support for injecting user-defined custom headers for all outgoing HTTP calls, typically useful for proxy authentication purposes.
4.12.0 (May 15, 2024)
- Added support for targeting rules based on semantic versions (https://semver.org/).
- Added the logic to handle correctly when the SDK receives an unsupported Matcher type.
- Enhanced SDK Headers for Authorization Frameworks
- Cleaned unused imports and renaming some methods
- Fixed empty token handler thanks to @hpark-miovision

4.11.1 (Feb 29, 2024)
- Fixed deadlock in UniqueKeysTracker when sending Unique Keys.
Expand Down
2 changes: 1 addition & 1 deletion client/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<groupId>io.split.client</groupId>
<artifactId>java-client-parent</artifactId>
<version>4.12.0-rc3</version>
<version>4.12.0</version>
</parent>
<artifactId>java-client</artifactId>
<packaging>jar</packaging>
Expand Down
11 changes: 11 additions & 0 deletions client/src/main/java/io/split/Spec.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.split;

public final class Spec {

private Spec() {
// restrict instantiation
}

public static final String SPEC_VERSION = "1.1";
}

12 changes: 8 additions & 4 deletions client/src/main/java/io/split/client/HttpSplitChangeFetcher.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.split.client;

import com.google.common.annotations.VisibleForTesting;

import io.split.client.dtos.SplitChange;
import io.split.client.dtos.SplitHttpResponse;
import io.split.client.exceptions.UriTooLongException;
Expand All @@ -21,6 +22,7 @@
import java.net.URISyntaxException;

import static com.google.common.base.Preconditions.checkNotNull;
import static io.split.Spec.SPEC_VERSION;

/**
* Created by adilaijaz on 5/30/15.
Expand All @@ -31,6 +33,7 @@ public final class HttpSplitChangeFetcher implements SplitChangeFetcher {
private static final String SINCE = "since";
private static final String TILL = "till";
private static final String SETS = "sets";
private static final String SPEC = "s";
private final SplitHttpClient _client;
private final URI _target;
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;
Expand Down Expand Up @@ -58,13 +61,14 @@ public SplitChange fetch(long since, FetchOptions options) {
long start = System.currentTimeMillis();

try {
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SINCE, "" + since);
if (options.hasCustomCN()) {
uriBuilder.addParameter(TILL, "" + options.targetCN());
}
URIBuilder uriBuilder = new URIBuilder(_target).addParameter(SPEC, "" + SPEC_VERSION);
uriBuilder.addParameter(SINCE, "" + since);
if (!options.flagSetsFilter().isEmpty()) {
uriBuilder.addParameter(SETS, "" + options.flagSetsFilter());
}
if (options.hasCustomCN()) {
uriBuilder.addParameter(TILL, "" + options.targetCN());
}
URI uri = uriBuilder.build();
SplitHttpResponse response = _client.get(uri, options, null);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package io.split.client.dtos;

/**
* Metadata to support the between matcher.
*
* @author adil
*/
public class BetweenStringMatcherData {
public String start;
public String end;
}
1 change: 1 addition & 0 deletions client/src/main/java/io/split/client/dtos/Matcher.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ public class Matcher {
public WhitelistMatcherData whitelistMatcherData;
public UnaryNumericMatcherData unaryNumericMatcherData;
public BetweenMatcherData betweenMatcherData;
public BetweenStringMatcherData betweenStringMatcherData;
public DependencyMatcherData dependencyMatcherData;
public Boolean booleanMatcherData;
public String stringMatcherData;
Expand Down
9 changes: 8 additions & 1 deletion client/src/main/java/io/split/client/dtos/MatcherType.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,12 @@ public enum MatcherType {
EQUAL_TO_BOOLEAN,

/* Dependency Matcher */
IN_SPLIT_TREATMENT
IN_SPLIT_TREATMENT,

/* Semver matchers */
EQUAL_TO_SEMVER,
GREATER_THAN_OR_EQUAL_TO_SEMVER,
LESS_THAN_OR_EQUAL_TO_SEMVER,
IN_LIST_SEMVER,
BETWEEN_SEMVER
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package io.split.client.exceptions;

public class SemverParseException extends Exception {
public SemverParseException(String message) {
super(message);
}
}
2 changes: 1 addition & 1 deletion client/src/main/java/io/split/engine/evaluator/Labels.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public class Labels {
public static final String KILLED = "killed";
public static final String DEFINITION_NOT_FOUND = "definition not found";
public static final String EXCEPTION = "exception";
public static final String UNSUPPORTED_MATCHER = "unsupported matcher type";
public static final String UNSUPPORTED_MATCHER = "targeting rule type unsupported by sdk";
}
26 changes: 26 additions & 0 deletions client/src/main/java/io/split/engine/experiments/SplitParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.split.engine.matchers.GreaterThanOrEqualToMatcher;
import io.split.engine.matchers.LessThanOrEqualToMatcher;
import io.split.engine.matchers.UserDefinedSegmentMatcher;
import io.split.engine.matchers.EqualToSemverMatcher;
import io.split.engine.matchers.collections.ContainsAllOfSetMatcher;
import io.split.engine.matchers.collections.ContainsAnyOfSetMatcher;
import io.split.engine.matchers.collections.EqualToSetMatcher;
Expand All @@ -28,6 +29,11 @@
import io.split.engine.matchers.strings.RegularExpressionMatcher;
import io.split.engine.matchers.strings.StartsWithAnyOfMatcher;
import io.split.engine.matchers.strings.WhitelistMatcher;
import io.split.engine.matchers.GreaterThanOrEqualToSemverMatcher;
import io.split.engine.matchers.LessThanOrEqualToSemverMatcher;
import io.split.engine.matchers.InListSemverMatcher;
import io.split.engine.matchers.BetweenSemverMatcher;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -193,6 +199,26 @@ private AttributeMatcher toMatcher(Matcher matcher) {
+ ". matcher.booleanMatcherData() MUST NOT BE null");
delegate = new BooleanMatcher(matcher.booleanMatcherData);
break;
case EQUAL_TO_SEMVER:
checkNotNull(matcher.stringMatcherData, "stringMatcherData is required for EQUAL_TO_SEMVER matcher type");
delegate = new EqualToSemverMatcher(matcher.stringMatcherData);
break;
case GREATER_THAN_OR_EQUAL_TO_SEMVER:
checkNotNull(matcher.stringMatcherData, "stringMatcherData is required for GREATER_THAN_OR_EQUAL_TO_SEMVER matcher type");
delegate = new GreaterThanOrEqualToSemverMatcher(matcher.stringMatcherData);
break;
case LESS_THAN_OR_EQUAL_TO_SEMVER:
checkNotNull(matcher.stringMatcherData, "stringMatcherData is required for LESS_THAN_OR_EQUAL_SEMVER matcher type");
delegate = new LessThanOrEqualToSemverMatcher(matcher.stringMatcherData);
break;
case IN_LIST_SEMVER:
checkNotNull(matcher.whitelistMatcherData, "whitelistMatcherData is required for IN_LIST_SEMVER matcher type");
delegate = new InListSemverMatcher(matcher.whitelistMatcherData.whitelist);
break;
case BETWEEN_SEMVER:
checkNotNull(matcher.betweenStringMatcherData, "betweenStringMatcherData is required for BETWEEN_SEMVER matcher type");
delegate = new BetweenSemverMatcher(matcher.betweenStringMatcherData.start, matcher.betweenStringMatcherData.end);
break;
default:
throw new IllegalArgumentException("Unknown matcher type: " + matcher.matcherType);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.split.engine.matchers;

import io.split.engine.evaluator.EvaluationContext;

import java.util.Map;

public class BetweenSemverMatcher implements Matcher {

private final Semver _semverStart;
private final Semver _semverEnd;

public BetweenSemverMatcher(String semverStart, String semverEnd) {
_semverStart = Semver.build(semverStart);
_semverEnd = Semver.build(semverEnd);
}

@Override
public boolean match(Object matchValue, String bucketingKey, Map<String, Object> attributes, EvaluationContext evaluationContext) {
if (!(matchValue instanceof String) || _semverStart == null || _semverEnd == null) {
return false;
}
Semver matchSemver = Semver.build(matchValue.toString());
if (matchSemver == null) {
return false;
}

return matchSemver.compare(_semverStart) >= 0 && matchSemver.compare(_semverEnd) <= 0;
}

@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append("between semver ");
bldr.append(_semverStart.version());
bldr.append(" and ");
bldr.append(_semverEnd.version());
return bldr.toString();
}

@Override
public int hashCode() {
int result = 17;
result = 31 * result + _semverStart.hashCode() + _semverEnd.hashCode();
return result;
}

@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (!(obj instanceof BetweenSemverMatcher)) return false;

BetweenSemverMatcher other = (BetweenSemverMatcher) obj;

return _semverStart == other._semverStart && _semverEnd == other._semverEnd;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.split.engine.matchers;

import io.split.engine.evaluator.EvaluationContext;

import java.util.Map;

public class EqualToSemverMatcher implements Matcher {

private final Semver _semVer;

public EqualToSemverMatcher(String semVer) {
_semVer = Semver.build(semVer);
}

@Override
public boolean match(Object matchValue, String bucketingKey, Map<String, Object> attributes, EvaluationContext evaluationContext) {
if (!(matchValue instanceof String) || _semVer == null) {
return false;
}
Semver matchSemver = Semver.build(matchValue.toString());
if (matchSemver == null) {
return false;
}

return matchSemver.version().equals(_semVer.version());
}

@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append("== semver ");
bldr.append(_semVer.version());
return bldr.toString();
}

@Override
public int hashCode() {
int result = 17;
result = 31 * result + _semVer.hashCode();
return result;
}

@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (!(obj instanceof EqualToSemverMatcher)) return false;

EqualToSemverMatcher other = (EqualToSemverMatcher) obj;

return _semVer == other._semVer;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package io.split.engine.matchers;

import io.split.engine.evaluator.EvaluationContext;

import java.util.Map;

public class GreaterThanOrEqualToSemverMatcher implements Matcher {

private final Semver _semVer;

public GreaterThanOrEqualToSemverMatcher(String semVer) {
_semVer = Semver.build(semVer);
}

@Override
public boolean match(Object matchValue, String bucketingKey, Map<String, Object> attributes, EvaluationContext evaluationContext) {
if (!(matchValue instanceof String)|| _semVer == null) {
return false;
}
Semver matchSemver = Semver.build(matchValue.toString());
if (matchSemver == null) {
return false;
}

return matchSemver.compare(_semVer) >= 0;
}

@Override
public String toString() {
StringBuilder bldr = new StringBuilder();
bldr.append(">= semver ");
bldr.append(_semVer.version());
return bldr.toString();
}

@Override
public int hashCode() {
int result = 17;
result = 31 * result + _semVer.hashCode();
return result;
}

@Override
public boolean equals(Object obj) {
if (obj == null) return false;
if (this == obj) return true;
if (!(obj instanceof GreaterThanOrEqualToSemverMatcher)) return false;

GreaterThanOrEqualToSemverMatcher other = (GreaterThanOrEqualToSemverMatcher) obj;

return _semVer == other._semVer;
}

}
Loading

0 comments on commit 426ea5a

Please sign in to comment.