20
20
import com .optimizely .ab .bucketing .DecisionService ;
21
21
import com .optimizely .ab .bucketing .FeatureDecision ;
22
22
import com .optimizely .ab .bucketing .UserProfileService ;
23
- import com .optimizely .ab .config .*;
23
+ import com .optimizely .ab .config .AtomicProjectConfigManager ;
24
+ import com .optimizely .ab .config .DatafileProjectConfig ;
25
+ import com .optimizely .ab .config .EventType ;
26
+ import com .optimizely .ab .config .Experiment ;
27
+ import com .optimizely .ab .config .FeatureFlag ;
28
+ import com .optimizely .ab .config .FeatureVariable ;
29
+ import com .optimizely .ab .config .FeatureVariableUsageInstance ;
30
+ import com .optimizely .ab .config .ProjectConfig ;
31
+ import com .optimizely .ab .config .ProjectConfigManager ;
32
+ import com .optimizely .ab .config .Variation ;
24
33
import com .optimizely .ab .config .parser .ConfigParseException ;
25
34
import com .optimizely .ab .error .ErrorHandler ;
26
35
import com .optimizely .ab .error .NoOpErrorHandler ;
27
- import com .optimizely .ab .event .*;
28
- import com .optimizely .ab .event .internal .*;
36
+ import com .optimizely .ab .event .EventHandler ;
37
+ import com .optimizely .ab .event .EventProcessor ;
38
+ import com .optimizely .ab .event .ForwardingEventProcessor ;
39
+ import com .optimizely .ab .event .LogEvent ;
40
+ import com .optimizely .ab .event .NoopEventHandler ;
41
+ import com .optimizely .ab .event .internal .BuildVersionInfo ;
42
+ import com .optimizely .ab .event .internal .ClientEngineInfo ;
43
+ import com .optimizely .ab .event .internal .EventFactory ;
44
+ import com .optimizely .ab .event .internal .UserEvent ;
45
+ import com .optimizely .ab .event .internal .UserEventFactory ;
29
46
import com .optimizely .ab .event .internal .payload .EventBatch ;
30
47
import com .optimizely .ab .internal .NotificationRegistry ;
31
- import com .optimizely .ab .notification .*;
32
- import com .optimizely .ab .odp .*;
48
+ import com .optimizely .ab .notification .ActivateNotification ;
49
+ import com .optimizely .ab .notification .DecisionNotification ;
50
+ import com .optimizely .ab .notification .FeatureTestSourceInfo ;
51
+ import com .optimizely .ab .notification .NotificationCenter ;
52
+ import com .optimizely .ab .notification .NotificationHandler ;
53
+ import com .optimizely .ab .notification .RolloutSourceInfo ;
54
+ import com .optimizely .ab .notification .SourceInfo ;
55
+ import com .optimizely .ab .notification .TrackNotification ;
56
+ import com .optimizely .ab .notification .UpdateConfigNotification ;
57
+ import com .optimizely .ab .odp .ODPEvent ;
58
+ import com .optimizely .ab .odp .ODPManager ;
59
+ import com .optimizely .ab .odp .ODPSegmentManager ;
60
+ import com .optimizely .ab .odp .ODPSegmentOption ;
33
61
import com .optimizely .ab .optimizelyconfig .OptimizelyConfig ;
34
62
import com .optimizely .ab .optimizelyconfig .OptimizelyConfigManager ;
35
63
import com .optimizely .ab .optimizelyconfig .OptimizelyConfigService ;
36
- import com .optimizely .ab .optimizelydecision .*;
64
+ import com .optimizely .ab .optimizelydecision .DecisionMessage ;
65
+ import com .optimizely .ab .optimizelydecision .DecisionReasons ;
66
+ import com .optimizely .ab .optimizelydecision .DecisionResponse ;
67
+ import com .optimizely .ab .optimizelydecision .DefaultDecisionReasons ;
68
+ import com .optimizely .ab .optimizelydecision .OptimizelyDecideOption ;
69
+ import com .optimizely .ab .optimizelydecision .OptimizelyDecision ;
37
70
import com .optimizely .ab .optimizelyjson .OptimizelyJSON ;
38
- import java .util .concurrent .locks .ReentrantLock ;
39
71
import org .slf4j .Logger ;
40
72
import org .slf4j .LoggerFactory ;
41
73
42
74
import javax .annotation .Nonnull ;
43
75
import javax .annotation .Nullable ;
44
76
import javax .annotation .concurrent .ThreadSafe ;
45
-
46
77
import java .io .Closeable ;
47
- import java .util .*;
48
- import java .util .stream .Collectors ;
78
+ import java .util .ArrayList ;
79
+ import java .util .Arrays ;
80
+ import java .util .Collections ;
81
+ import java .util .HashMap ;
82
+ import java .util .List ;
83
+ import java .util .Map ;
84
+ import java .util .concurrent .locks .ReentrantLock ;
49
85
50
86
import static com .optimizely .ab .internal .SafetyUtils .tryClose ;
51
87
52
88
/**
53
89
* Top-level container class for Optimizely functionality.
54
90
* Thread-safe, so can be created as a singleton and safely passed around.
55
- *
91
+ * <p>
56
92
* Example instantiation:
57
93
* <pre>
58
94
* Optimizely optimizely = Optimizely.builder(projectWatcher, eventHandler).build();
59
95
* </pre>
60
- *
96
+ * <p>
61
97
* To activate an experiment and perform variation specific processing:
62
98
* <pre>
63
99
* Variation variation = optimizely.activate(experimentKey, userId, attributes);
@@ -136,7 +172,9 @@ private Optimizely(@Nonnull EventHandler eventHandler,
136
172
if (projectConfigManager .getSDKKey () != null ) {
137
173
NotificationRegistry .getInternalNotificationCenter (projectConfigManager .getSDKKey ()).
138
174
addNotificationHandler (UpdateConfigNotification .class ,
139
- configNotification -> { updateODPSettings (); });
175
+ configNotification -> {
176
+ updateODPSettings ();
177
+ });
140
178
}
141
179
142
180
}
@@ -634,6 +672,53 @@ public Integer getFeatureVariableInteger(@Nonnull String featureKey,
634
672
return variableValue ;
635
673
}
636
674
675
+ /**
676
+ * Get the Long value of the specified variable in the feature.
677
+ *
678
+ * @param featureKey The unique key of the feature.
679
+ * @param variableKey The unique key of the variable.
680
+ * @param userId The ID of the user.
681
+ * @return The Integer value of the integer single variable feature.
682
+ * Null if the feature or variable could not be found.
683
+ */
684
+ @ Nullable
685
+ public Long getFeatureVariableLong (@ Nonnull String featureKey ,
686
+ @ Nonnull String variableKey ,
687
+ @ Nonnull String userId ) {
688
+ return getFeatureVariableLong (featureKey , variableKey , userId , Collections .emptyMap ());
689
+ }
690
+
691
+ /**
692
+ * Get the Integer value of the specified variable in the feature.
693
+ *
694
+ * @param featureKey The unique key of the feature.
695
+ * @param variableKey The unique key of the variable.
696
+ * @param userId The ID of the user.
697
+ * @param attributes The user's attributes.
698
+ * @return The Integer value of the integer single variable feature.
699
+ * Null if the feature or variable could not be found.
700
+ */
701
+ @ Nullable
702
+ public Long getFeatureVariableLong (@ Nonnull String featureKey ,
703
+ @ Nonnull String variableKey ,
704
+ @ Nonnull String userId ,
705
+ @ Nonnull Map <String , ?> attributes ) {
706
+ try {
707
+ return getFeatureVariableValueForType (
708
+ featureKey ,
709
+ variableKey ,
710
+ userId ,
711
+ attributes ,
712
+ FeatureVariable .INTEGER_TYPE
713
+ );
714
+
715
+ } catch (Exception exception ) {
716
+ logger .error ("NumberFormatException while trying to parse value as Long. {}" , String .valueOf (exception ));
717
+ }
718
+
719
+ return null ;
720
+ }
721
+
637
722
/**
638
723
* Get the String value of the specified variable in the feature.
639
724
*
@@ -828,8 +913,13 @@ Object convertStringToType(String variableValue, String type) {
828
913
try {
829
914
return Integer .parseInt (variableValue );
830
915
} catch (NumberFormatException exception ) {
831
- logger .error ("NumberFormatException while trying to parse \" " + variableValue +
832
- "\" as Integer. " + exception .toString ());
916
+ try {
917
+ return Long .parseLong (variableValue );
918
+ } catch (NumberFormatException longException ) {
919
+ logger .error ("NumberFormatException while trying to parse \" {}\" as Integer. {}" ,
920
+ variableValue ,
921
+ exception .toString ());
922
+ }
833
923
}
834
924
break ;
835
925
case FeatureVariable .JSON_TYPE :
@@ -845,11 +935,10 @@ Object convertStringToType(String variableValue, String type) {
845
935
/**
846
936
* Get the values of all variables in the feature.
847
937
*
848
- * @param featureKey The unique key of the feature.
849
- * @param userId The ID of the user.
938
+ * @param featureKey The unique key of the feature.
939
+ * @param userId The ID of the user.
850
940
* @return An OptimizelyJSON instance for all variable values.
851
941
* Null if the feature could not be found.
852
- *
853
942
*/
854
943
@ Nullable
855
944
public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
@@ -860,12 +949,11 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
860
949
/**
861
950
* Get the values of all variables in the feature.
862
951
*
863
- * @param featureKey The unique key of the feature.
864
- * @param userId The ID of the user.
865
- * @param attributes The user's attributes.
952
+ * @param featureKey The unique key of the feature.
953
+ * @param userId The ID of the user.
954
+ * @param attributes The user's attributes.
866
955
* @return An OptimizelyJSON instance for all variable values.
867
956
* Null if the feature could not be found.
868
- *
869
957
*/
870
958
@ Nullable
871
959
public OptimizelyJSON getAllFeatureVariables (@ Nonnull String featureKey ,
@@ -949,7 +1037,6 @@ public OptimizelyJSON getAllFeatureVariables(@Nonnull String featureKey,
949
1037
* @param attributes The user's attributes.
950
1038
* @return List of the feature keys that are enabled for the user if the userId is empty it will
951
1039
* return Empty List.
952
- *
953
1040
*/
954
1041
public List <String > getEnabledFeatures (@ Nonnull String userId , @ Nonnull Map <String , ?> attributes ) {
955
1042
List <String > enabledFeaturesList = new ArrayList ();
@@ -1164,10 +1251,10 @@ public OptimizelyConfig getOptimizelyConfig() {
1164
1251
1165
1252
/**
1166
1253
* Create a context of the user for which decision APIs will be called.
1167
- *
1254
+ * <p>
1168
1255
* A user context will be created successfully even when the SDK is not fully configured yet.
1169
1256
*
1170
- * @param userId The user ID to be used for bucketing.
1257
+ * @param userId The user ID to be used for bucketing.
1171
1258
* @param attributes: A map of attribute names to current user attribute values.
1172
1259
* @return An OptimizelyUserContext associated with this OptimizelyClient.
1173
1260
*/
@@ -1289,15 +1376,15 @@ private OptimizelyDecision createOptimizelyDecision(
1289
1376
}
1290
1377
1291
1378
Map <String , OptimizelyDecision > decideForKeys (@ Nonnull OptimizelyUserContext user ,
1292
- @ Nonnull List <String > keys ,
1293
- @ Nonnull List <OptimizelyDecideOption > options ) {
1379
+ @ Nonnull List <String > keys ,
1380
+ @ Nonnull List <OptimizelyDecideOption > options ) {
1294
1381
return decideForKeys (user , keys , options , false );
1295
1382
}
1296
1383
1297
1384
private Map <String , OptimizelyDecision > decideForKeys (@ Nonnull OptimizelyUserContext user ,
1298
- @ Nonnull List <String > keys ,
1299
- @ Nonnull List <OptimizelyDecideOption > options ,
1300
- boolean ignoreDefaultOptions ) {
1385
+ @ Nonnull List <String > keys ,
1386
+ @ Nonnull List <OptimizelyDecideOption > options ,
1387
+ boolean ignoreDefaultOptions ) {
1301
1388
Map <String , OptimizelyDecision > decisionMap = new HashMap <>();
1302
1389
1303
1390
ProjectConfig projectConfig = getProjectConfig ();
@@ -1308,7 +1395,7 @@ private Map<String, OptimizelyDecision> decideForKeys(@Nonnull OptimizelyUserCon
1308
1395
1309
1396
if (keys .isEmpty ()) return decisionMap ;
1310
1397
1311
- List <OptimizelyDecideOption > allOptions = ignoreDefaultOptions ? options : getAllOptions (options );
1398
+ List <OptimizelyDecideOption > allOptions = ignoreDefaultOptions ? options : getAllOptions (options );
1312
1399
1313
1400
Map <String , FeatureDecision > flagDecisions = new HashMap <>();
1314
1401
Map <String , DecisionReasons > decisionReasonsMap = new HashMap <>();
@@ -1351,7 +1438,7 @@ private Map<String, OptimizelyDecision> decideForKeys(@Nonnull OptimizelyUserCon
1351
1438
decisionReasonsMap .get (flagKey ).merge (decision .getReasons ());
1352
1439
}
1353
1440
1354
- for (String key : validKeys ) {
1441
+ for (String key : validKeys ) {
1355
1442
FeatureDecision flagDecision = flagDecisions .get (key );
1356
1443
DecisionReasons decisionReasons = decisionReasonsMap .get ((key ));
1357
1444
@@ -1484,9 +1571,9 @@ public int addLogEventNotificationHandler(NotificationHandler<LogEvent> handler)
1484
1571
/**
1485
1572
* Convenience method for adding NotificationHandlers
1486
1573
*
1487
- * @param clazz The class of NotificationHandler
1574
+ * @param clazz The class of NotificationHandler
1488
1575
* @param handler NotificationHandler handler
1489
- * @param <T> This is the type parameter
1576
+ * @param <T> This is the type parameter
1490
1577
* @return A handler Id (greater than 0 if succeeded)
1491
1578
*/
1492
1579
public <T > int addNotificationHandler (Class <T > clazz , NotificationHandler <T > handler ) {
@@ -1535,10 +1622,10 @@ public ODPManager getODPManager() {
1535
1622
/**
1536
1623
* Send an event to the ODP server.
1537
1624
*
1538
- * @param type the event type (default = "fullstack").
1539
- * @param action the event action name.
1625
+ * @param type the event type (default = "fullstack").
1626
+ * @param action the event action name.
1540
1627
* @param identifiers a dictionary for identifiers. The caller must provide at least one key-value pair unless non-empty common identifiers have been set already with {@link ODPManager.Builder#withUserCommonIdentifiers(Map) }.
1541
- * @param data a dictionary for associated data. The default event data will be added to this data before sending to the ODP server.
1628
+ * @param data a dictionary for associated data. The default event data will be added to this data before sending to the ODP server.
1542
1629
*/
1543
1630
public void sendODPEvent (@ Nullable String type , @ Nonnull String action , @ Nullable Map <String , String > identifiers , @ Nullable Map <String , Object > data ) {
1544
1631
ProjectConfig projectConfig = getProjectConfig ();
@@ -1586,7 +1673,7 @@ private void updateODPSettings() {
1586
1673
* {@link Builder#withDatafile(java.lang.String)} and
1587
1674
* {@link Builder#withEventHandler(com.optimizely.ab.event.EventHandler)}
1588
1675
* respectively.
1589
- *
1676
+ * <p>
1590
1677
* Example:
1591
1678
* <pre>
1592
1679
* Optimizely optimizely = Optimizely.builder()
@@ -1595,7 +1682,7 @@ private void updateODPSettings() {
1595
1682
* .build();
1596
1683
* </pre>
1597
1684
*
1598
- * @param datafile A datafile
1685
+ * @param datafile A datafile
1599
1686
* @param eventHandler An EventHandler
1600
1687
* @return An Optimizely builder
1601
1688
*/
@@ -1644,7 +1731,8 @@ public Builder(@Nonnull String datafile,
1644
1731
this .datafile = datafile ;
1645
1732
}
1646
1733
1647
- public Builder () { }
1734
+ public Builder () {
1735
+ }
1648
1736
1649
1737
public Builder withErrorHandler (ErrorHandler errorHandler ) {
1650
1738
this .errorHandler = errorHandler ;
@@ -1686,7 +1774,7 @@ public Builder withUserProfileService(UserProfileService userProfileService) {
1686
1774
* Override the SDK name and version (for client SDKs like android-sdk wrapping the core java-sdk) to be included in events.
1687
1775
*
1688
1776
* @param clientEngineName the client engine name ("java-sdk", "android-sdk", "flutter-sdk", etc.).
1689
- * @param clientVersion the client SDK version.
1777
+ * @param clientVersion the client SDK version.
1690
1778
* @return An Optimizely builder
1691
1779
*/
1692
1780
public Builder withClientInfo (String clientEngineName , String clientVersion ) {
0 commit comments