Skip to content

Commit 321279b

Browse files
author
Mike Davis
committed
Add UnknownValueTypeExceptioni.
1 parent 11be296 commit 321279b

15 files changed

+121
-113
lines changed

core-api/src/main/java/com/optimizely/ab/config/audience/UserAttribute.java

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -86,31 +86,32 @@ public Boolean evaluate(ProjectConfig config, Map<String, ?> attributes) {
8686
try {
8787
Match matcher = MatchRegistry.getMatch(match);
8888
Boolean result = matcher.eval(value, userAttributeValue);
89-
9089
if (result == null) {
91-
if (!attributes.containsKey(name)) {
92-
//Missing attribute value
93-
logger.debug("Audience condition \"{}\" evaluated to UNKNOWN because no value was passed for user attribute \"{}\"", this, name);
90+
throw new UnknownValueTypeException();
91+
}
92+
93+
return result;
94+
} catch(UnknownValueTypeException e) {
95+
if (!attributes.containsKey(name)) {
96+
//Missing attribute value
97+
logger.debug("Audience condition \"{}\" evaluated to UNKNOWN because no value was passed for user attribute \"{}\"", this, name);
98+
} else {
99+
//if attribute value is not valid
100+
if (userAttributeValue != null) {
101+
logger.warn(
102+
"Audience condition \"{}\" evaluated to UNKNOWN because a value of type \"{}\" was passed for user attribute \"{}\"",
103+
this,
104+
userAttributeValue.getClass().getCanonicalName(),
105+
name);
94106
} else {
95-
//if attribute value is not valid
96-
if (userAttributeValue != null) {
97-
logger.warn(
98-
"Audience condition \"{}\" evaluated to UNKNOWN because a value of type \"{}\" was passed for user attribute \"{}\"",
99-
this,
100-
userAttributeValue.getClass().getCanonicalName(),
101-
name);
102-
} else {
103-
logger.debug(
104-
"Audience condition \"{}\" evaluated to UNKNOWN because a null value was passed for user attribute \"{}\"",
105-
this,
106-
name);
107-
}
107+
logger.debug(
108+
"Audience condition \"{}\" evaluated to UNKNOWN because a null value was passed for user attribute \"{}\"",
109+
this,
110+
name);
108111
}
109112
}
110-
return result;
111113
} catch (UnknownMatchTypeException | UnexpectedValueTypeException e) {
112-
logger.warn("Audience condition \"{}\" " + e.getMessage(),
113-
this);
114+
logger.warn("Audience condition \"{}\" " + e.getMessage(), this);
114115
} catch (NullPointerException e) {
115116
logger.error("attribute or value null for match {}", match != null ? match : "legacy condition", e);
116117
}

core-api/src/main/java/com/optimizely/ab/config/audience/match/ExactMatch.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ protected ExactMatch() {
2929
public Boolean eval(Object conditionValue, Object attributeValue) throws UnexpectedValueTypeException {
3030
if (isValidNumber(attributeValue)) {
3131
if (isValidNumber(conditionValue)) {
32-
return evalNumber((Number) conditionValue, (Number) attributeValue);
32+
return NumberComparator.compareUnsafe(attributeValue, conditionValue) == 0;
3333
}
3434
return null;
3535
}
@@ -48,16 +48,4 @@ public Boolean eval(Object conditionValue, Object attributeValue) throws Unexpec
4848

4949
return conditionValue.equals(attributeValue);
5050
}
51-
52-
@Nullable
53-
public Boolean evalNumber(Number conditionValue, Number attributeValue) {
54-
try {
55-
if(isValidNumber(attributeValue)) {
56-
return conditionValue.doubleValue() == attributeValue.doubleValue();
57-
}
58-
} catch (Exception e) {
59-
}
60-
61-
return null;
62-
}
6351
}

core-api/src/main/java/com/optimizely/ab/config/audience/match/GEMatch.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,13 @@
1818

1919
import javax.annotation.Nullable;
2020

21-
import static com.optimizely.ab.internal.AttributesUtil.isValidNumber;
22-
2321
class GEMatch implements Match {
2422

23+
protected GEMatch() {
24+
}
25+
2526
@Nullable
26-
public Boolean eval(Object conditionValue, Object attributeValue) {
27-
try {
28-
if(isValidNumber(attributeValue) && isValidNumber(conditionValue) ) {
29-
return ((Number) attributeValue).doubleValue() >= ((Number) conditionValue).doubleValue();
30-
}
31-
} catch (Exception e) {
32-
return null;
33-
}
34-
return null;
27+
public Boolean eval(Object conditionValue, Object attributeValue) throws UnknownValueTypeException {
28+
return NumberComparator.compare(attributeValue, conditionValue) >= 0;
3529
}
3630
}

core-api/src/main/java/com/optimizely/ab/config/audience/match/GTMatch.java

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,13 @@
1818

1919
import javax.annotation.Nullable;
2020

21-
import static com.optimizely.ab.internal.AttributesUtil.isValidNumber;
22-
2321
class GTMatch implements Match {
2422

2523
protected GTMatch() {
2624
}
2725

2826
@Nullable
29-
public Boolean eval(Object conditionValue, Object attributeValue) {
30-
try {
31-
if(isValidNumber(attributeValue) && isValidNumber(conditionValue) ) {
32-
return ((Number) attributeValue).doubleValue() > ((Number) conditionValue).doubleValue();
33-
}
34-
} catch (Exception e) {
35-
return null;
36-
}
37-
return null;
27+
public Boolean eval(Object conditionValue, Object attributeValue) throws UnknownValueTypeException {
28+
return NumberComparator.compare(attributeValue, conditionValue) > 0;
3829
}
39-
}
30+
}

core-api/src/main/java/com/optimizely/ab/config/audience/match/LEMatch.java

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,14 @@
1818

1919
import javax.annotation.Nullable;
2020

21-
import static com.optimizely.ab.internal.AttributesUtil.isValidNumber;
22-
2321
class LEMatch implements Match {
2422

25-
@Nullable
26-
public Boolean eval(Object conditionValue, Object attributeValue) {
27-
try {
28-
if(isValidNumber(attributeValue) && isValidNumber(conditionValue) ) {
29-
return ((Number) attributeValue).doubleValue() <= ((Number) conditionValue).doubleValue();
30-
}
31-
} catch (Exception e) {
32-
return null;
33-
}
34-
return null;
23+
protected LEMatch() {
24+
}
3525

26+
@Nullable
27+
public Boolean eval(Object conditionValue, Object attributeValue) throws UnknownValueTypeException {
28+
return NumberComparator.compare(attributeValue, conditionValue) <= 0;
3629
}
3730
}
3831

core-api/src/main/java/com/optimizely/ab/config/audience/match/LTMatch.java

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,23 +18,13 @@
1818

1919
import javax.annotation.Nullable;
2020

21-
import static com.optimizely.ab.internal.AttributesUtil.isValidNumber;
22-
2321
class LTMatch implements Match {
2422

2523
protected LTMatch() {
2624
}
2725

2826
@Nullable
29-
public Boolean eval(Object conditionValue, Object attributeValue) {
30-
try {
31-
if(isValidNumber(attributeValue) && isValidNumber(conditionValue) ) {
32-
return ((Number) attributeValue).doubleValue() < ((Number) conditionValue).doubleValue();
33-
}
34-
} catch (Exception e) {
35-
return null;
36-
}
37-
return null;
27+
public Boolean eval(Object conditionValue, Object attributeValue) throws UnknownValueTypeException {
28+
return NumberComparator.compare(attributeValue, conditionValue) < 0;
3829
}
3930
}
40-

core-api/src/main/java/com/optimizely/ab/config/audience/match/Match.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,5 @@
2020

2121
public interface Match {
2222
@Nullable
23-
Boolean eval(Object conditionValue, Object attributeValue) throws UnexpectedValueTypeException;
23+
Boolean eval(Object conditionValue, Object attributeValue) throws UnexpectedValueTypeException, UnknownValueTypeException;
2424
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/**
2+
*
3+
* Copyright 2020, Optimizely and contributors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package com.optimizely.ab.config.audience.match;
18+
19+
import static com.optimizely.ab.internal.AttributesUtil.isValidNumber;
20+
21+
public class NumberComparator {
22+
public static int compare(Object o1, Object o2) throws UnknownValueTypeException {
23+
if (!isValidNumber(o1)) {
24+
throw new UnknownValueTypeException();
25+
}
26+
27+
if (!isValidNumber(o2)) {
28+
throw new UnknownValueTypeException();
29+
}
30+
31+
return compareUnsafe(o1, o2);
32+
}
33+
34+
public static int compareUnsafe(Object o1, Object o2) {
35+
return Double.compare(((Number) o1).doubleValue(), ((Number) o2).doubleValue());
36+
}
37+
}

core-api/src/main/java/com/optimizely/ab/config/audience/match/SemanticVersion.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
*/
1717
package com.optimizely.ab.config.audience.match;
1818

19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
21+
1922
import java.util.ArrayList;
2023
import java.util.Collections;
2124
import java.util.List;
@@ -25,6 +28,7 @@
2528

2629
public final class SemanticVersion {
2730

31+
private static final Logger logger = LoggerFactory.getLogger(SemanticVersion.class);
2832
private static final String BUILD_SEPERATOR = "\\+";
2933
private static final String PRE_RELEASE_SEPERATOR = "-";
3034

@@ -34,11 +38,15 @@ public SemanticVersion(String version) {
3438
this.version = version;
3539
}
3640

37-
public static int compare(Object o1, Object o2) throws Exception {
41+
public static int compare(Object o1, Object o2) throws UnexpectedValueTypeException {
3842
if (o1 instanceof String && o2 instanceof String) {
3943
SemanticVersion v1 = new SemanticVersion((String) o1);
4044
SemanticVersion v2 = new SemanticVersion((String) o2);
41-
return v1.compare(v2);
45+
try {
46+
return v1.compare(v2);
47+
} catch (Exception e) {
48+
logger.warn("Error comparing semantic versions", e);
49+
}
4250
}
4351

4452
throw new UnexpectedValueTypeException();

core-api/src/main/java/com/optimizely/ab/config/audience/match/SemanticVersionEqualsMatch.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,7 @@
2020

2121
class SemanticVersionEqualsMatch implements Match {
2222
@Nullable
23-
public Boolean eval(Object conditionValue, Object attributeValue) {
24-
try {
25-
return SemanticVersion.compare(attributeValue, conditionValue) == 0;
26-
} catch (Exception e) {
27-
return null;
28-
}
23+
public Boolean eval(Object conditionValue, Object attributeValue) throws UnexpectedValueTypeException {
24+
return SemanticVersion.compare(attributeValue, conditionValue) == 0;
2925
}
3026
}

0 commit comments

Comments
 (0)