Skip to content

Commit 020cbbb

Browse files
Merge pull request #21 from optimizely/yasir/datafile-host
feat(datafile-host-options): Adds support for datafile host options.
2 parents 0a589b0 + 4a673bf commit 020cbbb

File tree

15 files changed

+399
-53
lines changed

15 files changed

+399
-53
lines changed

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterClient.java

Lines changed: 58 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535

3636
import com.fasterxml.jackson.databind.ObjectMapper;
3737
import com.optimizely.ab.android.sdk.OptimizelyManager;
38+
import com.optimizely.ab.android.shared.DatafileConfig;
3839
import com.optimizely.ab.error.RaiseExceptionErrorHandler;
3940
import com.optimizely.ab.event.BatchEventProcessor;
4041
import com.optimizely.ab.event.EventProcessor;
@@ -47,12 +48,14 @@
4748
import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption;
4849
import com.optimizely.ab.optimizelydecision.OptimizelyDecision;
4950
import com.optimizely.optimizely_flutter_sdk.helper_classes.ArgumentsParser;
51+
import com.optimizely.optimizely_flutter_sdk.helper_classes.Utils;
5052

5153
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*;
5254

5355
import java.util.Collections;
5456
import java.util.LinkedHashMap;
5557
import java.util.List;
58+
import java.util.Objects;
5659
import java.util.concurrent.ArrayBlockingQueue;
5760
import java.util.concurrent.TimeUnit;
5861

@@ -61,7 +64,7 @@ public class OptimizelyFlutterClient {
6164
protected Activity activity;
6265

6366
protected static final Map<String, OptimizelyManager> optimizelyManagerTracker = new HashMap<>();
64-
protected static final Map<String, OptimizelyUserContext> userContextsTracker = new HashMap<>();
67+
protected static final Map<String, Map<String, OptimizelyUserContext>> userContextsTracker = new HashMap<>();
6568
protected static final Map<Integer, Integer> notificationIdsTracker = new HashMap<>();
6669

6770

@@ -105,6 +108,14 @@ protected void initializeOptimizely(@NonNull ArgumentsParser argumentsParser, @N
105108
if (argumentsParser.getDatafilePeriodicDownloadInterval() != null) {
106109
datafilePeriodicDownloadInterval = argumentsParser.getDatafilePeriodicDownloadInterval();
107110
}
111+
112+
// String default datafile host
113+
String defaultDatafileHost = "https://cdn.optimizely.com";
114+
String environmentUrlSuffix = "/datafiles/%s.json";
115+
116+
DatafileConfig.defaultHost = argumentsParser.getDatafileHostPrefix() != null ? argumentsParser.getDatafileHostPrefix() : defaultDatafileHost;
117+
DatafileConfig.environmentUrlSuffix = argumentsParser.getDatafileHostSuffix() != null ? argumentsParser.getDatafileHostSuffix() : environmentUrlSuffix;
118+
108119
// Delete old user context
109120
userContextsTracker.remove(sdkKey);
110121
if (getOptimizelyClient(sdkKey) != null) {
@@ -152,18 +163,21 @@ protected void createUserContext(ArgumentsParser argumentsParser, @NonNull Resul
152163
return;
153164
}
154165
try {
155-
OptimizelyUserContext optlyUserContext = null;
156-
if (attributes != null) {
157-
optlyUserContext = optimizelyClient.createUserContext(userId, attributes);
158-
userContextsTracker.put(sdkKey, optlyUserContext);
166+
String userContextId = Utils.getRandomUUID();
167+
168+
OptimizelyUserContext optlyUserContext = optimizelyClient.createUserContext(userId, attributes);
169+
if (optlyUserContext != null) {
170+
if (userContextsTracker.containsKey(sdkKey)) {
171+
userContextsTracker.get(sdkKey).put(userContextId, optlyUserContext);
172+
} else {
173+
userContextsTracker.put(sdkKey, Collections.singletonMap(userContextId, optlyUserContext));
174+
}
175+
result.success(createResponse(true,
176+
Collections.singletonMap(RequestParameterKey.USER_CONTEXT_ID, optlyUserContext),
177+
SuccessMessage.USER_CONTEXT_CREATED));
159178
} else {
160-
optlyUserContext = optimizelyClient.createUserContext(userId);
161-
userContextsTracker.put(sdkKey, optlyUserContext);
162-
}
163-
if (optlyUserContext != null)
164-
result.success(createResponse(true, SuccessMessage.USER_CONTEXT_CREATED));
165-
else
166179
result.success(createResponse(false, "User context not created "));
180+
}
167181
} catch (Exception ex) {
168182
result.success(createResponse(false, ex.getMessage()));
169183
}
@@ -176,7 +190,7 @@ protected void decide(ArgumentsParser argumentsParser, @NonNull Result result) {
176190
return;
177191
}
178192

179-
OptimizelyUserContext userContext = getUserContext(sdkKey);
193+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
180194
if (userContext == null) {
181195
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
182196
return;
@@ -210,7 +224,7 @@ protected void setForcedDecision(ArgumentsParser argumentsParser, @NonNull Resul
210224
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
211225
return;
212226
}
213-
OptimizelyUserContext userContext = getUserContext(sdkKey);
227+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
214228
if (userContext == null) {
215229
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
216230
return;
@@ -240,7 +254,7 @@ protected void getForcedDecision(ArgumentsParser argumentsParser, @NonNull Resul
240254
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
241255
return;
242256
}
243-
OptimizelyUserContext userContext = getUserContext(sdkKey);
257+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
244258
if (userContext == null) {
245259
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
246260
return;
@@ -267,7 +281,7 @@ protected void removeForcedDecision(ArgumentsParser argumentsParser, @NonNull Re
267281
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
268282
return;
269283
}
270-
OptimizelyUserContext userContext = getUserContext(sdkKey);
284+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
271285
if (userContext == null) {
272286
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
273287
return;
@@ -295,7 +309,7 @@ protected void removeAllForcedDecisions(ArgumentsParser argumentsParser, @NonNul
295309
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
296310
return;
297311
}
298-
OptimizelyUserContext userContext = getUserContext(sdkKey);
312+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
299313
if (userContext == null) {
300314
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
301315
return;
@@ -333,7 +347,7 @@ protected void trackEvent(ArgumentsParser argumentsParser, @NonNull Result resul
333347
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
334348
return;
335349
}
336-
OptimizelyUserContext userContext = getUserContext(sdkKey);
350+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
337351

338352
String eventKey = argumentsParser.getEventKey();
339353
Map<String, Object> eventTags = argumentsParser.getEventTags();
@@ -357,13 +371,31 @@ protected void trackEvent(ArgumentsParser argumentsParser, @NonNull Result resul
357371
}
358372
}
359373

374+
protected void getUserId(ArgumentsParser argumentsParser, @NonNull Result result) {
375+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
376+
if (userContext == null) {
377+
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
378+
return;
379+
}
380+
result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.USER_ID, userContext.getUserId()), ""));
381+
}
382+
383+
protected void getAttributes(ArgumentsParser argumentsParser, @NonNull Result result) {
384+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
385+
if (userContext == null) {
386+
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
387+
return;
388+
}
389+
result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.ATTRIBUTES, userContext.getAttributes()), ""));
390+
}
391+
360392
protected void setAttribute(ArgumentsParser argumentsParser, @NonNull Result result) {
361393
String sdkKey = argumentsParser.getSdkKey();
362394
if (sdkKey == null) {
363395
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
364396
return;
365397
}
366-
OptimizelyUserContext userContext = getUserContext(sdkKey);
398+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
367399

368400
Map<String, Object> attributes = argumentsParser.getAttributes();
369401
if (userContext == null) {
@@ -377,7 +409,7 @@ protected void setAttribute(ArgumentsParser argumentsParser, @NonNull Result res
377409
for (String attributeKey : attributes.keySet()) {
378410
userContext.setAttribute(attributeKey, attributes.get(attributeKey));
379411
}
380-
userContextsTracker.put(sdkKey, userContext);
412+
userContextsTracker.get(sdkKey).put(argumentsParser.getUserContextId(), userContext);
381413
result.success(createResponse(true, userContext.getAttributes(), SuccessMessage.ATTRIBUTES_ADDED));
382414
}
383415

@@ -446,8 +478,13 @@ public OptimizelyClient getOptimizelyClient(String SDKKey) {
446478
return optimizelyManagerTracker.get(SDKKey) == null? null : optimizelyManagerTracker.get(SDKKey).getOptimizely();
447479
}
448480

449-
public OptimizelyUserContext getUserContext(String SDKKey) {
450-
return userContextsTracker.get(SDKKey);
481+
public OptimizelyUserContext getUserContext(ArgumentsParser argumentsParser) {
482+
String SDKKey = argumentsParser.getSdkKey();
483+
String userContextId = argumentsParser.getUserContextId();
484+
if (userContextId == null || !userContextsTracker.get(SDKKey).containsKey(userContextId)) {
485+
return null;
486+
}
487+
return userContextsTracker.get(SDKKey).get(userContextId);
451488
}
452489

453490
protected void addNotificationListener(ArgumentsParser argumentsParser, @NonNull Result result) {

android/src/main/java/com/optimizely/optimizely_flutter_sdk/OptimizelyFlutterSdkPlugin.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
6262
createUserContext(argumentsParser, result);
6363
break;
6464
}
65+
case APIs.GET_USER_ID: {
66+
getUserId(argumentsParser, result);
67+
break;
68+
}
69+
case APIs.GET_ATTRIBUTES: {
70+
getAttributes(argumentsParser, result);
71+
break;
72+
}
6573
case APIs.SET_ATTRIBUTES: {
6674
setAttribute(argumentsParser, result);
6775
break;

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/ArgumentsParser.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ public String getUserID() {
4343
return (String) arguments.get(Constants.RequestParameterKey.USER_ID);
4444
}
4545

46+
public String getUserContextId() {
47+
return (String) arguments.get(Constants.RequestParameterKey.USER_CONTEXT_ID);
48+
}
49+
4650
public Map<String, Object> getAttributes() {
4751
return (Map<String, Object>) arguments.get(Constants.RequestParameterKey.ATTRIBUTES);
4852
}
@@ -90,4 +94,12 @@ public Integer getEventMaxQueueSize() {
9094
public Integer getDatafilePeriodicDownloadInterval() {
9195
return (Integer) arguments.get(Constants.RequestParameterKey.DATAFILE_PERIODIC_DOWNLOAD_INTERVAL);
9296
}
97+
98+
public String getDatafileHostSuffix() {
99+
return (String) arguments.get(Constants.RequestParameterKey.DATAFILE_HOST_SUFFIX);
100+
}
101+
102+
public String getDatafileHostPrefix() {
103+
return (String) arguments.get(Constants.RequestParameterKey.DATAFILE_HOST_PREFIX);
104+
}
93105
}

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Constants.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public static class APIs {
2121
public static final String INITIALIZE = "initialize";
2222
public static final String GET_OPTIMIZELY_CONFIG = "getOptimizelyConfig";
2323
public static final String CREATE_USER_CONTEXT = "createUserContext";
24+
public static final String GET_USER_ID = "getUserId";
25+
public static final String GET_ATTRIBUTES = "getAttributes";
2426
public static final String SET_ATTRIBUTES="setAttributes";
2527
public static final String GET_FORCED_DECISION = "getForcedDecision";
2628
public static final String REMOVE_FORCED_DECISION = "removeForcedDecision";
@@ -42,6 +44,7 @@ public static class NotificationType {
4244
public static class RequestParameterKey {
4345
public static final String SDK_KEY = "sdkKey";
4446
public static final String USER_ID = "userID";
47+
public static final String USER_CONTEXT_ID = "userContextId";
4548
public static final String NOTIFICATION_ID = "id";
4649
public static final String NOTIFICATION_TYPE = "type";
4750
public static final String NOTIFICATION_PAYLOAD = "payload";
@@ -57,6 +60,8 @@ public static class RequestParameterKey {
5760
public static final String FLAG_KEY = "flagKey";
5861
public static final String RULE_KEY = "ruleKey";
5962
public static final String VARIATION_KEY = "variationKey";
63+
public static final String DATAFILE_HOST_PREFIX = "datafileHostPrefix";
64+
public static final String DATAFILE_HOST_SUFFIX = "datafileHostSuffix";
6065
}
6166

6267
public static class ErrorMessage {

android/src/main/java/com/optimizely/optimizely_flutter_sdk/helper_classes/Utils.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,19 @@
1919
import java.util.HashMap;
2020
import java.util.List;
2121
import java.util.Map;
22+
import java.util.UUID;
23+
2224
import static com.optimizely.ab.notification.DecisionNotification.FeatureVariableDecisionNotificationBuilder.SOURCE_INFO;
2325

2426
import com.google.common.base.CaseFormat;
2527
import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption;
2628

2729
public class Utils {
2830

31+
public static String getRandomUUID() {
32+
return UUID.randomUUID().toString();
33+
}
34+
2935
public static List<OptimizelyDecideOption> getDecideOptions(List<String> options) {
3036
if(options == null || options.isEmpty()) {
3137
return null;

ios/Classes/HelperClasses/Constants.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ struct API {
2020
static let initialize = "initialize"
2121
static let getOptimizelyConfig = "getOptimizelyConfig"
2222
static let createUserContext = "createUserContext"
23+
static let getUserId = "getUserId"
24+
static let getAttributes = "getAttributes"
2325
static let setAttributes = "setAttributes"
2426
static let trackEvent = "trackEvent"
2527
static let decide = "decide"
@@ -50,6 +52,7 @@ struct DecideOption {
5052
struct RequestParameterKey {
5153
static let sdkKey = "sdkKey"
5254
static let userId = "userID"
55+
static let userContextId = "userContextId"
5356
static let notificationId = "id"
5457
static let notificationType = "type"
5558
static let notificationPayload = "payload"
@@ -69,6 +72,8 @@ struct RequestParameterKey {
6972
static let eventTimeInterval = "eventTimeInterval"
7073
static let eventMaxQueueSize = "eventMaxQueueSize"
7174
static let datafilePeriodicDownloadInterval = "datafilePeriodicDownloadInterval"
75+
static let datafileHostPrefix = "datafileHostPrefix"
76+
static let datafileHostSuffix = "datafileHostSuffix"
7277
}
7378

7479
struct ResponseKey {

0 commit comments

Comments
 (0)