Search in sources :

Example 1 with OptimizelyRuntimeException

use of com.optimizely.ab.OptimizelyRuntimeException in project java-sdk by optimizely.

the class DecisionService method getVariation.

/**
 * Get a {@link Variation} of an {@link Experiment} for a user to be allocated into.
 *
 * @param experiment The Experiment the user will be bucketed into.
 * @param userId The userId of the user.
 * @param filteredAttributes The user's attributes. This should be filtered to just attributes in the Datafile.
 * @return The {@link Variation} the user is allocated into.
 */
@Nullable
public Variation getVariation(@Nonnull Experiment experiment, @Nonnull String userId, @Nonnull Map<String, String> filteredAttributes) {
    if (!ExperimentUtils.isExperimentActive(experiment)) {
        return null;
    }
    // look for forced bucketing first.
    Variation variation = projectConfig.getForcedVariation(experiment.getKey(), userId);
    // check for whitelisting
    if (variation == null) {
        variation = getWhitelistedVariation(experiment, userId);
    }
    if (variation != null) {
        return variation;
    }
    // fetch the user profile map from the user profile service
    UserProfile userProfile = null;
    if (userProfileService != null) {
        try {
            Map<String, Object> userProfileMap = userProfileService.lookup(userId);
            if (userProfileMap == null) {
                logger.info("We were unable to get a user profile map from the UserProfileService.");
            } else if (UserProfileUtils.isValidUserProfileMap(userProfileMap)) {
                userProfile = UserProfileUtils.convertMapToUserProfile(userProfileMap);
            } else {
                logger.warn("The UserProfileService returned an invalid map.");
            }
        } catch (Exception exception) {
            logger.error(exception.getMessage());
            errorHandler.handleError(new OptimizelyRuntimeException(exception));
        }
    }
    // check if user exists in user profile
    if (userProfile != null) {
        variation = getStoredVariation(experiment, userProfile);
        // return the stored variation if it exists
        if (variation != null) {
            return variation;
        }
    } else {
        // if we could not find a user profile, make a new one
        userProfile = new UserProfile(userId, new HashMap<String, Decision>());
    }
    if (ExperimentUtils.isUserInExperiment(projectConfig, experiment, filteredAttributes)) {
        String bucketingId = userId;
        if (filteredAttributes.containsKey(BUCKETING_ATTRIBUTE)) {
            bucketingId = filteredAttributes.get(BUCKETING_ATTRIBUTE);
        }
        variation = bucketer.bucket(experiment, bucketingId);
        if (variation != null) {
            if (userProfileService != null) {
                saveVariation(experiment, variation, userProfile);
            } else {
                logger.info("This decision will not be saved since the UserProfileService is null.");
            }
        }
        return variation;
    }
    logger.info("User \"{}\" does not meet conditions to be in experiment \"{}\".", userId, experiment.getKey());
    return null;
}
Also used : HashMap(java.util.HashMap) Variation(com.optimizely.ab.config.Variation) OptimizelyRuntimeException(com.optimizely.ab.OptimizelyRuntimeException) OptimizelyRuntimeException(com.optimizely.ab.OptimizelyRuntimeException) Nullable(javax.annotation.Nullable)

Example 2 with OptimizelyRuntimeException

use of com.optimizely.ab.OptimizelyRuntimeException in project java-sdk by optimizely.

the class DecisionService method saveVariation.

/**
 * Save a {@link Variation} of an {@link Experiment} for a user in the {@link UserProfileService}.
 *
 * @param experiment  The experiment the user was buck
 * @param variation   The Variation to save.
 * @param userProfile A {@link UserProfile} instance of the user information.
 */
void saveVariation(@Nonnull Experiment experiment, @Nonnull Variation variation, @Nonnull UserProfile userProfile) {
    // only save if the user has implemented a user profile service
    if (userProfileService != null) {
        String experimentId = experiment.getId();
        String variationId = variation.getId();
        Decision decision;
        if (userProfile.experimentBucketMap.containsKey(experimentId)) {
            decision = userProfile.experimentBucketMap.get(experimentId);
            decision.variationId = variationId;
        } else {
            decision = new Decision(variationId);
        }
        userProfile.experimentBucketMap.put(experimentId, decision);
        try {
            userProfileService.save(userProfile.toMap());
            logger.info("Saved variation \"{}\" of experiment \"{}\" for user \"{}\".", variationId, experimentId, userProfile.userId);
        } catch (Exception exception) {
            logger.warn("Failed to save variation \"{}\" of experiment \"{}\" for user \"{}\".", variationId, experimentId, userProfile.userId);
            errorHandler.handleError(new OptimizelyRuntimeException(exception));
        }
    }
}
Also used : OptimizelyForcedDecision(com.optimizely.ab.OptimizelyForcedDecision) OptimizelyRuntimeException(com.optimizely.ab.OptimizelyRuntimeException) OptimizelyRuntimeException(com.optimizely.ab.OptimizelyRuntimeException)

Example 3 with OptimizelyRuntimeException

use of com.optimizely.ab.OptimizelyRuntimeException in project java-sdk by optimizely.

the class DecisionService method getVariation.

/**
 * Get a {@link Variation} of an {@link Experiment} for a user to be allocated into.
 *
 * @param experiment         The Experiment the user will be bucketed into.
 * @param user               The current OptimizelyUserContext
 * @param projectConfig      The current projectConfig
 * @param options            An array of decision options
 * @return A {@link DecisionResponse} including the {@link Variation} that user is bucketed into (or null) and the decision reasons
 */
@Nonnull
public DecisionResponse<Variation> getVariation(@Nonnull Experiment experiment, @Nonnull OptimizelyUserContext user, @Nonnull ProjectConfig projectConfig, @Nonnull List<OptimizelyDecideOption> options) {
    DecisionReasons reasons = DefaultDecisionReasons.newInstance();
    if (!ExperimentUtils.isExperimentActive(experiment)) {
        String message = reasons.addInfo("Experiment \"%s\" is not running.", experiment.getKey());
        logger.info(message);
        return new DecisionResponse(null, reasons);
    }
    // look for forced bucketing first.
    DecisionResponse<Variation> decisionVariation = getForcedVariation(experiment, user.getUserId());
    reasons.merge(decisionVariation.getReasons());
    Variation variation = decisionVariation.getResult();
    // check for whitelisting
    if (variation == null) {
        decisionVariation = getWhitelistedVariation(experiment, user.getUserId());
        reasons.merge(decisionVariation.getReasons());
        variation = decisionVariation.getResult();
    }
    if (variation != null) {
        return new DecisionResponse(variation, reasons);
    }
    // fetch the user profile map from the user profile service
    boolean ignoreUPS = options.contains(OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE);
    UserProfile userProfile = null;
    if (userProfileService != null && !ignoreUPS) {
        try {
            Map<String, Object> userProfileMap = userProfileService.lookup(user.getUserId());
            if (userProfileMap == null) {
                String message = reasons.addInfo("We were unable to get a user profile map from the UserProfileService.");
                logger.info(message);
            } else if (UserProfileUtils.isValidUserProfileMap(userProfileMap)) {
                userProfile = UserProfileUtils.convertMapToUserProfile(userProfileMap);
            } else {
                String message = reasons.addInfo("The UserProfileService returned an invalid map.");
                logger.warn(message);
            }
        } catch (Exception exception) {
            String message = reasons.addInfo(exception.getMessage());
            logger.error(message);
            errorHandler.handleError(new OptimizelyRuntimeException(exception));
        }
        // check if user exists in user profile
        if (userProfile != null) {
            decisionVariation = getStoredVariation(experiment, userProfile, projectConfig);
            reasons.merge(decisionVariation.getReasons());
            variation = decisionVariation.getResult();
            // return the stored variation if it exists
            if (variation != null) {
                return new DecisionResponse(variation, reasons);
            }
        } else {
            // if we could not find a user profile, make a new one
            userProfile = new UserProfile(user.getUserId(), new HashMap<String, Decision>());
        }
    }
    DecisionResponse<Boolean> decisionMeetAudience = ExperimentUtils.doesUserMeetAudienceConditions(projectConfig, experiment, user.getAttributes(), EXPERIMENT, experiment.getKey());
    reasons.merge(decisionMeetAudience.getReasons());
    if (decisionMeetAudience.getResult()) {
        String bucketingId = getBucketingId(user.getUserId(), user.getAttributes());
        decisionVariation = bucketer.bucket(experiment, bucketingId, projectConfig);
        reasons.merge(decisionVariation.getReasons());
        variation = decisionVariation.getResult();
        if (variation != null) {
            if (userProfileService != null && !ignoreUPS) {
                saveVariation(experiment, variation, userProfile);
            } else {
                logger.debug("This decision will not be saved since the UserProfileService is null.");
            }
        }
        return new DecisionResponse(variation, reasons);
    }
    String message = reasons.addInfo("User \"%s\" does not meet conditions to be in experiment \"%s\".", user.getUserId(), experiment.getKey());
    logger.info(message);
    return new DecisionResponse(null, reasons);
}
Also used : DecisionResponse(com.optimizely.ab.optimizelydecision.DecisionResponse) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) DefaultDecisionReasons(com.optimizely.ab.optimizelydecision.DefaultDecisionReasons) DecisionReasons(com.optimizely.ab.optimizelydecision.DecisionReasons) OptimizelyRuntimeException(com.optimizely.ab.OptimizelyRuntimeException) OptimizelyRuntimeException(com.optimizely.ab.OptimizelyRuntimeException) Nonnull(javax.annotation.Nonnull)

Aggregations

OptimizelyRuntimeException (com.optimizely.ab.OptimizelyRuntimeException)3 OptimizelyForcedDecision (com.optimizely.ab.OptimizelyForcedDecision)1 Variation (com.optimizely.ab.config.Variation)1 DecisionReasons (com.optimizely.ab.optimizelydecision.DecisionReasons)1 DecisionResponse (com.optimizely.ab.optimizelydecision.DecisionResponse)1 DefaultDecisionReasons (com.optimizely.ab.optimizelydecision.DefaultDecisionReasons)1 HashMap (java.util.HashMap)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 Nonnull (javax.annotation.Nonnull)1 Nullable (javax.annotation.Nullable)1