Skip to content

Commit e62e8ee

Browse files
committed
Merge branch 'yasir/activate-getvariation' of github.com:optimizely/optimizely-flutter-sdk into yasir/activate-getvariation
2 parents 8563b64 + a8c2766 commit e62e8ee

File tree

14 files changed

+378
-160
lines changed

14 files changed

+378
-160
lines changed

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

Lines changed: 49 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,14 @@
4949
import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption;
5050
import com.optimizely.ab.optimizelydecision.OptimizelyDecision;
5151
import com.optimizely.optimizely_flutter_sdk.helper_classes.ArgumentsParser;
52+
import com.optimizely.optimizely_flutter_sdk.helper_classes.Utils;
5253

5354
import static com.optimizely.optimizely_flutter_sdk.helper_classes.Constants.*;
5455

5556
import java.util.Collections;
5657
import java.util.LinkedHashMap;
5758
import java.util.List;
59+
import java.util.Objects;
5860
import java.util.concurrent.ArrayBlockingQueue;
5961
import java.util.concurrent.TimeUnit;
6062

@@ -63,7 +65,7 @@ public class OptimizelyFlutterClient {
6365
protected Activity activity;
6466

6567
protected static final Map<String, OptimizelyManager> optimizelyManagerTracker = new HashMap<>();
66-
protected static final Map<String, OptimizelyUserContext> userContextsTracker = new HashMap<>();
68+
protected static final Map<String, Map<String, OptimizelyUserContext>> userContextsTracker = new HashMap<>();
6769
protected static final Map<Integer, Integer> notificationIdsTracker = new HashMap<>();
6870

6971

@@ -162,18 +164,21 @@ protected void createUserContext(ArgumentsParser argumentsParser, @NonNull Resul
162164
return;
163165
}
164166
try {
165-
OptimizelyUserContext optlyUserContext = null;
166-
if (attributes != null) {
167-
optlyUserContext = optimizelyClient.createUserContext(userId, attributes);
168-
userContextsTracker.put(sdkKey, optlyUserContext);
167+
String userContextId = Utils.getRandomUUID();
168+
169+
OptimizelyUserContext optlyUserContext = optimizelyClient.createUserContext(userId, attributes);
170+
if (optlyUserContext != null) {
171+
if (userContextsTracker.containsKey(sdkKey)) {
172+
userContextsTracker.get(sdkKey).put(userContextId, optlyUserContext);
173+
} else {
174+
userContextsTracker.put(sdkKey, Collections.singletonMap(userContextId, optlyUserContext));
175+
}
176+
result.success(createResponse(true,
177+
Collections.singletonMap(RequestParameterKey.USER_CONTEXT_ID, optlyUserContext),
178+
SuccessMessage.USER_CONTEXT_CREATED));
169179
} else {
170-
optlyUserContext = optimizelyClient.createUserContext(userId);
171-
userContextsTracker.put(sdkKey, optlyUserContext);
172-
}
173-
if (optlyUserContext != null)
174-
result.success(createResponse(true, SuccessMessage.USER_CONTEXT_CREATED));
175-
else
176180
result.success(createResponse(false, "User context not created "));
181+
}
177182
} catch (Exception ex) {
178183
result.success(createResponse(false, ex.getMessage()));
179184
}
@@ -249,7 +254,7 @@ protected void decide(ArgumentsParser argumentsParser, @NonNull Result result) {
249254
return;
250255
}
251256

252-
OptimizelyUserContext userContext = getUserContext(sdkKey);
257+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
253258
if (userContext == null) {
254259
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
255260
return;
@@ -283,7 +288,7 @@ protected void setForcedDecision(ArgumentsParser argumentsParser, @NonNull Resul
283288
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
284289
return;
285290
}
286-
OptimizelyUserContext userContext = getUserContext(sdkKey);
291+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
287292
if (userContext == null) {
288293
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
289294
return;
@@ -313,7 +318,7 @@ protected void getForcedDecision(ArgumentsParser argumentsParser, @NonNull Resul
313318
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
314319
return;
315320
}
316-
OptimizelyUserContext userContext = getUserContext(sdkKey);
321+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
317322
if (userContext == null) {
318323
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
319324
return;
@@ -340,7 +345,7 @@ protected void removeForcedDecision(ArgumentsParser argumentsParser, @NonNull Re
340345
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
341346
return;
342347
}
343-
OptimizelyUserContext userContext = getUserContext(sdkKey);
348+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
344349
if (userContext == null) {
345350
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
346351
return;
@@ -368,7 +373,7 @@ protected void removeAllForcedDecisions(ArgumentsParser argumentsParser, @NonNul
368373
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
369374
return;
370375
}
371-
OptimizelyUserContext userContext = getUserContext(sdkKey);
376+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
372377
if (userContext == null) {
373378
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
374379
return;
@@ -406,7 +411,7 @@ protected void trackEvent(ArgumentsParser argumentsParser, @NonNull Result resul
406411
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
407412
return;
408413
}
409-
OptimizelyUserContext userContext = getUserContext(sdkKey);
414+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
410415

411416
String eventKey = argumentsParser.getEventKey();
412417
Map<String, Object> eventTags = argumentsParser.getEventTags();
@@ -430,13 +435,31 @@ protected void trackEvent(ArgumentsParser argumentsParser, @NonNull Result resul
430435
}
431436
}
432437

438+
protected void getUserId(ArgumentsParser argumentsParser, @NonNull Result result) {
439+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
440+
if (userContext == null) {
441+
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
442+
return;
443+
}
444+
result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.USER_ID, userContext.getUserId()), ""));
445+
}
446+
447+
protected void getAttributes(ArgumentsParser argumentsParser, @NonNull Result result) {
448+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
449+
if (userContext == null) {
450+
result.success(createResponse(false, ErrorMessage.USER_CONTEXT_NOT_FOUND));
451+
return;
452+
}
453+
result.success(createResponse(true, Collections.singletonMap(RequestParameterKey.ATTRIBUTES, userContext.getAttributes()), ""));
454+
}
455+
433456
protected void setAttribute(ArgumentsParser argumentsParser, @NonNull Result result) {
434457
String sdkKey = argumentsParser.getSdkKey();
435458
if (sdkKey == null) {
436459
result.success(createResponse(false, ErrorMessage.INVALID_PARAMS));
437460
return;
438461
}
439-
OptimizelyUserContext userContext = getUserContext(sdkKey);
462+
OptimizelyUserContext userContext = getUserContext(argumentsParser);
440463

441464
Map<String, Object> attributes = argumentsParser.getAttributes();
442465
if (userContext == null) {
@@ -450,7 +473,7 @@ protected void setAttribute(ArgumentsParser argumentsParser, @NonNull Result res
450473
for (String attributeKey : attributes.keySet()) {
451474
userContext.setAttribute(attributeKey, attributes.get(attributeKey));
452475
}
453-
userContextsTracker.put(sdkKey, userContext);
476+
userContextsTracker.get(sdkKey).put(argumentsParser.getUserContextId(), userContext);
454477
result.success(createResponse(true, userContext.getAttributes(), SuccessMessage.ATTRIBUTES_ADDED));
455478
}
456479

@@ -519,8 +542,13 @@ public OptimizelyClient getOptimizelyClient(String SDKKey) {
519542
return optimizelyManagerTracker.get(SDKKey) == null? null : optimizelyManagerTracker.get(SDKKey).getOptimizely();
520543
}
521544

522-
public OptimizelyUserContext getUserContext(String SDKKey) {
523-
return userContextsTracker.get(SDKKey);
545+
public OptimizelyUserContext getUserContext(ArgumentsParser argumentsParser) {
546+
String SDKKey = argumentsParser.getSdkKey();
547+
String userContextId = argumentsParser.getUserContextId();
548+
if (userContextId == null || !userContextsTracker.get(SDKKey).containsKey(userContextId)) {
549+
return null;
550+
}
551+
return userContextsTracker.get(SDKKey).get(userContextId);
524552
}
525553

526554
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
@@ -70,6 +70,14 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
7070
createUserContext(argumentsParser, result);
7171
break;
7272
}
73+
case APIs.GET_USER_ID: {
74+
getUserId(argumentsParser, result);
75+
break;
76+
}
77+
case APIs.GET_ATTRIBUTES: {
78+
getAttributes(argumentsParser, result);
79+
break;
80+
}
7381
case APIs.SET_ATTRIBUTES: {
7482
setAttribute(argumentsParser, result);
7583
break;

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

Lines changed: 4 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
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ public static class APIs {
2323
public static final String INITIALIZE = "initialize";
2424
public static final String GET_OPTIMIZELY_CONFIG = "getOptimizelyConfig";
2525
public static final String CREATE_USER_CONTEXT = "createUserContext";
26+
public static final String GET_USER_ID = "getUserId";
27+
public static final String GET_ATTRIBUTES = "getAttributes";
2628
public static final String SET_ATTRIBUTES="setAttributes";
2729
public static final String GET_FORCED_DECISION = "getForcedDecision";
2830
public static final String REMOVE_FORCED_DECISION = "removeForcedDecision";
@@ -44,6 +46,7 @@ public static class NotificationType {
4446
public static class RequestParameterKey {
4547
public static final String SDK_KEY = "sdkKey";
4648
public static final String USER_ID = "userID";
49+
public static final String USER_CONTEXT_ID = "userContextId";
4750
public static final String NOTIFICATION_ID = "id";
4851
public static final String NOTIFICATION_TYPE = "type";
4952
public static final String NOTIFICATION_PAYLOAD = "payload";

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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@ struct API {
2121
static let getOptimizelyConfig = "getOptimizelyConfig"
2222
static let activate = "activate"
2323
static let getVariation = "getVariation"
24-
static let setForcedVariation = "setForcedVariation"
25-
static let getForcedVariation = "getForcedVariation"
2624
static let createUserContext = "createUserContext"
25+
static let getUserId = "getUserId"
26+
static let getAttributes = "getAttributes"
2727
static let setAttributes = "setAttributes"
2828
static let trackEvent = "trackEvent"
2929
static let decide = "decide"

ios/Classes/SwiftOptimizelyFlutterSdkPlugin.swift

Lines changed: 21 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,9 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
5353
case API.getOptimizelyConfig: getOptimizelyConfig(call, result: result)
5454
case API.activate: activate(call, result: result)
5555
case API.getVariation: getVariation(call, result: result)
56-
case API.setForcedVariation: setForcedVariation(call, result: result)
57-
case API.getForcedVariation: getForcedVariation(call, result: result)
5856
case API.createUserContext: createUserContext(call, result: result)
57+
case API.getUserId: getUserId(call, result: result)
58+
case API.getAttributes: getAttributes(call, result: result)
5959
case API.setAttributes: setAttributes(call, result: result)
6060
case API.trackEvent: trackEvent(call, result: result)
6161
case API.decide: decide(call, result: result)
@@ -239,44 +239,6 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
239239
}
240240
}
241241

242-
/// Set forced variation for experiment and user ID to variationKey.
243-
///
244-
func setForcedVariation(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
245-
guard let optimizelyClient = getOptimizelyClient(arguments: call.arguments) else {
246-
result(self.createResponse(success: false, reason: ErrorMessage.optlyClientNotFound))
247-
return
248-
}
249-
250-
guard let parameters = call.arguments as? Dictionary<String, Any?>, let experimentKey = parameters[RequestParameterKey.experimentKey] as? String, let userId = parameters[RequestParameterKey.userId] as? String else {
251-
result(createResponse(success: false, reason: ErrorMessage.invalidParameters))
252-
return
253-
}
254-
let variationKey = parameters[RequestParameterKey.variationKey] as? String
255-
let success = optimizelyClient.setForcedVariation(experimentKey: experimentKey, userId: userId, variationKey: variationKey)
256-
result(self.createResponse(success: success))
257-
}
258-
259-
/// Get forced variation for experiment and user ID.
260-
///
261-
func getForcedVariation(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
262-
guard let optimizelyClient = getOptimizelyClient(arguments: call.arguments) else {
263-
result(self.createResponse(success: false, reason: ErrorMessage.optlyClientNotFound))
264-
return
265-
}
266-
267-
guard let parameters = call.arguments as? Dictionary<String, Any?>, let experimentKey = parameters[RequestParameterKey.experimentKey] as? String, let userId = parameters[RequestParameterKey.userId] as? String else {
268-
result(createResponse(success: false, reason: ErrorMessage.invalidParameters))
269-
return
270-
}
271-
if let variationKey = optimizelyClient.getForcedVariation(experimentKey: experimentKey, userId: userId) {
272-
result(self.createResponse(success: true, result: [RequestParameterKey.variationKey: variationKey]))
273-
return
274-
}
275-
result(self.createResponse(success: false))
276-
}
277-
278-
279-
280242
/// Creates a context of the user for which decision APIs will be called.
281243
/// A user context will only be created successfully when the SDK is fully configured using initializeClient.
282244
func createUserContext(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
@@ -296,7 +258,25 @@ public class SwiftOptimizelyFlutterSdkPlugin: NSObject, FlutterPlugin {
296258
} else {
297259
userContextsTracker[sdkKey] = [userContextId: userContext]
298260
}
299-
result(self.createResponse(success: true,result: [RequestParameterKey.userContextId: userContextId], reason: SuccessMessage.userContextCreated))
261+
result(self.createResponse(success: true, result: [RequestParameterKey.userContextId: userContextId], reason: SuccessMessage.userContextCreated))
262+
}
263+
264+
/// Returns userId for the user context.
265+
func getUserId(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
266+
guard let usrContext = getUserContext(arguments: call.arguments) else {
267+
result(self.createResponse(success: false, reason: ErrorMessage.userContextNotFound))
268+
return
269+
}
270+
result(createResponse(success: true, result: [RequestParameterKey.userId: usrContext.userId]))
271+
}
272+
273+
/// Returns attributes for the user context.
274+
func getAttributes(_ call: FlutterMethodCall, result: @escaping FlutterResult) {
275+
guard let usrContext = getUserContext(arguments: call.arguments) else {
276+
result(self.createResponse(success: false, reason: ErrorMessage.userContextNotFound))
277+
return
278+
}
279+
result(createResponse(success: true, result: [RequestParameterKey.attributes: usrContext.attributes]))
300280
}
301281

302282
/// Sets attributes for the user context.

lib/optimizely_flutter_sdk.dart

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -93,20 +93,6 @@ class OptimizelyFlutterSdk {
9393
_sdkKey, experimentKey, userId, attributes);
9494
}
9595

96-
/// Get forced variation for experiment and user ID.
97-
Future<GetForcedDecisionResponse> getForcedVariation(
98-
String experimentKey, String userId) async {
99-
return await OptimizelyClientWrapper.getForcedVariation(
100-
_sdkKey, experimentKey, userId);
101-
}
102-
103-
/// Set forced variation for experiment and user ID to variationKey.
104-
Future<BaseResponse> setForcedVariation(String experimentKey, String userId,
105-
[String variationKey = ""]) async {
106-
return await OptimizelyClientWrapper.setForcedVariation(
107-
_sdkKey, experimentKey, userId, variationKey);
108-
}
109-
11096
/// Returns a snapshot of the current project configuration.
11197
Future<OptimizelyConfigResponse> getOptimizelyConfig() async {
11298
return await OptimizelyClientWrapper.getOptimizelyConfig(_sdkKey);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
/// **************************************************************************
2+
/// Copyright 2022, Optimizely, Inc. and contributors *
3+
/// *
4+
/// Licensed under the Apache License, Version 2.0 (the "License"); *
5+
/// you may not use this file except in compliance with the License. *
6+
/// You may obtain a copy of the License at *
7+
/// *
8+
/// http://www.apache.org/licenses/LICENSE-2.0 *
9+
/// *
10+
/// Unless required by applicable law or agreed to in writing, software *
11+
/// distributed under the License is distributed on an "AS IS" BASIS, *
12+
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13+
/// See the License for the specific language governing permissions and *
14+
/// limitations under the License. *
15+
///**************************************************************************/
16+
17+
import 'package:optimizely_flutter_sdk/src/data_objects/base_response.dart';
18+
import 'package:optimizely_flutter_sdk/src/utils/constants.dart';
19+
20+
class GetAttributesResponse extends BaseResponse {
21+
Map<String, dynamic> attributes = {};
22+
23+
GetAttributesResponse(Map<String, dynamic> json) : super(json) {
24+
if (json[Constants.responseResult] is Map<dynamic, dynamic>) {
25+
var response = Map<String, dynamic>.from(json[Constants.responseResult]);
26+
if (response[Constants.attributes] is Map<dynamic, dynamic>) {
27+
attributes = Map<String, dynamic>.from(response[Constants.attributes]);
28+
}
29+
}
30+
}
31+
}

0 commit comments

Comments
 (0)