3131import com .optimizely .ab .optimizelyconfig .OptimizelyConfig ;
3232import com .optimizely .ab .optimizelyconfig .OptimizelyConfigManager ;
3333import com .optimizely .ab .optimizelyconfig .OptimizelyConfigService ;
34+ import com .optimizely .ab .optimizelyjson .OptimizelyJSON ;
35+ import com .sun .org .apache .xpath .internal .operations .Variable ;
3436import org .slf4j .Logger ;
3537import org .slf4j .LoggerFactory ;
3638
@@ -601,6 +603,46 @@ public String getFeatureVariableString(@Nonnull String featureKey,
601603 FeatureVariable .STRING_TYPE );
602604 }
603605
606+ /**
607+ * Get the JSON value of the specified variable in the feature.
608+ *
609+ * @param featureKey The unique key of the feature.
610+ * @param variableKey The unique key of the variable.
611+ * @param userId The ID of the user.
612+ * @return An OptimizelyJSON instance for the JSON variable value.
613+ * Null if the feature or variable could not be found.
614+ */
615+ @ Nullable
616+ public OptimizelyJSON getFeatureVariableJSON (@ Nonnull String featureKey ,
617+ @ Nonnull String variableKey ,
618+ @ Nonnull String userId ) {
619+ return getFeatureVariableJSON (featureKey , variableKey , userId , Collections .<String , String >emptyMap ());
620+ }
621+
622+ /**
623+ * Get the JSON value of the specified variable in the feature.
624+ *
625+ * @param featureKey The unique key of the feature.
626+ * @param variableKey The unique key of the variable.
627+ * @param userId The ID of the user.
628+ * @param attributes The user's attributes.
629+ * @return An OptimizelyJSON instance for the JSON variable value.
630+ * Null if the feature or variable could not be found.
631+ */
632+ @ Nullable
633+ public OptimizelyJSON getFeatureVariableJSON (@ Nonnull String featureKey ,
634+ @ Nonnull String variableKey ,
635+ @ Nonnull String userId ,
636+ @ Nonnull Map <String , ?> attributes ) {
637+
638+ return getFeatureVariableValueForType (
639+ featureKey ,
640+ variableKey ,
641+ userId ,
642+ attributes ,
643+ FeatureVariable .JSON_TYPE );
644+ }
645+
604646 @ VisibleForTesting
605647 <T > T getFeatureVariableValueForType (@ Nonnull String featureKey ,
606648 @ Nonnull String variableKey ,
@@ -714,6 +756,8 @@ Object convertStringToType(String variableValue, String type) {
714756 "\" as Integer. " + exception .toString ());
715757 }
716758 break ;
759+ case FeatureVariable .JSON_TYPE :
760+ return new OptimizelyJSON (variableValue );
717761 default :
718762 return variableValue ;
719763 }
@@ -722,6 +766,103 @@ Object convertStringToType(String variableValue, String type) {
722766 return null ;
723767 }
724768
769+ /**
770+ * Get the values of all variables in the feature.
771+ *
772+ * @param featureKey The unique key of the feature.
773+ * @param userId The ID of the user.
774+ * @return An OptimizelyJSON instance for all variable values.
775+ * Null if the feature could not be found.
776+ */
777+ @ Nullable
778+ public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
779+ @ Nonnull String userId ) {
780+ return getAllFeatureVariables (featureKey , userId , Collections .<String , String >emptyMap ());
781+ }
782+
783+ /**
784+ * Get the values of all variables in the feature.
785+ *
786+ * @param featureKey The unique key of the feature.
787+ * @param userId The ID of the user.
788+ * @param attributes The user's attributes.
789+ * @return An OptimizelyJSON instance for all variable values.
790+ * Null if the feature could not be found.
791+ */
792+ @ Nullable
793+ public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
794+ @ Nonnull String userId ,
795+ @ Nonnull Map <String , ?> attributes ) {
796+
797+ if (featureKey == null ) {
798+ logger .warn ("The featureKey parameter must be nonnull." );
799+ return null ;
800+ } else if (userId == null ) {
801+ logger .warn ("The userId parameter must be nonnull." );
802+ return null ;
803+ }
804+
805+ ProjectConfig projectConfig = getProjectConfig ();
806+ if (projectConfig == null ) {
807+ logger .error ("Optimizely instance is not valid, failing getAllFeatureVariableValues call. type" );
808+ return null ;
809+ }
810+
811+ FeatureFlag featureFlag = projectConfig .getFeatureKeyMapping ().get (featureKey );
812+ if (featureFlag == null ) {
813+ logger .info ("No feature flag was found for key \" {}\" ." , featureKey );
814+ return null ;
815+ }
816+
817+ Map <String , ?> copiedAttributes = copyAttributes (attributes );
818+ FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , userId , copiedAttributes , projectConfig );
819+ Boolean featureEnabled = false ;
820+ Variation variation = featureDecision .variation ;
821+
822+ if (variation != null ) {
823+ if (!variation .getFeatureEnabled ()) {
824+ logger .info ("Feature \" {}\" for variation \" {}\" was not enabled. " +
825+ "The default value is being returned." , featureKey , featureDecision .variation .getKey ());
826+ }
827+
828+ featureEnabled = variation .getFeatureEnabled ();
829+ } else {
830+ logger .info ("User \" {}\" was not bucketed into any variation for feature flag \" {}\" . " +
831+ "The default values are being returned." , userId , featureKey );
832+ }
833+
834+ Map <String , Object > valuesMap = new HashMap <String , Object >();
835+ for (FeatureVariable variable : featureFlag .getVariables ()) {
836+ String value = variable .getDefaultValue ();
837+ if (featureEnabled && variation != null ) {
838+ FeatureVariableUsageInstance instance = variation .getVariableIdToFeatureVariableUsageInstanceMap ().get (variable .getId ());
839+ if (instance != null ) {
840+ value = instance .getValue ();
841+ }
842+ }
843+
844+ Object convertedValue = convertStringToType (value , variable .getType ());
845+ if (convertedValue instanceof OptimizelyJSON ) {
846+ convertedValue = ((OptimizelyJSON ) convertedValue ).toMap ();
847+ }
848+
849+ valuesMap .put (variable .getKey (), value );
850+ }
851+
852+ DecisionNotification decisionNotification = DecisionNotification .newFeatureVariableDecisionNotificationBuilder ()
853+ .withUserId (userId )
854+ .withAttributes (copiedAttributes )
855+ .withFeatureKey (featureKey )
856+ .withFeatureEnabled (featureEnabled )
857+ .withVariableValues (valuesMap )
858+ .withFeatureDecision (featureDecision )
859+ .build ();
860+
861+ notificationCenter .send (decisionNotification );
862+
863+ return new OptimizelyJSON (valuesMap );
864+ }
865+
725866 /**
726867 * Get the list of features that are enabled for the user.
727868 * TODO revisit this method. Calling this as-is can dramatically increase visitor impression counts.
0 commit comments