@@ -376,7 +376,7 @@ public void track(@Nonnull String eventName,
376
376
@ Nonnull
377
377
public Boolean isFeatureEnabled (@ Nonnull String featureKey ,
378
378
@ Nonnull String userId ) {
379
- return isFeatureEnabled (featureKey , userId , Collections .< String , String > emptyMap ());
379
+ return isFeatureEnabled (featureKey , userId , Collections .emptyMap ());
380
380
}
381
381
382
382
/**
@@ -424,7 +424,7 @@ private Boolean isFeatureEnabled(@Nonnull ProjectConfig projectConfig,
424
424
425
425
Map <String , ?> copiedAttributes = copyAttributes (attributes );
426
426
FeatureDecision .DecisionSource decisionSource = FeatureDecision .DecisionSource .ROLLOUT ;
427
- FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , userId , copiedAttributes , projectConfig ).getResult ();
427
+ FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , createUserContext ( userId , copiedAttributes ) , projectConfig ).getResult ();
428
428
Boolean featureEnabled = false ;
429
429
SourceInfo sourceInfo = new RolloutSourceInfo ();
430
430
if (featureDecision .decisionSource != null ) {
@@ -733,7 +733,7 @@ <T> T getFeatureVariableValueForType(@Nonnull String featureKey,
733
733
734
734
String variableValue = variable .getDefaultValue ();
735
735
Map <String , ?> copiedAttributes = copyAttributes (attributes );
736
- FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , userId , copiedAttributes , projectConfig ).getResult ();
736
+ FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , createUserContext ( userId , copiedAttributes ) , projectConfig ).getResult ();
737
737
Boolean featureEnabled = false ;
738
738
if (featureDecision .variation != null ) {
739
739
if (featureDecision .variation .getFeatureEnabled ()) {
@@ -824,6 +824,7 @@ Object convertStringToType(String variableValue, String type) {
824
824
* @param userId The ID of the user.
825
825
* @return An OptimizelyJSON instance for all variable values.
826
826
* Null if the feature could not be found.
827
+ *
827
828
*/
828
829
@ Nullable
829
830
public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
@@ -839,6 +840,7 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
839
840
* @param attributes The user's attributes.
840
841
* @return An OptimizelyJSON instance for all variable values.
841
842
* Null if the feature could not be found.
843
+ *
842
844
*/
843
845
@ Nullable
844
846
public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
@@ -866,7 +868,7 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
866
868
}
867
869
868
870
Map <String , ?> copiedAttributes = copyAttributes (attributes );
869
- FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , userId , copiedAttributes , projectConfig ).getResult ();
871
+ FeatureDecision featureDecision = decisionService .getVariationForFeature (featureFlag , createUserContext ( userId , copiedAttributes ) , projectConfig , Collections . emptyList () ).getResult ();
870
872
Boolean featureEnabled = false ;
871
873
Variation variation = featureDecision .variation ;
872
874
@@ -922,9 +924,10 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
922
924
* @param attributes The user's attributes.
923
925
* @return List of the feature keys that are enabled for the user if the userId is empty it will
924
926
* return Empty List.
927
+ *
925
928
*/
926
929
public List <String > getEnabledFeatures (@ Nonnull String userId , @ Nonnull Map <String , ?> attributes ) {
927
- List <String > enabledFeaturesList = new ArrayList < String > ();
930
+ List <String > enabledFeaturesList = new ArrayList ();
928
931
if (!validateUserId (userId )) {
929
932
return enabledFeaturesList ;
930
933
}
@@ -951,7 +954,7 @@ public List<String> getEnabledFeatures(@Nonnull String userId, @Nonnull Map<Stri
951
954
public Variation getVariation (@ Nonnull Experiment experiment ,
952
955
@ Nonnull String userId ) throws UnknownExperimentException {
953
956
954
- return getVariation (experiment , userId , Collections .< String , String > emptyMap ());
957
+ return getVariation (experiment , userId , Collections .emptyMap ());
955
958
}
956
959
957
960
@ Nullable
@@ -967,8 +970,7 @@ private Variation getVariation(@Nonnull ProjectConfig projectConfig,
967
970
@ Nonnull String userId ,
968
971
@ Nonnull Map <String , ?> attributes ) throws UnknownExperimentException {
969
972
Map <String , ?> copiedAttributes = copyAttributes (attributes );
970
- Variation variation = decisionService .getVariation (experiment , userId , copiedAttributes , projectConfig ).getResult ();
971
-
973
+ Variation variation = decisionService .getVariation (experiment , createUserContext (userId , copiedAttributes ), projectConfig ).getResult ();
972
974
String notificationType = NotificationCenter .DecisionNotificationType .AB_TEST .toString ();
973
975
974
976
if (projectConfig .getExperimentFeatureKeyMapping ().get (experiment .getId ()) != null ) {
@@ -1145,7 +1147,7 @@ public OptimizelyConfig getOptimizelyConfig() {
1145
1147
* @return An OptimizelyUserContext associated with this OptimizelyClient.
1146
1148
*/
1147
1149
public OptimizelyUserContext createUserContext (@ Nonnull String userId ,
1148
- @ Nonnull Map <String , Object > attributes ) {
1150
+ @ Nonnull Map <String , ? > attributes ) {
1149
1151
if (userId == null ) {
1150
1152
logger .warn ("The userId parameter must be nonnull." );
1151
1153
return null ;
@@ -1179,14 +1181,24 @@ OptimizelyDecision decide(@Nonnull OptimizelyUserContext user,
1179
1181
DecisionReasons decisionReasons = DefaultDecisionReasons .newInstance (allOptions );
1180
1182
1181
1183
Map <String , ?> copiedAttributes = new HashMap <>(attributes );
1182
- DecisionResponse <FeatureDecision > decisionVariation = decisionService .getVariationForFeature (
1183
- flag ,
1184
- userId ,
1185
- copiedAttributes ,
1186
- projectConfig ,
1187
- allOptions );
1188
- FeatureDecision flagDecision = decisionVariation .getResult ();
1189
- decisionReasons .merge (decisionVariation .getReasons ());
1184
+ FeatureDecision flagDecision ;
1185
+
1186
+ // Check Forced Decision
1187
+ OptimizelyDecisionContext optimizelyDecisionContext = new OptimizelyDecisionContext (flag .getKey (), null );
1188
+ DecisionResponse <Variation > forcedDecisionVariation = user .findValidatedForcedDecision (optimizelyDecisionContext );
1189
+ decisionReasons .merge (forcedDecisionVariation .getReasons ());
1190
+ if (forcedDecisionVariation .getResult () != null ) {
1191
+ flagDecision = new FeatureDecision (null , forcedDecisionVariation .getResult (), FeatureDecision .DecisionSource .FEATURE_TEST );
1192
+ } else {
1193
+ // Regular decision
1194
+ DecisionResponse <FeatureDecision > decisionVariation = decisionService .getVariationForFeature (
1195
+ flag ,
1196
+ user ,
1197
+ projectConfig ,
1198
+ allOptions );
1199
+ flagDecision = decisionVariation .getResult ();
1200
+ decisionReasons .merge (decisionVariation .getReasons ());
1201
+ }
1190
1202
1191
1203
Boolean flagEnabled = false ;
1192
1204
if (flagDecision .variation != null ) {
@@ -1332,6 +1344,26 @@ private DecisionResponse<Map<String, Object>> getDecisionVariableMap(@Nonnull Fe
1332
1344
return new DecisionResponse (valuesMap , reasons );
1333
1345
}
1334
1346
1347
+ /**
1348
+ * Gets a variation based on flagKey and variationKey
1349
+ *
1350
+ * @param flagKey The flag key for the variation
1351
+ * @param variationKey The variation key for the variation
1352
+ * @return Returns a variation based on flagKey and variationKey, otherwise null
1353
+ */
1354
+ public Variation getFlagVariationByKey (String flagKey , String variationKey ) {
1355
+ Map <String , List <Variation >> flagVariationsMap = getProjectConfig ().getFlagVariationsMap ();
1356
+ if (flagVariationsMap .containsKey (flagKey )) {
1357
+ List <Variation > variations = flagVariationsMap .get (flagKey );
1358
+ for (Variation variation : variations ) {
1359
+ if (variation .getKey ().equals (variationKey )) {
1360
+ return variation ;
1361
+ }
1362
+ }
1363
+ }
1364
+ return null ;
1365
+ }
1366
+
1335
1367
/**
1336
1368
* Helper method which makes separate copy of attributesMap variable and returns it
1337
1369
*
0 commit comments