use of com.optimizely.ab.bucketing.FeatureDecision in project java-sdk by optimizely.
the class OptimizelyTest method isFeatureEnabledWithListenerUserInExperimentFeatureOff.
/**
* Verify that the {@link Optimizely#isFeatureEnabled(String, String, Map<String, String>)}
* notification listener of isFeatureEnabled is called when feature is in experiment and feature is false
*/
@Test
public void isFeatureEnabledWithListenerUserInExperimentFeatureOff() throws Exception {
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
isListenerCalled = false;
final String validFeatureKey = FEATURE_MULTI_VARIATE_FEATURE_KEY;
Optimizely optimizely = optimizelyBuilder.withDecisionService(mockDecisionService).build();
final Map<String, String> testUserAttributes = new HashMap<>();
testUserAttributes.put(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE);
final Map<String, String> testSourceInfo = new HashMap<>();
testSourceInfo.put(VARIATION_KEY, "variation_toggled_off");
testSourceInfo.put(EXPERIMENT_KEY, "multivariate_experiment");
final Map<String, Object> testDecisionInfoMap = new HashMap<>();
testDecisionInfoMap.put(FEATURE_KEY, validFeatureKey);
testDecisionInfoMap.put(FEATURE_ENABLED, false);
testDecisionInfoMap.put(SOURCE, FeatureDecision.DecisionSource.FEATURE_TEST.toString());
testDecisionInfoMap.put(SOURCE_INFO, testSourceInfo);
int notificationId = optimizely.addDecisionNotificationHandler(getDecisionListener(NotificationCenter.DecisionNotificationType.FEATURE.toString(), genericUserId, testUserAttributes, testDecisionInfoMap));
Experiment activatedExperiment = validProjectConfig.getExperimentKeyMapping().get(EXPERIMENT_MULTIVARIATE_EXPERIMENT_KEY);
Variation variation = new Variation("2", "variation_toggled_off", false, null);
FeatureDecision featureDecision = new FeatureDecision(activatedExperiment, variation, FeatureDecision.DecisionSource.FEATURE_TEST);
doReturn(DecisionResponse.responseNoReasons(featureDecision)).when(mockDecisionService).getVariationForFeature(any(FeatureFlag.class), any(OptimizelyUserContext.class), any(ProjectConfig.class));
assertFalse(optimizely.isFeatureEnabled(validFeatureKey, genericUserId, testUserAttributes));
eventHandler.expectImpression(activatedExperiment.getId(), variation.getId(), genericUserId, testUserAttributes);
logbackVerifier.expectMessage(Level.INFO, "Feature \"" + validFeatureKey + "\" is enabled for user \"" + genericUserId + "\"? false");
// Verify that listener being called
assertTrue(isListenerCalled);
assertTrue(optimizely.notificationCenter.removeNotificationListener(notificationId));
}
use of com.optimizely.ab.bucketing.FeatureDecision in project java-sdk by optimizely.
the class OptimizelyTest method getFeatureVariableValueReturnsDefaultValueWhenFeatureEnabledIsFalse.
/**
* Verify {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, FeatureVariable.VariableType)}
* is called when the variation is not null and feature enabled is false
* returns the default variable value
*/
@Test
public void getFeatureVariableValueReturnsDefaultValueWhenFeatureEnabledIsFalse() throws Exception {
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
String validFeatureKey = FEATURE_MULTI_VARIATE_FEATURE_KEY;
String validVariableKey = VARIABLE_FIRST_LETTER_KEY;
String expectedValue = VARIABLE_FIRST_LETTER_DEFAULT_VALUE;
Experiment multivariateExperiment = validProjectConfig.getExperimentKeyMapping().get(EXPERIMENT_MULTIVARIATE_EXPERIMENT_KEY);
Optimizely optimizely = optimizelyBuilder.withDecisionService(mockDecisionService).build();
FeatureDecision featureDecision = new FeatureDecision(multivariateExperiment, VARIATION_MULTIVARIATE_EXPERIMENT_GRED, FeatureDecision.DecisionSource.FEATURE_TEST);
doReturn(DecisionResponse.responseNoReasons(featureDecision)).when(mockDecisionService).getVariationForFeature(FEATURE_FLAG_MULTI_VARIATE_FEATURE, optimizely.createUserContext(genericUserId, Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE)), validProjectConfig);
String value = optimizely.getFeatureVariableValueForType(validFeatureKey, validVariableKey, genericUserId, Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE), FeatureVariable.STRING_TYPE);
logbackVerifier.expectMessage(Level.INFO, "Feature \"multi_variate_feature\" is not enabled for user \"genericUserId\". Returning the default variable value \"H\".");
assertEquals(expectedValue, value);
}
use of com.optimizely.ab.bucketing.FeatureDecision in project java-sdk by optimizely.
the class Optimizely method isFeatureEnabled.
/**
* Determine whether a boolean feature is enabled.
* Send an impression event if the user is bucketed into an experiment using the feature.
*
* @param featureKey The unique key of the feature.
* @param userId The ID of the user.
* @param attributes The user's attributes.
* @return True if the feature is enabled.
* False if the feature is disabled.
* False if the feature is not found.
*/
@Nonnull
public Boolean isFeatureEnabled(@Nonnull String featureKey, @Nonnull String userId, @Nonnull Map<String, String> attributes) {
if (featureKey == null) {
logger.warn("The featureKey parameter must be nonnull.");
return false;
} else if (userId == null) {
logger.warn("The userId parameter must be nonnull.");
return false;
}
FeatureFlag featureFlag = projectConfig.getFeatureKeyMapping().get(featureKey);
if (featureFlag == null) {
logger.info("No feature flag was found for key \"{}\".", featureKey);
return false;
}
Map<String, String> filteredAttributes = filterAttributes(projectConfig, attributes);
FeatureDecision featureDecision = decisionService.getVariationForFeature(featureFlag, userId, filteredAttributes);
if (featureDecision.variation == null || !featureDecision.variation.getFeatureEnabled()) {
logger.info("Feature \"{}\" is not enabled for user \"{}\".", featureKey, userId);
return false;
} else {
if (featureDecision.decisionSource.equals(FeatureDecision.DecisionSource.EXPERIMENT)) {
sendImpression(projectConfig, featureDecision.experiment, userId, filteredAttributes, featureDecision.variation);
} else {
logger.info("The user \"{}\" is not included in an experiment for feature \"{}\".", userId, featureKey);
}
logger.info("Feature \"{}\" is enabled for user \"{}\".", featureKey, userId);
return true;
}
}
use of com.optimizely.ab.bucketing.FeatureDecision in project java-sdk by optimizely.
the class OptimizelyTest method getFeatureVariableValueReturnsVariationValueWhenUserGetsBucketedToVariation.
/**
* Verify {@link Optimizely#getFeatureVariableValueForType(String, String, String, Map, LiveVariable.VariableType)}
* returns the variable value of the variation the user is bucketed into
* if the variation is not null and the variable has a usage within the variation.
* @throws ConfigParseException
*/
@Test
public void getFeatureVariableValueReturnsVariationValueWhenUserGetsBucketedToVariation() throws ConfigParseException {
assumeTrue(datafileVersion >= Integer.parseInt(ProjectConfig.Version.V4.toString()));
String validFeatureKey = FEATURE_MULTI_VARIATE_FEATURE_KEY;
String validVariableKey = VARIABLE_FIRST_LETTER_KEY;
LiveVariable variable = FEATURE_FLAG_MULTI_VARIATE_FEATURE.getVariableKeyToLiveVariableMap().get(validVariableKey);
String expectedValue = VARIATION_MULTIVARIATE_EXPERIMENT_GRED.getVariableIdToLiveVariableUsageInstanceMap().get(variable.getId()).getValue();
Experiment multivariateExperiment = validProjectConfig.getExperimentKeyMapping().get(EXPERIMENT_MULTIVARIATE_EXPERIMENT_KEY);
Optimizely optimizely = Optimizely.builder(validDatafile, mockEventHandler).withConfig(validProjectConfig).withDecisionService(mockDecisionService).build();
FeatureDecision featureDecision = new FeatureDecision(multivariateExperiment, VARIATION_MULTIVARIATE_EXPERIMENT_GRED, FeatureDecision.DecisionSource.EXPERIMENT);
doReturn(featureDecision).when(mockDecisionService).getVariationForFeature(FEATURE_FLAG_MULTI_VARIATE_FEATURE, genericUserId, Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE));
String value = optimizely.getFeatureVariableValueForType(validFeatureKey, validVariableKey, genericUserId, Collections.singletonMap(ATTRIBUTE_HOUSE_KEY, AUDIENCE_GRYFFINDOR_VALUE), LiveVariable.VariableType.STRING);
assertEquals(expectedValue, value);
}
use of com.optimizely.ab.bucketing.FeatureDecision in project java-sdk by optimizely.
the class Optimizely method getAllFeatureVariables.
/**
* Get the values of all variables in the feature.
*
* @param featureKey The unique key of the feature.
* @param userId The ID of the user.
* @param attributes The user's attributes.
* @return An OptimizelyJSON instance for all variable values.
* Null if the feature could not be found.
*/
@Nullable
public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey, @Nonnull String userId, @Nonnull Map<String, ?> attributes) {
if (featureKey == null) {
logger.warn("The featureKey parameter must be nonnull.");
return null;
} else if (userId == null) {
logger.warn("The userId parameter must be nonnull.");
return null;
}
ProjectConfig projectConfig = getProjectConfig();
if (projectConfig == null) {
logger.error("Optimizely instance is not valid, failing getAllFeatureVariableValues call. type");
return null;
}
FeatureFlag featureFlag = projectConfig.getFeatureKeyMapping().get(featureKey);
if (featureFlag == null) {
logger.info("No feature flag was found for key \"{}\".", featureKey);
return null;
}
Map<String, ?> copiedAttributes = copyAttributes(attributes);
FeatureDecision featureDecision = decisionService.getVariationForFeature(featureFlag, createUserContext(userId, copiedAttributes), projectConfig, Collections.emptyList()).getResult();
Boolean featureEnabled = false;
Variation variation = featureDecision.variation;
if (variation != null) {
featureEnabled = variation.getFeatureEnabled();
if (featureEnabled) {
logger.info("Feature \"{}\" is enabled for user \"{}\".", featureKey, userId);
} else {
logger.info("Feature \"{}\" is not enabled for user \"{}\".", featureKey, userId);
}
} else {
logger.info("User \"{}\" was not bucketed into any variation for feature flag \"{}\". " + "The default values are being returned.", userId, featureKey);
}
Map<String, Object> valuesMap = new HashMap<String, Object>();
for (FeatureVariable variable : featureFlag.getVariables()) {
String value = variable.getDefaultValue();
if (featureEnabled) {
FeatureVariableUsageInstance instance = variation.getVariableIdToFeatureVariableUsageInstanceMap().get(variable.getId());
if (instance != null) {
value = instance.getValue();
}
}
Object convertedValue = convertStringToType(value, variable.getType());
if (convertedValue instanceof OptimizelyJSON) {
convertedValue = ((OptimizelyJSON) convertedValue).toMap();
}
valuesMap.put(variable.getKey(), convertedValue);
}
DecisionNotification decisionNotification = DecisionNotification.newFeatureVariableDecisionNotificationBuilder().withUserId(userId).withAttributes(copiedAttributes).withFeatureKey(featureKey).withFeatureEnabled(featureEnabled).withVariableValues(valuesMap).withFeatureDecision(featureDecision).build();
notificationCenter.send(decisionNotification);
return new OptimizelyJSON(valuesMap);
}
Aggregations