20
20
import io .flutter .plugin .common .MethodChannel .Result ;
21
21
22
22
import com .optimizely .ab .OptimizelyUserContext ;
23
+ import com .optimizely .ab .OptimizelyDecisionContext ;
24
+ import com .optimizely .ab .OptimizelyForcedDecision ;
23
25
import com .optimizely .ab .android .sdk .OptimizelyClient ;
24
26
25
27
import java .util .HashMap ;
30
32
31
33
import com .fasterxml .jackson .databind .ObjectMapper ;
32
34
import com .optimizely .ab .android .sdk .OptimizelyManager ;
35
+ import com .optimizely .ab .event .LogEvent ;
36
+ import com .optimizely .ab .notification .DecisionNotification ;
37
+ import com .optimizely .ab .notification .TrackNotification ;
38
+ import com .optimizely .ab .notification .UpdateConfigNotification ;
33
39
import com .optimizely .ab .optimizelyconfig .OptimizelyConfig ;
34
40
import com .optimizely .ab .optimizelydecision .OptimizelyDecideOption ;
35
41
import com .optimizely .ab .optimizelydecision .OptimizelyDecision ;
42
+ import com .optimizely .optimizely_flutter_sdk .helper_classes .ArgumentsParser ;
43
+
36
44
import static com .optimizely .optimizely_flutter_sdk .helper_classes .Constants .*;
45
+ import static com .optimizely .optimizely_flutter_sdk .helper_classes .Utils .convertKeysCamelCaseToSnakeCase ;
37
46
38
47
import java .util .Collections ;
39
48
import java .util .LinkedHashMap ;
@@ -49,7 +58,12 @@ public class OptimizelyFlutterClient {
49
58
protected static final Map <Integer , Integer > notificationIdsTracker = new HashMap <>();
50
59
51
60
52
- protected void initializeOptimizely (@ NonNull String sdkKey , @ NonNull Result result ) {
61
+ protected void initializeOptimizely (@ NonNull ArgumentsParser argumentsParser , @ NonNull Result result ) {
62
+ String sdkKey = argumentsParser .getSdkKey ();
63
+ if (sdkKey == null ) {
64
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
65
+ return ;
66
+ }
53
67
// Delete old user context
54
68
userContextsTracker .remove (sdkKey );
55
69
// Creating new instance
@@ -68,12 +82,21 @@ protected void initializeOptimizely(@NonNull String sdkKey, @NonNull Result resu
68
82
});
69
83
}
70
84
71
- protected void createUserContext (String sdkKey , String userId , Map <String , Object > attributes , @ NonNull Result result ) {
85
+ protected void createUserContext (ArgumentsParser argumentsParser , @ NonNull Result result ) {
86
+ String sdkKey = argumentsParser .getSdkKey ();
87
+ if (sdkKey == null ) {
88
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
89
+ return ;
90
+ }
91
+
72
92
OptimizelyClient optimizelyClient = getOptimizelyClient (sdkKey );
73
- if (optimizelyClient == null ) {
93
+ if (optimizelyClient == null ) {
74
94
result .success (createResponse (false , ErrorMessage .OPTIMIZELY_CLIENT_NOT_FOUND ));
75
95
return ;
76
96
}
97
+
98
+ String userId = argumentsParser .getUserID ();
99
+ Map <String , Object > attributes = argumentsParser .getAttributes ();
77
100
if (userId == null ) {
78
101
result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
79
102
return ;
@@ -96,12 +119,20 @@ protected void createUserContext(String sdkKey, String userId, Map<String, Objec
96
119
}
97
120
}
98
121
99
- protected void decide (String sdkKey , List <String > decideKeys , List <OptimizelyDecideOption > decideOptions , @ NonNull Result result ) {
122
+ protected void decide (ArgumentsParser argumentsParser , @ NonNull Result result ) {
123
+ String sdkKey = argumentsParser .getSdkKey ();
124
+ if (sdkKey == null ) {
125
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
126
+ return ;
127
+ }
128
+
100
129
OptimizelyUserContext userContext = getUserContext (sdkKey );
101
130
if (userContext == null ) {
102
131
result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
103
132
return ;
104
133
}
134
+ List <String > decideKeys = argumentsParser .getDecideKeys ();
135
+ List <OptimizelyDecideOption > decideOptions = argumentsParser .getDecideOptions ();
105
136
106
137
Map <String , OptimizelyDecision > optimizelyDecisionsMap ;
107
138
@@ -123,8 +154,119 @@ protected void decide(String sdkKey, List<String> decideKeys, List<OptimizelyDec
123
154
result .success (createResponse (true , s , "" ));
124
155
}
125
156
126
- protected void trackEvent (String sdkKey , String eventKey , Map <String , Object > eventTags , @ NonNull Result result ) {
157
+ protected void setForcedDecision (ArgumentsParser argumentsParser , @ NonNull Result result ) {
158
+ String sdkKey = argumentsParser .getSdkKey ();
159
+ if (sdkKey == null ) {
160
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
161
+ return ;
162
+ }
163
+ OptimizelyUserContext userContext = getUserContext (sdkKey );
164
+ if (userContext == null ) {
165
+ result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
166
+ return ;
167
+ }
168
+ String flagKey = argumentsParser .getFlagKey ();
169
+ String ruleKey = argumentsParser .getRuleKey ();
170
+ String variationKey = argumentsParser .getVariationKey ();
171
+
172
+ if (flagKey == null || variationKey == null ) {
173
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
174
+ return ;
175
+ }
176
+
177
+ OptimizelyDecisionContext optimizelyDecisionContext = new OptimizelyDecisionContext (flagKey , ruleKey );
178
+ OptimizelyForcedDecision optimizelyForcedDecision = new OptimizelyForcedDecision (variationKey );
179
+ if (userContext .setForcedDecision (optimizelyDecisionContext , optimizelyForcedDecision )) {
180
+ result .success (createResponse (true , SuccessMessage .FORCED_DECISION_SET ));
181
+ }
182
+
183
+ result .success (createResponse (false , "" ));
184
+ }
185
+
186
+ protected void getForcedDecision (ArgumentsParser argumentsParser , @ NonNull Result result ) {
187
+ String sdkKey = argumentsParser .getSdkKey ();
188
+ if (sdkKey == null ) {
189
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
190
+ return ;
191
+ }
127
192
OptimizelyUserContext userContext = getUserContext (sdkKey );
193
+ if (userContext == null ) {
194
+ result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
195
+ return ;
196
+ }
197
+ String flagKey = argumentsParser .getFlagKey ();
198
+ String ruleKey = argumentsParser .getRuleKey ();
199
+ if (flagKey == null ) {
200
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
201
+ return ;
202
+ }
203
+
204
+ OptimizelyDecisionContext optimizelyDecisionContext = new OptimizelyDecisionContext (flagKey , ruleKey );
205
+ OptimizelyForcedDecision forcedDecision = userContext .getForcedDecision (optimizelyDecisionContext );
206
+ if (forcedDecision != null ) {
207
+ result .success (createResponse (true , forcedDecision .getVariationKey (), "" ));
208
+ }
209
+
210
+ result .success (createResponse (false , "" ));
211
+ }
212
+
213
+ protected void removeForcedDecision (ArgumentsParser argumentsParser , @ NonNull Result result ) {
214
+ String sdkKey = argumentsParser .getSdkKey ();
215
+ if (sdkKey == null ) {
216
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
217
+ return ;
218
+ }
219
+ OptimizelyUserContext userContext = getUserContext (sdkKey );
220
+ if (userContext == null ) {
221
+ result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
222
+ return ;
223
+ }
224
+
225
+ String flagKey = argumentsParser .getFlagKey ();
226
+ String ruleKey = argumentsParser .getRuleKey ();
227
+ if (flagKey == null ) {
228
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
229
+ return ;
230
+ }
231
+
232
+ OptimizelyDecisionContext optimizelyDecisionContext = new OptimizelyDecisionContext (flagKey , ruleKey );
233
+ if (userContext .removeForcedDecision (optimizelyDecisionContext )) {
234
+ result .success (createResponse (true , SuccessMessage .REMOVED_FORCED_DECISION ));
235
+ }
236
+
237
+ result .success (createResponse (false , "" ));
238
+ }
239
+
240
+ protected void removeAllForcedDecisions (ArgumentsParser argumentsParser , @ NonNull Result result ) {
241
+ String sdkKey = argumentsParser .getSdkKey ();
242
+ if (sdkKey == null ) {
243
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
244
+ return ;
245
+ }
246
+ OptimizelyUserContext userContext = getUserContext (sdkKey );
247
+ if (userContext == null ) {
248
+ result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
249
+ return ;
250
+ }
251
+
252
+ if (userContext .removeAllForcedDecisions ()) {
253
+ result .success (createResponse (true , SuccessMessage .REMOVED_ALL_FORCED_DECISION ));
254
+ }
255
+
256
+ result .success (createResponse (false , "" ));
257
+ }
258
+
259
+ protected void trackEvent (ArgumentsParser argumentsParser , @ NonNull Result result ) {
260
+ String sdkKey = argumentsParser .getSdkKey ();
261
+ if (sdkKey == null ) {
262
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
263
+ return ;
264
+ }
265
+ OptimizelyUserContext userContext = getUserContext (sdkKey );
266
+
267
+ String eventKey = argumentsParser .getEventKey ();
268
+ Map <String , Object > eventTags = argumentsParser .getEventTags ();
269
+
128
270
if (userContext == null ) {
129
271
result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
130
272
return ;
@@ -144,8 +286,15 @@ protected void trackEvent(String sdkKey, String eventKey, Map<String, Object> ev
144
286
}
145
287
}
146
288
147
- protected void setAttribute (String sdkKey , Map <String , Object > attributes , @ NonNull Result result ) {
289
+ protected void setAttribute (ArgumentsParser argumentsParser , @ NonNull Result result ) {
290
+ String sdkKey = argumentsParser .getSdkKey ();
291
+ if (sdkKey == null ) {
292
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
293
+ return ;
294
+ }
148
295
OptimizelyUserContext userContext = getUserContext (sdkKey );
296
+
297
+ Map <String , Object > attributes = argumentsParser .getAttributes ();
149
298
if (userContext == null ) {
150
299
result .success (createResponse (false , ErrorMessage .USER_CONTEXT_NOT_FOUND ));
151
300
return ;
@@ -161,8 +310,18 @@ protected void setAttribute(String sdkKey, Map<String, Object> attributes, @NonN
161
310
result .success (createResponse (true , userContext .getAttributes (), SuccessMessage .ATTRIBUTES_ADDED ));
162
311
}
163
312
164
- protected void removeNotificationListener (String sdkKey , Integer id , String type , @ NonNull Result result ) {
313
+ protected void removeNotificationListener (ArgumentsParser argumentsParser , @ NonNull Result result ) {
314
+ String sdkKey = argumentsParser .getSdkKey ();
315
+ if (sdkKey == null ) {
316
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
317
+ return ;
318
+ }
319
+
165
320
OptimizelyClient optimizelyClient = getOptimizelyClient (sdkKey );
321
+
322
+ Integer id = argumentsParser .getNotificaitonID ();
323
+ String type = argumentsParser .getNotificationType ();
324
+
166
325
if (optimizelyClient == null ) {
167
326
result .success (createResponse (false , ErrorMessage .OPTIMIZELY_CLIENT_NOT_FOUND ));
168
327
return ;
@@ -176,7 +335,12 @@ protected void removeNotificationListener(String sdkKey, Integer id, String type
176
335
result .success (createResponse (true , SuccessMessage .LISTENER_REMOVED ));
177
336
}
178
337
179
- protected void getOptimizelyConfig (String sdkKey , @ NonNull Result result ) {
338
+ protected void getOptimizelyConfig (ArgumentsParser argumentsParser , @ NonNull Result result ) {
339
+ String sdkKey = argumentsParser .getSdkKey ();
340
+ if (sdkKey == null ) {
341
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
342
+ return ;
343
+ }
180
344
OptimizelyClient optimizelyClient = getOptimizelyClient (sdkKey );
181
345
if (optimizelyClient == null ) {
182
346
result .success (createResponse (false , ErrorMessage .OPTIMIZELY_CLIENT_NOT_FOUND ));
@@ -193,9 +357,9 @@ protected void getOptimizelyConfig(String sdkKey, @NonNull Result result) {
193
357
194
358
public Map <String , ?> createResponse (Boolean success , Object result , String reason ) {
195
359
Map <String , Object > response = new HashMap <>();
196
- response .put ("success" , success );
197
- response .put ("result" , result );
198
- response .put ("reason" , reason );
360
+ response .put (ResponseKey . SUCCESS , success );
361
+ response .put (ResponseKey . RESULT , result );
362
+ response .put (ResponseKey . REASON , reason );
199
363
200
364
return response ;
201
365
}
@@ -211,4 +375,88 @@ public OptimizelyClient getOptimizelyClient(String SDKKey) {
211
375
public OptimizelyUserContext getUserContext (String SDKKey ) {
212
376
return userContextsTracker .get (SDKKey );
213
377
}
378
+
379
+ protected void addNotificationListener (ArgumentsParser argumentsParser , @ NonNull Result result ) {
380
+ String sdkKey = argumentsParser .getSdkKey ();
381
+ if (sdkKey == null ) {
382
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
383
+ return ;
384
+ }
385
+ Integer id = argumentsParser .getNotificaitonID ();
386
+ String type = argumentsParser .getNotificationType ();
387
+
388
+ OptimizelyClient optimizelyClient = getOptimizelyClient (sdkKey );
389
+ if (optimizelyClient == null ) {
390
+ result .success (createResponse (false , ErrorMessage .OPTIMIZELY_CLIENT_NOT_FOUND ));
391
+ return ;
392
+ }
393
+
394
+ if (id == null || type == null ) {
395
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
396
+ return ;
397
+ }
398
+ switch (type ) {
399
+ case NotificationType .DECISION : {
400
+ int notificationId = optimizelyClient .getNotificationCenter ().addNotificationHandler (DecisionNotification .class , decisionNotification -> {
401
+ Map <String , Object > notificationMap = new HashMap <>();
402
+ notificationMap .put (DecisionListenerKeys .TYPE , decisionNotification .getType ());
403
+ notificationMap .put (DecisionListenerKeys .USER_ID , decisionNotification .getUserId ());
404
+ notificationMap .put (DecisionListenerKeys .ATTRIBUTES , decisionNotification .getAttributes ());
405
+ notificationMap .put (DecisionListenerKeys .DECISION_INFO , convertKeysCamelCaseToSnakeCase (decisionNotification .getDecisionInfo ()));
406
+ invokeNotification (id , NotificationType .DECISION , notificationMap );
407
+ });
408
+ notificationIdsTracker .put (id , notificationId );
409
+ result .success (createResponse (true , SuccessMessage .LISTENER_ADDED ));
410
+ break ;
411
+ }
412
+ case NotificationType .TRACK : {
413
+ int notificationId = optimizelyClient .getNotificationCenter ().addNotificationHandler (TrackNotification .class , trackNotification -> {
414
+ Map <String , Object > notificationMap = new HashMap <>();
415
+ notificationMap .put (TrackListenerKeys .EVENT_KEY , trackNotification .getEventKey ());
416
+ notificationMap .put (TrackListenerKeys .USER_ID , trackNotification .getUserId ());
417
+ notificationMap .put (TrackListenerKeys .ATTRIBUTES , trackNotification .getAttributes ());
418
+ notificationMap .put (TrackListenerKeys .EVENT_TAGS , trackNotification .getEventTags ());
419
+ invokeNotification (id , NotificationType .TRACK , notificationMap );
420
+ });
421
+ notificationIdsTracker .put (id , notificationId );
422
+ result .success (createResponse (true , SuccessMessage .LISTENER_ADDED ));
423
+ break ;
424
+ }
425
+ case NotificationType .LOG_EVENT : {
426
+ int notificationId = optimizelyClient .getNotificationCenter ().addNotificationHandler (LogEvent .class , logEvent -> {
427
+ ObjectMapper mapper = new ObjectMapper ();
428
+ Map <String , Object > eventParams = mapper .readValue (logEvent .getBody (), Map .class );
429
+ Map <String , Object > listenerMap = new HashMap <>();
430
+ listenerMap .put (LogEventListenerKeys .URL , logEvent .getEndpointUrl ());
431
+ listenerMap .put (LogEventListenerKeys .HTTP_VERB , logEvent .getRequestMethod ());
432
+ listenerMap .put (LogEventListenerKeys .PARAMS , eventParams );
433
+ invokeNotification (id , NotificationType .LOG_EVENT , listenerMap );
434
+ });
435
+ notificationIdsTracker .put (id , notificationId );
436
+ result .success (createResponse (true , SuccessMessage .LISTENER_ADDED ));
437
+ break ;
438
+ }
439
+ case NotificationType .CONFIG_UPDATE : {
440
+ int notificationId = optimizelyClient .getNotificationCenter ().addNotificationHandler (UpdateConfigNotification .class , configUpdate -> {
441
+ Map <String , Object > listenerMap = new HashMap <>();
442
+ listenerMap .put ("Config-update" , Collections .emptyMap ());
443
+ invokeNotification (id , NotificationType .CONFIG_UPDATE , listenerMap );
444
+ });
445
+ notificationIdsTracker .put (id , notificationId );
446
+ result .success (createResponse (true , SuccessMessage .LISTENER_ADDED ));
447
+ break ;
448
+ }
449
+ default :
450
+ result .success (createResponse (false , ErrorMessage .INVALID_PARAMS ));
451
+ }
452
+ }
453
+
454
+ private void invokeNotification (int id , String notificationType , Map notificationMap ) {
455
+ Map <String , Object > listenerResponse = new HashMap <>();
456
+ listenerResponse .put (RequestParameterKey .NOTIFICATION_ID , id );
457
+ listenerResponse .put (RequestParameterKey .NOTIFICATION_TYPE , notificationType );
458
+ listenerResponse .put (RequestParameterKey .NOTIFICATION_PAYLOAD , notificationMap );
459
+ Map <String , Object > listenerUnmodifiable = Collections .unmodifiableMap (listenerResponse );
460
+ OptimizelyFlutterSdkPlugin .channel .invokeMethod ("callbackListener" , listenerUnmodifiable );
461
+ }
214
462
}
0 commit comments