1515 ***************************************************************************/
1616package com .optimizely .ab .bucketing ;
1717
18+ import java .util .AbstractMap ;
19+ import java .util .ArrayList ;
20+ import java .util .Arrays ;
21+ import java .util .Collections ;
22+ import java .util .List ;
23+ import java .util .Map ;
24+ import java .util .concurrent .ConcurrentHashMap ;
25+
26+ import javax .annotation .Nonnull ;
27+ import javax .annotation .Nullable ;
28+
29+ import org .slf4j .Logger ;
30+ import org .slf4j .LoggerFactory ;
31+
1832import com .optimizely .ab .OptimizelyDecisionContext ;
1933import com .optimizely .ab .OptimizelyForcedDecision ;
2034import com .optimizely .ab .OptimizelyRuntimeException ;
2135import com .optimizely .ab .OptimizelyUserContext ;
22- import com .optimizely .ab .config .*;
36+ import com .optimizely .ab .config .Experiment ;
37+ import com .optimizely .ab .config .FeatureFlag ;
38+ import com .optimizely .ab .config .Holdout ;
39+ import com .optimizely .ab .config .ProjectConfig ;
40+ import com .optimizely .ab .config .Rollout ;
41+ import com .optimizely .ab .config .Variation ;
2342import com .optimizely .ab .error .ErrorHandler ;
2443import com .optimizely .ab .internal .ControlAttribute ;
2544import com .optimizely .ab .internal .ExperimentUtils ;
45+ import static com .optimizely .ab .internal .LoggingConstants .LoggingEntityType .EXPERIMENT ;
46+ import static com .optimizely .ab .internal .LoggingConstants .LoggingEntityType .RULE ;
2647import com .optimizely .ab .optimizelydecision .DecisionReasons ;
2748import com .optimizely .ab .optimizelydecision .DecisionResponse ;
2849import com .optimizely .ab .optimizelydecision .DefaultDecisionReasons ;
2950import com .optimizely .ab .optimizelydecision .OptimizelyDecideOption ;
30- import org .slf4j .Logger ;
31- import org .slf4j .LoggerFactory ;
32- import javax .annotation .Nonnull ;
33- import javax .annotation .Nullable ;
34- import java .util .*;
35- import java .util .concurrent .ConcurrentHashMap ;
36-
37- import static com .optimizely .ab .internal .LoggingConstants .LoggingEntityType .EXPERIMENT ;
38- import static com .optimizely .ab .internal .LoggingConstants .LoggingEntityType .RULE ;
3951
4052/**
4153 * Optimizely's decision service that determines which variation of an experiment the user will be allocated to.
@@ -446,7 +458,7 @@ DecisionResponse<Variation> getVariationForHoldout(@Nonnull Holdout holdout,
446458 DecisionReasons reasons = DefaultDecisionReasons .newInstance ();
447459
448460 if (!holdout .isActive ()) {
449- String message = reasons .addInfo ("Holdout \" %s \" is not running." , holdout .getKey ());
461+ String message = reasons .addInfo ("Holdout (%s) is not running." , holdout .getKey ());
450462 logger .info (message );
451463 return new DecisionResponse <>(null , reasons );
452464 }
@@ -455,6 +467,10 @@ DecisionResponse<Variation> getVariationForHoldout(@Nonnull Holdout holdout,
455467 reasons .merge (decisionMeetAudience .getReasons ());
456468
457469 if (decisionMeetAudience .getResult ()) {
470+ // User meets audience conditions for holdout
471+ String audienceMatchMessage = reasons .addInfo ("User (%s) meets audience conditions for holdout (%s)." , user .getUserId (), holdout .getKey ());
472+ logger .info (audienceMatchMessage );
473+
458474 String bucketingId = getBucketingId (user .getUserId (), user .getAttributes ());
459475 DecisionResponse <Variation > decisionVariation = bucketer .bucket (holdout , bucketingId , projectConfig );
460476 reasons .merge (decisionVariation .getReasons ());
0 commit comments