From 6be691f62d5b5baa218948779e070ba5f41eb6f8 Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Wed, 15 Apr 2020 15:02:13 -0700 Subject: [PATCH 1/2] change FeatureVariable type from enum to string for forward compatibility --- .../java/com/optimizely/ab/Optimizely.java | 20 ++--- .../optimizely/ab/config/FeatureVariable.java | 53 ++---------- .../ab/config/parser/JsonConfigParser.java | 2 +- .../config/parser/JsonSimpleConfigParser.java | 3 +- .../ab/notification/DecisionNotification.java | 4 +- .../OptimizelyConfigService.java | 4 +- .../com/optimizely/ab/OptimizelyTest.java | 80 +++++++++---------- .../ab/config/ValidProjectConfigV4.java | 27 +++++-- .../DecisionNotificationTest.java | 10 +-- .../OptimizelyConfigServiceTest.java | 6 +- .../config/valid-project-config-v4.json | 9 ++- 11 files changed, 98 insertions(+), 120 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/Optimizely.java b/core-api/src/main/java/com/optimizely/ab/Optimizely.java index 8cecc685a..4f90a0f5c 100644 --- a/core-api/src/main/java/com/optimizely/ab/Optimizely.java +++ b/core-api/src/main/java/com/optimizely/ab/Optimizely.java @@ -458,7 +458,7 @@ public Boolean getFeatureVariableBoolean(@Nonnull String featureKey, variableKey, userId, attributes, - FeatureVariable.VariableType.BOOLEAN + FeatureVariable.BOOLEAN_TYPE ); } @@ -501,7 +501,7 @@ public Double getFeatureVariableDouble(@Nonnull String featureKey, variableKey, userId, attributes, - FeatureVariable.VariableType.DOUBLE + FeatureVariable.DOUBLE_TYPE ); } catch (Exception exception) { logger.error("NumberFormatException while trying to parse \"" + variableValue + @@ -551,7 +551,7 @@ public Integer getFeatureVariableInteger(@Nonnull String featureKey, variableKey, userId, attributes, - FeatureVariable.VariableType.INTEGER + FeatureVariable.INTEGER_TYPE ); } catch (Exception exception) { @@ -598,7 +598,7 @@ public String getFeatureVariableString(@Nonnull String featureKey, variableKey, userId, attributes, - FeatureVariable.VariableType.STRING); + FeatureVariable.STRING_TYPE); } @VisibleForTesting @@ -606,7 +606,7 @@ T getFeatureVariableValueForType(@Nonnull String featureKey, @Nonnull String variableKey, @Nonnull String userId, @Nonnull Map attributes, - @Nonnull FeatureVariable.VariableType variableType) { + @Nonnull String variableType) { if (featureKey == null) { logger.warn("The featureKey parameter must be nonnull."); return null; @@ -691,10 +691,10 @@ T getFeatureVariableValueForType(@Nonnull String featureKey, // Helper method which takes type and variable value and convert it to object to use in Listener DecisionInfo object variable value @VisibleForTesting - Object convertStringToType(String variableValue, FeatureVariable.VariableType type) { + Object convertStringToType(String variableValue, String type) { if (variableValue != null) { switch (type) { - case DOUBLE: + case FeatureVariable.DOUBLE_TYPE: try { return Double.parseDouble(variableValue); } catch (NumberFormatException exception) { @@ -702,11 +702,11 @@ Object convertStringToType(String variableValue, FeatureVariable.VariableType ty "\" as Double. " + exception); } break; - case STRING: + case FeatureVariable.STRING_TYPE: return variableValue; - case BOOLEAN: + case FeatureVariable.BOOLEAN_TYPE: return Boolean.parseBoolean(variableValue); - case INTEGER: + case FeatureVariable.INTEGER_TYPE: try { return Integer.parseInt(variableValue); } catch (NumberFormatException exception) { diff --git a/core-api/src/main/java/com/optimizely/ab/config/FeatureVariable.java b/core-api/src/main/java/com/optimizely/ab/config/FeatureVariable.java index 0ca48b84b..7d8657970 100644 --- a/core-api/src/main/java/com/optimizely/ab/config/FeatureVariable.java +++ b/core-api/src/main/java/com/optimizely/ab/config/FeatureVariable.java @@ -61,52 +61,15 @@ public static VariableStatus fromString(String variableStatusString) { } } - public enum VariableType { - @SerializedName("boolean") - BOOLEAN("boolean"), - - @SerializedName("integer") - INTEGER("integer"), - - @SerializedName("string") - STRING("string"), - - @SerializedName("double") - DOUBLE("double"); - - private final String variableType; - - VariableType(String variableType) { - this.variableType = variableType; - } - - @JsonValue - public String getVariableType() { - return variableType; - } - - public static VariableType fromString(String variableTypeString) { - if (variableTypeString != null) { - for (VariableType variableTypeEnum : VariableType.values()) { - if (variableTypeString.equals(variableTypeEnum.getVariableType())) { - return variableTypeEnum; - } - } - } - - return null; - } - - @Override - public String toString() { - return variableType; - } - } + public static final String STRING_TYPE = "string"; + public static final String INTEGER_TYPE = "integer"; + public static final String DOUBLE_TYPE = "double"; + public static final String BOOLEAN_TYPE = "boolean"; private final String id; private final String key; private final String defaultValue; - private final VariableType type; + private final String type; @Nullable private final VariableStatus status; @@ -115,7 +78,7 @@ public FeatureVariable(@JsonProperty("id") String id, @JsonProperty("key") String key, @JsonProperty("defaultValue") String defaultValue, @JsonProperty("status") VariableStatus status, - @JsonProperty("type") VariableType type) { + @JsonProperty("type") String type) { this.id = id; this.key = key; this.defaultValue = defaultValue; @@ -140,7 +103,7 @@ public String getDefaultValue() { return defaultValue; } - public VariableType getType() { + public String getType() { return type; } @@ -165,7 +128,7 @@ public boolean equals(Object o) { if (!id.equals(variable.id)) return false; if (!key.equals(variable.key)) return false; if (!defaultValue.equals(variable.defaultValue)) return false; - if (type != variable.type) return false; + if (!type.equals(variable.type)) return false; return status == variable.status; } diff --git a/core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java b/core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java index fb122b6d4..21198da06 100644 --- a/core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java +++ b/core-api/src/main/java/com/optimizely/ab/config/parser/JsonConfigParser.java @@ -344,7 +344,7 @@ private List parseFeatureVariables(JSONArray featureVariablesJs String id = FeatureVariableObject.getString("id"); String key = FeatureVariableObject.getString("key"); String defaultValue = FeatureVariableObject.getString("defaultValue"); - FeatureVariable.VariableType type = FeatureVariable.VariableType.fromString(FeatureVariableObject.getString("type")); + String type = FeatureVariableObject.getString("type"); FeatureVariable.VariableStatus status = null; if (FeatureVariableObject.has("status")) { status = FeatureVariable.VariableStatus.fromString(FeatureVariableObject.getString("status")); diff --git a/core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java b/core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java index 453be2e69..f800595e3 100644 --- a/core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java +++ b/core-api/src/main/java/com/optimizely/ab/config/parser/JsonSimpleConfigParser.java @@ -19,7 +19,6 @@ import com.optimizely.ab.config.*; import com.optimizely.ab.config.Experiment.ExperimentStatus; import com.optimizely.ab.config.FeatureVariable.VariableStatus; -import com.optimizely.ab.config.FeatureVariable.VariableType; import com.optimizely.ab.config.audience.Audience; import com.optimizely.ab.config.audience.AudienceIdCondition; import com.optimizely.ab.config.audience.Condition; @@ -335,7 +334,7 @@ private List parseFeatureVariables(JSONArray featureVariablesJs String id = (String) featureVariableObject.get("id"); String key = (String) featureVariableObject.get("key"); String defaultValue = (String) featureVariableObject.get("defaultValue"); - VariableType type = VariableType.fromString((String) featureVariableObject.get("type")); + String type = (String) featureVariableObject.get("type"); VariableStatus status = VariableStatus.fromString((String) featureVariableObject.get("status")); featureVariables.add(new FeatureVariable(id, key, defaultValue, status, type)); diff --git a/core-api/src/main/java/com/optimizely/ab/notification/DecisionNotification.java b/core-api/src/main/java/com/optimizely/ab/notification/DecisionNotification.java index cf132f033..741af7bd2 100644 --- a/core-api/src/main/java/com/optimizely/ab/notification/DecisionNotification.java +++ b/core-api/src/main/java/com/optimizely/ab/notification/DecisionNotification.java @@ -244,7 +244,7 @@ public static class FeatureVariableDecisionNotificationBuilder { private Boolean featureEnabled; private FeatureDecision featureDecision; private String variableKey; - private FeatureVariable.VariableType variableType; + private String variableType; private Object variableValue; private String userId; private Map attributes; @@ -283,7 +283,7 @@ public FeatureVariableDecisionNotificationBuilder withVariableKey(String variabl return this; } - public FeatureVariableDecisionNotificationBuilder withVariableType(FeatureVariable.VariableType variableType) { + public FeatureVariableDecisionNotificationBuilder withVariableType(String variableType) { this.variableType = variableType; return this; } diff --git a/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigService.java b/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigService.java index 6bb01fcef..4ec447ead 100644 --- a/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigService.java +++ b/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigService.java @@ -130,7 +130,7 @@ Map getMergedVariablesMap(Variation variation, Strin featureVariableKeyMap.put(featureVariable.getKey(), new OptimizelyVariable( featureVariable.getId(), featureVariable.getKey(), - featureVariable.getType().getVariableType().toLowerCase(), + featureVariable.getType(), variation.getFeatureEnabled() && tempVariableIdMap.get(featureVariable.getId()) != null ? tempVariableIdMap.get(featureVariable.getId()).getValue() : featureVariable.getDefaultValue() @@ -205,7 +205,7 @@ Map getFeatureVariablesMap(List fea featureVariableKeyMap.put(featureVariable.getKey(), new OptimizelyVariable( featureVariable.getId(), featureVariable.getKey(), - featureVariable.getType().getVariableType().toLowerCase(), + featureVariable.getType(), featureVariable.getDefaultValue() )); } diff --git a/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java b/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java index 0817ddc41..c8c5ddb53 100644 --- a/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java +++ b/core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java @@ -1952,7 +1952,7 @@ public void getFeatureVariableWithListenerUserInExperimentFeatureOn() throws Exc testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey); testDecisionInfoMap.put(FEATURE_ENABLED, true); testDecisionInfoMap.put(VARIABLE_KEY, validVariableKey); - testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.VariableType.STRING.toString()); + testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.STRING_TYPE); testDecisionInfoMap.put(VARIABLE_VALUE, expectedValue); testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.FEATURE_TEST.toString()); testDecisionInfoMap.put(SOURCE_INFO, testSourceInfo); @@ -2002,7 +2002,7 @@ public void getFeatureVariableWithListenerUserInExperimentFeatureOff() { testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey); testDecisionInfoMap.put(FEATURE_ENABLED, false); testDecisionInfoMap.put(VARIABLE_KEY, validVariableKey); - testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.VariableType.STRING.toString()); + testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.STRING_TYPE); testDecisionInfoMap.put(VARIABLE_VALUE, expectedValue); testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.FEATURE_TEST.toString()); testDecisionInfoMap.put(SOURCE_INFO, testSourceInfo); @@ -2049,7 +2049,7 @@ public void getFeatureVariableWithListenerUserInRollOutFeatureOn() throws Except testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey); testDecisionInfoMap.put(FEATURE_ENABLED, true); testDecisionInfoMap.put(VARIABLE_KEY, validVariableKey); - testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.VariableType.STRING.toString()); + testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.STRING_TYPE); testDecisionInfoMap.put(VARIABLE_VALUE, expectedValue); testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.ROLLOUT.toString()); testDecisionInfoMap.put(SOURCE_INFO, Collections.EMPTY_MAP); @@ -2096,7 +2096,7 @@ public void getFeatureVariableWithListenerUserNotInRollOutFeatureOff() { testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey); testDecisionInfoMap.put(FEATURE_ENABLED, false); testDecisionInfoMap.put(VARIABLE_KEY, validVariableKey); - testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.VariableType.BOOLEAN.toString()); + testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.BOOLEAN_TYPE); testDecisionInfoMap.put(VARIABLE_VALUE, expectedValue); testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.ROLLOUT.toString()); testDecisionInfoMap.put(SOURCE_INFO, Collections.EMPTY_MAP); @@ -2142,7 +2142,7 @@ public void getFeatureVariableIntegerWithListenerUserInRollOutFeatureOn() { testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey); testDecisionInfoMap.put(FEATURE_ENABLED, true); testDecisionInfoMap.put(VARIABLE_KEY, validVariableKey); - testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.VariableType.INTEGER.toString()); + testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.INTEGER_TYPE); testDecisionInfoMap.put(VARIABLE_VALUE, expectedValue); testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.ROLLOUT.toString()); testDecisionInfoMap.put(SOURCE_INFO, Collections.EMPTY_MAP); @@ -2191,7 +2191,7 @@ public void getFeatureVariableDoubleWithListenerUserInExperimentFeatureOn() thro testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey); testDecisionInfoMap.put(FEATURE_ENABLED, true); testDecisionInfoMap.put(VARIABLE_KEY, validVariableKey); - testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.VariableType.DOUBLE.toString()); + testDecisionInfoMap.put(VARIABLE_TYPE, FeatureVariable.DOUBLE_TYPE); testDecisionInfoMap.put(VARIABLE_VALUE, 3.14); testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.FEATURE_TEST.toString()); testDecisionInfoMap.put(SOURCE_INFO, testSourceInfo); @@ -2519,7 +2519,7 @@ public void getFeatureVariableValueForTypeReturnsNullWhenFeatureNotFound() throw invalidVariableKey, genericUserId, Collections.emptyMap(), - FeatureVariable.VariableType.STRING); + FeatureVariable.STRING_TYPE); assertNull(value); value = optimizely.getFeatureVariableString(invalidFeatureKey, invalidVariableKey, genericUserId, attributes); @@ -2548,7 +2548,7 @@ public void getFeatureVariableValueForTypeReturnsNullWhenVariableNotFoundInValid invalidVariableKey, genericUserId, Collections.emptyMap(), - FeatureVariable.VariableType.STRING); + FeatureVariable.STRING_TYPE); assertNull(value); logbackVerifier.expectMessage(Level.INFO, @@ -2572,15 +2572,15 @@ public void getFeatureVariableValueReturnsNullWhenVariableTypeDoesNotMatch() thr validVariableKey, genericUserId, Collections.emptyMap(), - FeatureVariable.VariableType.INTEGER + FeatureVariable.INTEGER_TYPE ); assertNull(value); logbackVerifier.expectMessage( Level.INFO, "The feature variable \"" + validVariableKey + - "\" is actually of type \"" + FeatureVariable.VariableType.STRING.toString() + - "\" type. You tried to access it as type \"" + FeatureVariable.VariableType.INTEGER.toString() + + "\" is actually of type \"" + FeatureVariable.STRING_TYPE + + "\" type. You tried to access it as type \"" + FeatureVariable.INTEGER_TYPE + "\". Please use the appropriate feature variable accessor." ); } @@ -2606,7 +2606,7 @@ public void getFeatureVariableValueForTypeReturnsDefaultValueWhenFeatureIsNotAtt validVariableKey, genericUserId, attributes, - FeatureVariable.VariableType.BOOLEAN); + FeatureVariable.BOOLEAN_TYPE); assertEquals(defaultValue, value); logbackVerifier.expectMessage( @@ -2648,7 +2648,7 @@ public void getFeatureVariableValueReturnsDefaultValueWhenFeatureIsAttachedToOne validVariableKey, genericUserId, Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, "Ravenclaw"), - FeatureVariable.VariableType.DOUBLE + FeatureVariable.DOUBLE_TYPE ); assertEquals(expectedValue, valueWithImproperAttributes); @@ -2699,7 +2699,7 @@ public void getFeatureVariableValueReturnsDefaultValueWhenFeatureEnabledIsFalse( validVariableKey, genericUserId, Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE), - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE ); logbackVerifier.expectMessage( @@ -2871,7 +2871,7 @@ public void getFeatureVariableValueReturnsDefaultValueWhenNoVariationUsageIsPres validVariableKey, genericUserId, Collections.emptyMap(), - FeatureVariable.VariableType.INTEGER + FeatureVariable.INTEGER_TYPE ); assertEquals(expectedValue, value); @@ -3371,7 +3371,7 @@ public void getFeatureVariableStringReturnsNullWhenUserIdIsNull() throws Excepti * Verify {@link Optimizely#getFeatureVariableString(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableString(String, String, String, Map)} * and returns null - * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)} + * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)} * returns null */ @Test @@ -3386,7 +3386,7 @@ public void getFeatureVariableStringReturnsNullFromInternal() throws Exception { eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.STRING) + eq(FeatureVariable.STRING_TYPE) ); assertNull(spyOptimizely.getFeatureVariableString(featureKey, variableKey, genericUserId)); @@ -3403,7 +3403,7 @@ public void getFeatureVariableStringReturnsNullFromInternal() throws Exception { * Verify {@link Optimizely#getFeatureVariableString(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableString(String, String, String, Map)} * and both return the value returned from - * {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)}. + * {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)}. */ @Test public void getFeatureVariableStringReturnsWhatInternalReturns() throws Exception { @@ -3420,7 +3420,7 @@ public void getFeatureVariableStringReturnsWhatInternalReturns() throws Exceptio eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.STRING) + eq(FeatureVariable.STRING_TYPE) ); doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType( @@ -3428,7 +3428,7 @@ public void getFeatureVariableStringReturnsWhatInternalReturns() throws Exceptio eq(variableKey), eq(genericUserId), eq(attributes), - eq(FeatureVariable.VariableType.STRING) + eq(FeatureVariable.STRING_TYPE) ); assertEquals(valueNoAttributes, spyOptimizely.getFeatureVariableString( @@ -3552,7 +3552,7 @@ public void getFeatureVariableBooleanReturnsNullWhenUserIdIsNull() throws Except * Verify {@link Optimizely#getFeatureVariableBoolean(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableBoolean(String, String, String, Map)} * and returns null - * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)} + * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)} * returns null */ @Test @@ -3567,7 +3567,7 @@ public void getFeatureVariableBooleanReturnsNullFromInternal() throws Exception eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.BOOLEAN) + eq(FeatureVariable.BOOLEAN_TYPE) ); assertNull(spyOptimizely.getFeatureVariableBoolean( @@ -3588,7 +3588,7 @@ public void getFeatureVariableBooleanReturnsNullFromInternal() throws Exception * Verify {@link Optimizely#getFeatureVariableBoolean(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableBoolean(String, String, String, Map)} * and both return a Boolean representation of the value returned from - * {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)}. + * {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)}. */ @Test public void getFeatureVariableBooleanReturnsWhatInternalReturns() throws Exception { @@ -3605,7 +3605,7 @@ public void getFeatureVariableBooleanReturnsWhatInternalReturns() throws Excepti eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.BOOLEAN) + eq(FeatureVariable.BOOLEAN_TYPE) ); doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType( @@ -3613,7 +3613,7 @@ public void getFeatureVariableBooleanReturnsWhatInternalReturns() throws Excepti eq(variableKey), eq(genericUserId), eq(attributes), - eq(FeatureVariable.VariableType.BOOLEAN) + eq(FeatureVariable.BOOLEAN_TYPE) ); assertEquals(valueNoAttributes, spyOptimizely.getFeatureVariableBoolean( @@ -3641,7 +3641,7 @@ public void getFeatureVariableBooleanReturnsWhatInternalReturns() throws Excepti * Verify {@link Optimizely#getFeatureVariableDouble(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableDouble(String, String, String, Map)} * and returns null - * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)} + * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)} * returns null */ @Test @@ -3656,7 +3656,7 @@ public void getFeatureVariableDoubleReturnsNullFromInternal() throws Exception { eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.DOUBLE) + eq(FeatureVariable.DOUBLE_TYPE) ); assertNull(spyOptimizely.getFeatureVariableDouble( @@ -3677,7 +3677,7 @@ public void getFeatureVariableDoubleReturnsNullFromInternal() throws Exception { * Verify {@link Optimizely#getFeatureVariableDouble(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableDouble(String, String, String, Map)} * and both return the parsed Double from the value returned from - * {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)}. + * {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)}. */ @Test public void getFeatureVariableDoubleReturnsWhatInternalReturns() throws Exception { @@ -3694,7 +3694,7 @@ public void getFeatureVariableDoubleReturnsWhatInternalReturns() throws Exceptio eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.DOUBLE) + eq(FeatureVariable.DOUBLE_TYPE) ); doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType( @@ -3702,7 +3702,7 @@ public void getFeatureVariableDoubleReturnsWhatInternalReturns() throws Exceptio eq(variableKey), eq(genericUserId), eq(attributes), - eq(FeatureVariable.VariableType.DOUBLE) + eq(FeatureVariable.DOUBLE_TYPE) ); assertEquals(valueNoAttributes, spyOptimizely.getFeatureVariableDouble( @@ -3730,7 +3730,7 @@ public void getFeatureVariableDoubleReturnsWhatInternalReturns() throws Exceptio * Verify {@link Optimizely#getFeatureVariableInteger(String, String, String)} * calls through to {@link Optimizely#getFeatureVariableInteger(String, String, String, Map)} * and returns null - * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)} + * when {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, String)} * returns null */ @Test @@ -3745,7 +3745,7 @@ public void getFeatureVariableIntegerReturnsNullFromInternal() throws Exception eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.INTEGER) + eq(FeatureVariable.INTEGER_TYPE) ); assertNull(spyOptimizely.getFeatureVariableInteger( @@ -3853,14 +3853,14 @@ public void getFeatureVariableDoubleCatchesExceptionFromParsing() throws Excepti anyString(), anyString(), anyMapOf(String.class, String.class), - eq(FeatureVariable.VariableType.DOUBLE) + eq(FeatureVariable.DOUBLE_TYPE) ); assertNull(spyOptimizely.getFeatureVariableDouble(featureKey, variableKey, genericUserId)); } /** - * Verify that {@link Optimizely#convertStringToType(String, FeatureVariable.VariableType)} + * Verify that {@link Optimizely#convertStringToType(String, String)} * do not throw errors when they are unable to parse the value into an Double. * * @throws NumberFormatException @@ -3870,7 +3870,7 @@ public void convertStringToTypeDoubleCatchesExceptionFromParsing() throws Number String unParsableValue = "not_a_double"; Optimizely optimizely = optimizelyBuilder.build(); - assertNull(optimizely.convertStringToType(unParsableValue, FeatureVariable.VariableType.DOUBLE)); + assertNull(optimizely.convertStringToType(unParsableValue, FeatureVariable.DOUBLE_TYPE)); logbackVerifier.expectMessage( Level.ERROR, @@ -3880,7 +3880,7 @@ public void convertStringToTypeDoubleCatchesExceptionFromParsing() throws Number } /** - * Verify that {@link Optimizely#convertStringToType(String, FeatureVariable.VariableType)} + * Verify that {@link Optimizely#convertStringToType(String, String)} * do not throw errors when they are unable to parse the value into an Integer. * * @throws NumberFormatException @@ -3890,7 +3890,7 @@ public void convertStringToTypeIntegerCatchesExceptionFromParsing() throws Numbe String unParsableValue = "not_a_integer"; Optimizely optimizely = optimizelyBuilder.build(); - assertNull(optimizely.convertStringToType(unParsableValue, FeatureVariable.VariableType.INTEGER)); + assertNull(optimizely.convertStringToType(unParsableValue, FeatureVariable.INTEGER_TYPE)); logbackVerifier.expectMessage( Level.ERROR, @@ -3990,7 +3990,7 @@ public void getFeatureVariableIntegerReturnsWhatInternalReturns() throws Excepti eq(variableKey), eq(genericUserId), eq(Collections.emptyMap()), - eq(FeatureVariable.VariableType.INTEGER) + eq(FeatureVariable.INTEGER_TYPE) ); doReturn(valueWithAttributes).when(spyOptimizely).getFeatureVariableValueForType( @@ -3998,7 +3998,7 @@ public void getFeatureVariableIntegerReturnsWhatInternalReturns() throws Excepti eq(variableKey), eq(genericUserId), eq(attributes), - eq(FeatureVariable.VariableType.INTEGER) + eq(FeatureVariable.INTEGER_TYPE) ); assertEquals(valueNoAttributes, spyOptimizely.getFeatureVariableInteger( @@ -4040,7 +4040,7 @@ public void getFeatureVariableIntegerCatchesExceptionFromParsing() throws Except anyString(), anyString(), anyMapOf(String.class, String.class), - eq(FeatureVariable.VariableType.INTEGER) + eq(FeatureVariable.INTEGER_TYPE) ); assertNull(spyOptimizely.getFeatureVariableInteger(featureKey, variableKey, genericUserId)); diff --git a/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java b/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java index 0206c2d5b..dd79294b8 100644 --- a/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java +++ b/core-api/src/test/java/com/optimizely/ab/config/ValidProjectConfigV4.java @@ -247,7 +247,7 @@ public class ValidProjectConfigV4 { VARIABLE_DOUBLE_VARIABLE_KEY, VARIABLE_DOUBLE_DEFAULT_VALUE, null, - FeatureVariable.VariableType.DOUBLE + FeatureVariable.DOUBLE_TYPE ); private static final String FEATURE_SINGLE_VARIABLE_INTEGER_ID = "3281420120"; public static final String FEATURE_SINGLE_VARIABLE_INTEGER_KEY = "integer_single_variable_feature"; @@ -259,7 +259,7 @@ public class ValidProjectConfigV4 { VARIABLE_INTEGER_VARIABLE_KEY, VARIABLE_INTEGER_DEFAULT_VALUE, null, - FeatureVariable.VariableType.INTEGER + FeatureVariable.INTEGER_TYPE ); private static final String FEATURE_SINGLE_VARIABLE_BOOLEAN_ID = "2591051011"; public static final String FEATURE_SINGLE_VARIABLE_BOOLEAN_KEY = "boolean_single_variable_feature"; @@ -271,7 +271,7 @@ public class ValidProjectConfigV4 { VARIABLE_BOOLEAN_VARIABLE_KEY, VARIABLE_BOOLEAN_VARIABLE_DEFAULT_VALUE, null, - FeatureVariable.VariableType.BOOLEAN + FeatureVariable.BOOLEAN_TYPE ); private static final FeatureFlag FEATURE_FLAG_SINGLE_VARIABLE_BOOLEAN = new FeatureFlag( FEATURE_SINGLE_VARIABLE_BOOLEAN_ID, @@ -292,7 +292,7 @@ public class ValidProjectConfigV4 { VARIABLE_STRING_VARIABLE_KEY, VARIABLE_STRING_VARIABLE_DEFAULT_VALUE, null, - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE ); private static final String ROLLOUT_1_ID = "1058508303"; private static final String ROLLOUT_1_EVERYONE_ELSE_EXPERIMENT_ID = "1785077004"; @@ -388,7 +388,7 @@ public class ValidProjectConfigV4 { VARIABLE_FIRST_LETTER_KEY, VARIABLE_FIRST_LETTER_DEFAULT_VALUE, null, - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE ); private static final String VARIABLE_REST_OF_NAME_ID = "4052219963"; private static final String VARIABLE_REST_OF_NAME_KEY = "rest_of_name"; @@ -398,7 +398,17 @@ public class ValidProjectConfigV4 { VARIABLE_REST_OF_NAME_KEY, VARIABLE_REST_OF_NAME_DEFAULT_VALUE, null, - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE + ); + private static final String VARIABLE_FUTURE_TYPE_ID = "4111661234"; + private static final String VARIABLE_FUTURE_TYPE_KEY = "future_variable"; + private static final String VARIABLE_FUTURE_TYPE_DEFAULT_VALUE = "future_value"; + private static final FeatureVariable VARIABLE_FUTURE_TYPE_VARIABLE = new FeatureVariable( + VARIABLE_FUTURE_TYPE_ID, + VARIABLE_FUTURE_TYPE_KEY, + VARIABLE_FUTURE_TYPE_DEFAULT_VALUE, + null, + "future_type" ); private static final String FEATURE_MUTEX_GROUP_FEATURE_ID = "3263342226"; public static final String FEATURE_MUTEX_GROUP_FEATURE_KEY = "mutex_group_feature"; @@ -410,7 +420,7 @@ public class ValidProjectConfigV4 { VARIABLE_CORRELATING_VARIATION_NAME_KEY, VARIABLE_CORRELATING_VARIATION_NAME_DEFAULT_VALUE, null, - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE ); // group IDs @@ -1251,7 +1261,8 @@ public class ValidProjectConfigV4 { Collections.singletonList(EXPERIMENT_MULTIVARIATE_EXPERIMENT_ID), DatafileProjectConfigTestUtils.createListOfObjects( VARIABLE_FIRST_LETTER_VARIABLE, - VARIABLE_REST_OF_NAME_VARIABLE + VARIABLE_REST_OF_NAME_VARIABLE, + VARIABLE_FUTURE_TYPE_VARIABLE ) ); public static final FeatureFlag FEATURE_FLAG_MUTEX_GROUP_FEATURE = new FeatureFlag( diff --git a/core-api/src/test/java/com/optimizely/ab/notification/DecisionNotificationTest.java b/core-api/src/test/java/com/optimizely/ab/notification/DecisionNotificationTest.java index 58ab5b5d9..8ba0e7f7b 100644 --- a/core-api/src/test/java/com/optimizely/ab/notification/DecisionNotificationTest.java +++ b/core-api/src/test/java/com/optimizely/ab/notification/DecisionNotificationTest.java @@ -75,7 +75,7 @@ public void setUp() { .withFeatureKey(FEATURE_KEY) .withFeatureEnabled(Boolean.TRUE) .withVariableKey(FEATURE_VARIABLE_KEY) - .withVariableType(FeatureVariable.VariableType.STRING) + .withVariableType(FeatureVariable.STRING_TYPE) .withAttributes(USER_ATTRIBUTES) .build(); } @@ -121,7 +121,7 @@ public void testGetDecisionInfo() { assertTrue((Boolean) actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.FEATURE_ENABLED)); assertEquals(FEATURE_KEY, actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.FEATURE_KEY)); assertEquals(FEATURE_VARIABLE_KEY, actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.VARIABLE_KEY)); - assertEquals(FeatureVariable.VariableType.STRING.toString(), actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.VARIABLE_TYPE)); + assertEquals(FeatureVariable.STRING_TYPE, actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.VARIABLE_TYPE)); assertEquals(FeatureDecision.DecisionSource.ROLLOUT.toString(), actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.SOURCE)); assertEquals(rolloutSourceInfo.get(), actualFeatureVariableDecisionInfo.get(DecisionNotification.FeatureVariableDecisionNotificationBuilder.SOURCE_INFO)); } @@ -176,7 +176,7 @@ public void nullFeatureKeyFailsFeatureVariableNotificationBuild() { DecisionNotification.newFeatureVariableDecisionNotificationBuilder() .withFeatureEnabled(Boolean.TRUE) .withVariableKey(FEATURE_VARIABLE_KEY) - .withVariableType(FeatureVariable.VariableType.STRING) + .withVariableType(FeatureVariable.STRING_TYPE) .build(); } @@ -185,7 +185,7 @@ public void nullFeatureEnabledFailsFeatureVariableNotificationBuild() { DecisionNotification.newFeatureVariableDecisionNotificationBuilder() .withFeatureKey(FEATURE_KEY) .withVariableKey(FEATURE_VARIABLE_KEY) - .withVariableType(FeatureVariable.VariableType.STRING) + .withVariableType(FeatureVariable.STRING_TYPE) .build(); } @@ -194,7 +194,7 @@ public void nullVariableKeyFailsFeatureVariableNotificationBuild() { DecisionNotification.newFeatureVariableDecisionNotificationBuilder() .withFeatureKey(FEATURE_KEY) .withFeatureEnabled(Boolean.TRUE) - .withVariableType(FeatureVariable.VariableType.STRING) + .withVariableType(FeatureVariable.STRING_TYPE) .build(); } diff --git a/core-api/src/test/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigServiceTest.java b/core-api/src/test/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigServiceTest.java index c116b2f4f..44808c93b 100644 --- a/core-api/src/test/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigServiceTest.java +++ b/core-api/src/test/java/com/optimizely/ab/optimizelyconfig/OptimizelyConfigServiceTest.java @@ -131,7 +131,7 @@ public void testGenerateFeatureKeyToVariablesMap() { assertEquals(expectedOptimizelyVariable.getId(), featureVariable.getId()); assertEquals(expectedOptimizelyVariable.getValue(), featureVariable.getDefaultValue()); assertEquals(expectedOptimizelyVariable.getKey(), featureVariable.getKey()); - assertEquals(expectedOptimizelyVariable.getType(), featureVariable.getType().getVariableType().toLowerCase()); + assertEquals(expectedOptimizelyVariable.getType(), featureVariable.getType()); } @Test @@ -287,14 +287,14 @@ private ProjectConfig generateOptimizelyConfig() { "first_letter", "H", FeatureVariable.VariableStatus.ACTIVE, - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE ), new FeatureVariable( "4052219963", "rest_of_name", "arry", FeatureVariable.VariableStatus.ACTIVE, - FeatureVariable.VariableType.STRING + FeatureVariable.STRING_TYPE ) ) ) diff --git a/core-api/src/test/resources/config/valid-project-config-v4.json b/core-api/src/test/resources/config/valid-project-config-v4.json index 4f58f4c66..293b26cc7 100644 --- a/core-api/src/test/resources/config/valid-project-config-v4.json +++ b/core-api/src/test/resources/config/valid-project-config-v4.json @@ -632,8 +632,7 @@ "key": "double_variable", "type": "double", "defaultValue": "14.99" - } - ] + } ] }, { "id": "3281420120", @@ -694,6 +693,12 @@ "key": "rest_of_name", "type": "string", "defaultValue": "arry" + }, + { + "id": "4111661234", + "key": "future_variable", + "type": "future_type", + "defaultValue": "future_value" } ] }, From a336d5df03fe4cea686750b5506f1265547a5056 Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Wed, 15 Apr 2020 15:58:47 -0700 Subject: [PATCH 2/2] fix switch default error --- core-api/src/main/java/com/optimizely/ab/Optimizely.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core-api/src/main/java/com/optimizely/ab/Optimizely.java b/core-api/src/main/java/com/optimizely/ab/Optimizely.java index 4f90a0f5c..39690a82e 100644 --- a/core-api/src/main/java/com/optimizely/ab/Optimizely.java +++ b/core-api/src/main/java/com/optimizely/ab/Optimizely.java @@ -714,6 +714,8 @@ Object convertStringToType(String variableValue, String type) { "\" as Integer. " + exception.toString()); } break; + default: + return variableValue; } }