11/****************************************************************************
2- * Copyright 2017-2018 , Optimizely, Inc. and contributors *
2+ * Copyright 2017-2019 , Optimizely, Inc. and contributors *
33 * *
44 * Licensed under the Apache License, Version 2.0 (the "License"); *
55 * you may not use this file except in compliance with the License. *
@@ -55,9 +55,10 @@ public class DecisionService {
5555
5656 /**
5757 * Initialize a decision service for the Optimizely client.
58- * @param bucketer Base bucketer to allocate new users to an experiment.
59- * @param errorHandler The error handler of the Optimizely client.
60- * @param projectConfig Optimizely Project Config representing the datafile.
58+ *
59+ * @param bucketer Base bucketer to allocate new users to an experiment.
60+ * @param errorHandler The error handler of the Optimizely client.
61+ * @param projectConfig Optimizely Project Config representing the datafile.
6162 * @param userProfileService UserProfileService implementation for storing user info.
6263 */
6364 public DecisionService (@ Nonnull Bucketer bucketer ,
@@ -73,14 +74,15 @@ public DecisionService(@Nonnull Bucketer bucketer,
7374 /**
7475 * Get a {@link Variation} of an {@link Experiment} for a user to be allocated into.
7576 *
76- * @param experiment The Experiment the user will be bucketed into.
77- * @param userId The userId of the user.
77+ * @param experiment The Experiment the user will be bucketed into.
78+ * @param userId The userId of the user.
7879 * @param filteredAttributes The user's attributes. This should be filtered to just attributes in the Datafile.
7980 * @return The {@link Variation} the user is allocated into.
8081 */
81- public @ Nullable Variation getVariation (@ Nonnull Experiment experiment ,
82- @ Nonnull String userId ,
83- @ Nonnull Map <String , ?> filteredAttributes ) {
82+ @ Nullable
83+ public Variation getVariation (@ Nonnull Experiment experiment ,
84+ @ Nonnull String userId ,
85+ @ Nonnull Map <String , ?> filteredAttributes ) {
8486
8587 if (!ExperimentUtils .isExperimentActive (experiment )) {
8688 return null ;
@@ -100,7 +102,7 @@ public DecisionService(@Nonnull Bucketer bucketer,
100102
101103 // fetch the user profile map from the user profile service
102104 UserProfile userProfile = null ;
103-
105+
104106 if (userProfileService != null ) {
105107 try {
106108 Map <String , Object > userProfileMap = userProfileService .lookup (userId );
@@ -149,21 +151,23 @@ public DecisionService(@Nonnull Bucketer bucketer,
149151
150152 /**
151153 * Get the variation the user is bucketed into for the FeatureFlag
152- * @param featureFlag The feature flag the user wants to access.
153- * @param userId User Identifier
154+ *
155+ * @param featureFlag The feature flag the user wants to access.
156+ * @param userId User Identifier
154157 * @param filteredAttributes A map of filtered attributes.
155158 * @return {@link FeatureDecision}
156159 */
157- public @ Nonnull FeatureDecision getVariationForFeature (@ Nonnull FeatureFlag featureFlag ,
158- @ Nonnull String userId ,
159- @ Nonnull Map <String , ?> filteredAttributes ) {
160+ @ Nonnull
161+ public FeatureDecision getVariationForFeature (@ Nonnull FeatureFlag featureFlag ,
162+ @ Nonnull String userId ,
163+ @ Nonnull Map <String , ?> filteredAttributes ) {
160164 if (!featureFlag .getExperimentIds ().isEmpty ()) {
161165 for (String experimentId : featureFlag .getExperimentIds ()) {
162166 Experiment experiment = projectConfig .getExperimentIdMapping ().get (experimentId );
163167 Variation variation = this .getVariation (experiment , userId , filteredAttributes );
164168 if (variation != null ) {
165169 return new FeatureDecision (experiment , variation ,
166- FeatureDecision .DecisionSource .EXPERIMENT );
170+ FeatureDecision .DecisionSource .EXPERIMENT );
167171 }
168172 }
169173 } else {
@@ -173,10 +177,10 @@ public DecisionService(@Nonnull Bucketer bucketer,
173177 FeatureDecision featureDecision = getVariationForFeatureInRollout (featureFlag , userId , filteredAttributes );
174178 if (featureDecision .variation == null ) {
175179 logger .info ("The user \" {}\" was not bucketed into a rollout for feature flag \" {}\" ." ,
176- userId , featureFlag .getKey ());
180+ userId , featureFlag .getKey ());
177181 } else {
178182 logger .info ("The user \" {}\" was bucketed into a rollout for feature flag \" {}\" ." ,
179- userId , featureFlag .getKey ());
183+ userId , featureFlag .getKey ());
180184 }
181185 return featureDecision ;
182186 }
@@ -185,14 +189,16 @@ public DecisionService(@Nonnull Bucketer bucketer,
185189 * Try to bucket the user into a rollout rule.
186190 * Evaluate the user for rules in priority order by seeing if the user satisfies the audience.
187191 * Fall back onto the everyone else rule if the user is ever excluded from a rule due to traffic allocation.
188- * @param featureFlag The feature flag the user wants to access.
189- * @param userId User Identifier
192+ *
193+ * @param featureFlag The feature flag the user wants to access.
194+ * @param userId User Identifier
190195 * @param filteredAttributes A map of filtered attributes.
191196 * @return {@link FeatureDecision}
192197 */
193- @ Nonnull FeatureDecision getVariationForFeatureInRollout (@ Nonnull FeatureFlag featureFlag ,
194- @ Nonnull String userId ,
195- @ Nonnull Map <String , ?> filteredAttributes ) {
198+ @ Nonnull
199+ FeatureDecision getVariationForFeatureInRollout (@ Nonnull FeatureFlag featureFlag ,
200+ @ Nonnull String userId ,
201+ @ Nonnull Map <String , ?> filteredAttributes ) {
196202 // use rollout to get variation for feature
197203 if (featureFlag .getRolloutId ().isEmpty ()) {
198204 logger .info ("The feature flag \" {}\" is not used in a rollout." , featureFlag .getKey ());
@@ -201,7 +207,7 @@ public DecisionService(@Nonnull Bucketer bucketer,
201207 Rollout rollout = projectConfig .getRolloutIdMapping ().get (featureFlag .getRolloutId ());
202208 if (rollout == null ) {
203209 logger .error ("The rollout with id \" {}\" was not found in the datafile for feature flag \" {}\" ." ,
204- featureFlag .getRolloutId (), featureFlag .getKey ());
210+ featureFlag .getRolloutId (), featureFlag .getKey ());
205211 return new FeatureDecision (null , null , null );
206212 }
207213
@@ -218,11 +224,10 @@ public DecisionService(@Nonnull Bucketer bucketer,
218224 break ;
219225 }
220226 return new FeatureDecision (rolloutRule , variation ,
221- FeatureDecision .DecisionSource .ROLLOUT );
222- }
223- else {
227+ FeatureDecision .DecisionSource .ROLLOUT );
228+ } else {
224229 logger .debug ("User \" {}\" did not meet the conditions to be in rollout rule for audience \" {}\" ." ,
225- userId , audience .getName ());
230+ userId , audience .getName ());
226231 }
227232 }
228233
@@ -232,20 +237,22 @@ public DecisionService(@Nonnull Bucketer bucketer,
232237 variation = bucketer .bucket (finalRule , bucketingId );
233238 if (variation != null ) {
234239 return new FeatureDecision (finalRule , variation ,
235- FeatureDecision .DecisionSource .ROLLOUT );
240+ FeatureDecision .DecisionSource .ROLLOUT );
236241 }
237242 }
238243 return new FeatureDecision (null , null , null );
239244 }
240245
241246 /**
242247 * Get the variation the user has been whitelisted into.
248+ *
243249 * @param experiment {@link Experiment} in which user is to be bucketed.
244- * @param userId User Identifier
250+ * @param userId User Identifier
245251 * @return null if the user is not whitelisted into any variation
246- * {@link Variation} the user is bucketed into if the user has a specified whitelisted variation.
252+ * {@link Variation} the user is bucketed into if the user has a specified whitelisted variation.
247253 */
248- @ Nullable Variation getWhitelistedVariation (@ Nonnull Experiment experiment , @ Nonnull String userId ) {
254+ @ Nullable
255+ Variation getWhitelistedVariation (@ Nonnull Experiment experiment , @ Nonnull String userId ) {
249256 // if a user has a forced variation mapping, return the respective variation
250257 Map <String , String > userIdToVariationKeyMap = experiment .getUserIdToVariationKeyMap ();
251258 if (userIdToVariationKeyMap .containsKey (userId )) {
@@ -255,7 +262,7 @@ public DecisionService(@Nonnull Bucketer bucketer,
255262 logger .info ("User \" {}\" is forced in variation \" {}\" ." , userId , forcedVariationKey );
256263 } else {
257264 logger .error ("Variation \" {}\" is not in the datafile. Not activating user \" {}\" ." ,
258- forcedVariationKey , userId );
265+ forcedVariationKey , userId );
259266 }
260267 return forcedVariation ;
261268 }
@@ -264,13 +271,15 @@ public DecisionService(@Nonnull Bucketer bucketer,
264271
265272 /**
266273 * Get the {@link Variation} that has been stored for the user in the {@link UserProfileService} implementation.
267- * @param experiment {@link Experiment} in which the user was bucketed.
274+ *
275+ * @param experiment {@link Experiment} in which the user was bucketed.
268276 * @param userProfile {@link UserProfile} of the user.
269277 * @return null if the {@link UserProfileService} implementation is null or the user was not previously bucketed.
270- * else return the {@link Variation} the user was previously bucketed into.
278+ * else return the {@link Variation} the user was previously bucketed into.
271279 */
272- @ Nullable Variation getStoredVariation (@ Nonnull Experiment experiment ,
273- @ Nonnull UserProfile userProfile ) {
280+ @ Nullable
281+ Variation getStoredVariation (@ Nonnull Experiment experiment ,
282+ @ Nonnull UserProfile userProfile ) {
274283 // ---------- Check User Profile for Sticky Bucketing ----------
275284 // If a user profile instance is present then check it for a saved variation
276285 String experimentId = experiment .getId ();
@@ -279,35 +288,35 @@ public DecisionService(@Nonnull Bucketer bucketer,
279288 if (decision != null ) {
280289 String variationId = decision .variationId ;
281290 Variation savedVariation = projectConfig
282- .getExperimentIdMapping ()
283- .get (experimentId )
284- .getVariationIdToVariationMap ()
285- .get (variationId );
291+ .getExperimentIdMapping ()
292+ .get (experimentId )
293+ .getVariationIdToVariationMap ()
294+ .get (variationId );
286295 if (savedVariation != null ) {
287296 logger .info ("Returning previously activated variation \" {}\" of experiment \" {}\" " +
288- "for user \" {}\" from user profile." ,
289- savedVariation .getKey (), experimentKey , userProfile .userId );
297+ "for user \" {}\" from user profile." ,
298+ savedVariation .getKey (), experimentKey , userProfile .userId );
290299 // A variation is stored for this combined bucket id
291300 return savedVariation ;
292301 } else {
293302 logger .info ("User \" {}\" was previously bucketed into variation with ID \" {}\" for experiment \" {}\" , " +
294- "but no matching variation was found for that user. We will re-bucket the user." ,
295- userProfile .userId , variationId , experimentKey );
303+ "but no matching variation was found for that user. We will re-bucket the user." ,
304+ userProfile .userId , variationId , experimentKey );
296305 return null ;
297306 }
298307 } else {
299308 logger .info ("No previously activated variation of experiment \" {}\" " +
300- "for user \" {}\" found in user profile." ,
301- experimentKey , userProfile .userId );
309+ "for user \" {}\" found in user profile." ,
310+ experimentKey , userProfile .userId );
302311 return null ;
303312 }
304313 }
305314
306315 /**
307316 * Save a {@link Variation} of an {@link Experiment} for a user in the {@link UserProfileService}.
308317 *
309- * @param experiment The experiment the user was buck
310- * @param variation The Variation to save.
318+ * @param experiment The experiment the user was buck
319+ * @param variation The Variation to save.
311320 * @param userProfile A {@link UserProfile} instance of the user information.
312321 */
313322 void saveVariation (@ Nonnull Experiment experiment ,
@@ -332,18 +341,19 @@ void saveVariation(@Nonnull Experiment experiment,
332341 variationId , experimentId , userProfile .userId );
333342 } catch (Exception exception ) {
334343 logger .warn ("Failed to save variation \" {}\" of experiment \" {}\" for user \" {}\" ." ,
335- variationId , experimentId , userProfile .userId );
344+ variationId , experimentId , userProfile .userId );
336345 errorHandler .handleError (new OptimizelyRuntimeException (exception ));
337346 }
338347 }
339348 }
340349
341350 /**
342351 * Get the bucketingId of a user if a bucketingId exists in attributes, or else default to userId.
343- * @param userId The userId of the user.
352+ *
353+ * @param userId The userId of the user.
344354 * @param filteredAttributes The user's attributes. This should be filtered to just attributes in the Datafile.
345355 * @return bucketingId if it is a String type in attributes.
346- * else return userId
356+ * else return userId
347357 */
348358 String getBucketingId (@ Nonnull String userId ,
349359 @ Nonnull Map <String , ?> filteredAttributes ) {
@@ -352,10 +362,9 @@ String getBucketingId(@Nonnull String userId,
352362 if (String .class .isInstance (filteredAttributes .get (ControlAttribute .BUCKETING_ATTRIBUTE .toString ()))) {
353363 bucketingId = (String ) filteredAttributes .get (ControlAttribute .BUCKETING_ATTRIBUTE .toString ());
354364 logger .debug ("BucketingId is valid: \" {}\" " , bucketingId );
355- }
356- else {
365+ } else {
357366 logger .warn ("BucketingID attribute is not a string. Defaulted to userId" );
358- }
367+ }
359368 }
360369 return bucketingId ;
361370 }
0 commit comments