Skip to content

Commit 3dde5da

Browse files
committed
Updated getFeatureVariableValueForType to return casted object so that we dont have to parse twice
1 parent 4fa7a37 commit 3dde5da

File tree

2 files changed

+106
-63
lines changed

2 files changed

+106
-63
lines changed

core-api/src/main/java/com/optimizely/ab/Optimizely.java

Lines changed: 48 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -446,16 +446,19 @@ public Boolean getFeatureVariableBoolean(@Nonnull String featureKey,
446446
logger.error("Optimizely instance is not valid, failing getFeatureVariableBoolean call.");
447447
return null;
448448
}
449-
450-
String variableValue = getFeatureVariableValueForType(
451-
featureKey,
452-
variableKey,
453-
userId,
454-
attributes,
455-
FeatureVariable.VariableType.BOOLEAN
456-
);
457-
if (variableValue != null) {
458-
return Boolean.parseBoolean(variableValue);
449+
Boolean variableValue = null;
450+
try {
451+
variableValue = getFeatureVariableValueForType(
452+
featureKey,
453+
variableKey,
454+
userId,
455+
attributes,
456+
FeatureVariable.VariableType.BOOLEAN
457+
);
458+
return variableValue;
459+
} catch (Exception exception) {
460+
logger.error("BooleanTypeException while trying to parse \"" + variableValue +
461+
"\" as Boolean. " + exception);
459462
}
460463
return null;
461464
}
@@ -496,20 +499,21 @@ public Double getFeatureVariableDouble(@Nonnull String featureKey,
496499
return null;
497500
}
498501

499-
String variableValue = getFeatureVariableValueForType(
500-
featureKey,
501-
variableKey,
502-
userId,
503-
attributes,
504-
FeatureVariable.VariableType.DOUBLE
505-
);
506-
if (variableValue != null) {
507-
try {
508-
return Double.parseDouble(variableValue);
509-
} catch (NumberFormatException exception) {
510-
logger.error("NumberFormatException while trying to parse \"" + variableValue +
511-
"\" as Double. " + exception);
502+
Double variableValue = null;
503+
try {
504+
variableValue = getFeatureVariableValueForType(
505+
featureKey,
506+
variableKey,
507+
userId,
508+
attributes,
509+
FeatureVariable.VariableType.DOUBLE
510+
);
511+
if (variableValue != null) {
512+
return variableValue;
512513
}
514+
} catch (Exception exception) {
515+
logger.error("NumberFormatException while trying to parse \"" + variableValue +
516+
"\" as Double. " + exception);
513517
}
514518
return null;
515519
}
@@ -549,21 +553,19 @@ public Integer getFeatureVariableInteger(@Nonnull String featureKey,
549553
logger.error("Optimizely instance is not valid, failing getFeatureVariableInteger call.");
550554
return null;
551555
}
552-
553-
String variableValue = getFeatureVariableValueForType(
554-
featureKey,
555-
variableKey,
556-
userId,
557-
attributes,
558-
FeatureVariable.VariableType.INTEGER
559-
);
560-
if (variableValue != null) {
561-
try {
562-
return Integer.parseInt(variableValue);
563-
} catch (NumberFormatException exception) {
564-
logger.error("NumberFormatException while trying to parse \"" + variableValue +
565-
"\" as Integer. " + exception.toString());
556+
try {
557+
Integer variableValue = getFeatureVariableValueForType(
558+
featureKey,
559+
variableKey,
560+
userId,
561+
attributes,
562+
FeatureVariable.VariableType.INTEGER
563+
);
564+
if (variableValue != null) {
565+
return variableValue;
566566
}
567+
} catch (Exception exception) {
568+
logger.error("NumberFormatException while trying to parse value as Integer. " + exception.toString());
567569
}
568570
return null;
569571
}
@@ -613,11 +615,11 @@ public String getFeatureVariableString(@Nonnull String featureKey,
613615
}
614616

615617
@VisibleForTesting
616-
String getFeatureVariableValueForType(@Nonnull String featureKey,
617-
@Nonnull String variableKey,
618-
@Nonnull String userId,
619-
@Nonnull Map<String, ?> attributes,
620-
@Nonnull FeatureVariable.VariableType variableType) {
618+
<T extends Object> T getFeatureVariableValueForType(@Nonnull String featureKey,
619+
@Nonnull String variableKey,
620+
@Nonnull String userId,
621+
@Nonnull Map<String, ?> attributes,
622+
@Nonnull FeatureVariable.VariableType variableType) {
621623
if (featureKey == null) {
622624
logger.warn("The featureKey parameter must be nonnull.");
623625
return null;
@@ -689,12 +691,13 @@ String getFeatureVariableValueForType(@Nonnull String featureKey,
689691
copiedAttributes,
690692
decisionInfo);
691693

692-
return variableValue;
694+
return (T) convertedValue;
693695
}
694696

695697
// Helper method which takes type and variable value and convert it to object to use in Listener DecisionInfo object variable value
696-
private Object convertStringToType(String variableValue, FeatureVariable.VariableType type) {
697-
if(variableValue != null) {
698+
@VisibleForTesting
699+
Object convertStringToType(String variableValue, FeatureVariable.VariableType type) {
700+
if (variableValue != null) {
698701
switch (type) {
699702
case DOUBLE:
700703
try {

core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java

Lines changed: 58 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3588,14 +3588,14 @@ public void getFeatureVariableValueForTypeReturnsDefaultValueWhenFeatureIsNotAtt
35883588

35893589
String validFeatureKey = FEATURE_SINGLE_VARIABLE_BOOLEAN_KEY;
35903590
String validVariableKey = VARIABLE_BOOLEAN_VARIABLE_KEY;
3591-
String defaultValue = VARIABLE_BOOLEAN_VARIABLE_DEFAULT_VALUE;
3591+
Boolean defaultValue = Boolean.parseBoolean(VARIABLE_BOOLEAN_VARIABLE_DEFAULT_VALUE);
35923592
Map<String, String> attributes = Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE);
35933593

35943594
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
35953595
.withConfig(validProjectConfig)
35963596
.build();
35973597

3598-
String value = optimizely.getFeatureVariableValueForType(
3598+
Boolean value = optimizely.getFeatureVariableValueForType(
35993599
validFeatureKey,
36003600
validVariableKey,
36013601
genericUserId,
@@ -3633,15 +3633,15 @@ public void getFeatureVariableValueReturnsDefaultValueWhenFeatureIsAttachedToOne
36333633

36343634
String validFeatureKey = FEATURE_SINGLE_VARIABLE_DOUBLE_KEY;
36353635
String validVariableKey = VARIABLE_DOUBLE_VARIABLE_KEY;
3636-
String expectedValue = VARIABLE_DOUBLE_DEFAULT_VALUE;
3636+
Double expectedValue = Double.parseDouble(VARIABLE_DOUBLE_DEFAULT_VALUE);
36373637
FeatureFlag featureFlag = FEATURE_FLAG_SINGLE_VARIABLE_DOUBLE;
36383638
Experiment experiment = validProjectConfig.getExperimentIdMapping().get(featureFlag.getExperimentIds().get(0));
36393639

36403640
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
36413641
.withConfig(validProjectConfig)
36423642
.build();
36433643

3644-
String valueWithImproperAttributes = optimizely.getFeatureVariableValueForType(
3644+
Double valueWithImproperAttributes = optimizely.getFeatureVariableValueForType(
36453645
validFeatureKey,
36463646
validVariableKey,
36473647
genericUserId,
@@ -3721,13 +3721,13 @@ public void getFeatureVariableValueReturnsDefaultValueWhenNoVariationUsageIsPres
37213721
String validFeatureKey = FEATURE_SINGLE_VARIABLE_INTEGER_KEY;
37223722
String validVariableKey = VARIABLE_INTEGER_VARIABLE_KEY;
37233723
FeatureVariable variable = FEATURE_FLAG_SINGLE_VARIABLE_INTEGER.getVariableKeyToFeatureVariableMap().get(validVariableKey);
3724-
String expectedValue = variable.getDefaultValue();
3724+
Integer expectedValue = Integer.parseInt(variable.getDefaultValue());
37253725

37263726
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
37273727
.withConfig(validProjectConfig)
37283728
.build();
37293729

3730-
String value = optimizely.getFeatureVariableValueForType(
3730+
Integer value = optimizely.getFeatureVariableValueForType(
37313731
validFeatureKey,
37323732
validVariableKey,
37333733
genericUserId,
@@ -4601,15 +4601,15 @@ public void getFeatureVariableBooleanReturnsWhatInternalReturns() throws ConfigP
46014601
.build());
46024602

46034603

4604-
doReturn(valueNoAttributes.toString()).when(spyOptimizely).getFeatureVariableValueForType(
4604+
doReturn(valueNoAttributes).when(spyOptimizely).getFeatureVariableValueForType(
46054605
eq(featureKey),
46064606
eq(variableKey),
46074607
eq(genericUserId),
46084608
eq(Collections.<String, String>emptyMap()),
46094609
eq(FeatureVariable.VariableType.BOOLEAN)
46104610
);
46114611

4612-
doReturn(valueWithAttributes.toString()).when(spyOptimizely).getFeatureVariableValueForType(
4612+
doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType(
46134613
eq(featureKey),
46144614
eq(variableKey),
46154615
eq(genericUserId),
@@ -4699,15 +4699,15 @@ public void getFeatureVariableDoubleReturnsWhatInternalReturns() throws ConfigPa
46994699
.build());
47004700

47014701

4702-
doReturn(valueNoAttributes.toString()).when(spyOptimizely).getFeatureVariableValueForType(
4702+
doReturn(valueNoAttributes).when(spyOptimizely).getFeatureVariableValueForType(
47034703
eq(featureKey),
47044704
eq(variableKey),
47054705
eq(genericUserId),
47064706
eq(Collections.<String, String>emptyMap()),
47074707
eq(FeatureVariable.VariableType.DOUBLE)
47084708
);
47094709

4710-
doReturn(valueWithAttributes.toString()).when(spyOptimizely).getFeatureVariableValueForType(
4710+
doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType(
47114711
eq(featureKey),
47124712
eq(variableKey),
47134713
eq(genericUserId),
@@ -4912,6 +4912,26 @@ public void getFeatureVariableDoubleCatchesExceptionFromParsing() throws ConfigP
49124912
variableKey,
49134913
genericUserId
49144914
));
4915+
}
4916+
4917+
/**
4918+
* Verify that {@link Optimizely#convertStringToType(String, FeatureVariable.VariableType)}
4919+
* do not throw errors when they are unable to parse the value into an Double.
4920+
*
4921+
* @throws NumberFormatException
4922+
*/
4923+
@Test
4924+
public void convertStringToTypeDoubleCatchesExceptionFromParsing() throws NumberFormatException {
4925+
String unParsableValue = "not_a_double";
4926+
4927+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
4928+
.withConfig(validProjectConfig)
4929+
.build();
4930+
4931+
assertNull(optimizely.convertStringToType(
4932+
unParsableValue,
4933+
FeatureVariable.VariableType.DOUBLE
4934+
));
49154935

49164936
logbackVerifier.expectMessage(
49174937
Level.ERROR,
@@ -4920,6 +4940,32 @@ public void getFeatureVariableDoubleCatchesExceptionFromParsing() throws ConfigP
49204940
);
49214941
}
49224942

4943+
/**
4944+
* Verify that {@link Optimizely#convertStringToType(String, FeatureVariable.VariableType)}
4945+
* do not throw errors when they are unable to parse the value into an Integer.
4946+
*
4947+
* @throws NumberFormatException
4948+
*/
4949+
@Test
4950+
public void convertStringToTypeIntegerCatchesExceptionFromParsing() throws NumberFormatException {
4951+
String unParsableValue = "not_a_integer";
4952+
4953+
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler)
4954+
.withConfig(validProjectConfig)
4955+
.build();
4956+
4957+
assertNull(optimizely.convertStringToType(
4958+
unParsableValue,
4959+
FeatureVariable.VariableType.INTEGER
4960+
));
4961+
4962+
logbackVerifier.expectMessage(
4963+
Level.ERROR,
4964+
"NumberFormatException while trying to parse \"" + unParsableValue +
4965+
"\" as Integer. "
4966+
);
4967+
}
4968+
49234969
/**
49244970
* Verify {@link Optimizely#getFeatureVariableInteger(String, String, String)}
49254971
* calls through to {@link Optimizely#getFeatureVariableInteger(String, String, String, Map)}
@@ -5047,15 +5093,15 @@ public void getFeatureVariableIntegerReturnsWhatInternalReturns() throws ConfigP
50475093
.build());
50485094

50495095

5050-
doReturn(valueNoAttributes.toString()).when(spyOptimizely).getFeatureVariableValueForType(
5096+
doReturn(valueNoAttributes).when(spyOptimizely).getFeatureVariableValueForType(
50515097
eq(featureKey),
50525098
eq(variableKey),
50535099
eq(genericUserId),
50545100
eq(Collections.<String, String>emptyMap()),
50555101
eq(FeatureVariable.VariableType.INTEGER)
50565102
);
50575103

5058-
doReturn(valueWithAttributes.toString()).when(spyOptimizely).getFeatureVariableValueForType(
5104+
doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType(
50595105
eq(featureKey),
50605106
eq(variableKey),
50615107
eq(genericUserId),
@@ -5114,12 +5160,6 @@ public void getFeatureVariableIntegerCatchesExceptionFromParsing() throws Config
51145160
variableKey,
51155161
genericUserId
51165162
));
5117-
5118-
logbackVerifier.expectMessage(
5119-
Level.ERROR,
5120-
"NumberFormatException while trying to parse \"" + unParsableValue +
5121-
"\" as Integer. "
5122-
);
51235163
}
51245164

51255165
/**

0 commit comments

Comments
 (0)