Skip to content

Commit 1c2ae64

Browse files
committed
fix cmab in test-app
1 parent 929e676 commit 1c2ae64

File tree

5 files changed

+267
-18
lines changed

5 files changed

+267
-18
lines changed

android-sdk/src/main/java/com/optimizely/ab/android/sdk/cmab/DefaultCmabClient.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ open class DefaultCmabClient : CmabClient {
6868
val requestBody: String =
6969
cmabClientHelper.buildRequestJson(userId, ruleId, attributes, cmabUuid)
7070

71+
logger.info("Fetching CMAB decision: " + apiEndpoint + " with body: " + requestBody)
72+
7173
val url = URL(apiEndpoint)
7274
urlConnection = client.openConnection(url)
7375
if (urlConnection == null) {
@@ -99,6 +101,7 @@ open class DefaultCmabClient : CmabClient {
99101

100102
return@Request cmabClientHelper.parseVariationId(json)
101103
} else {
104+
logger.debug("Failed to fetching CMAB decision for ruleId=" + ruleId + " and userId=" + userId + ": status=" + status);
102105
val errorMessage: String = java.lang.String.format(
103106
cmabClientHelper.cmabFetchFailed,
104107
urlConnection.responseMessage
@@ -107,6 +110,7 @@ open class DefaultCmabClient : CmabClient {
107110
throw CmabFetchException(errorMessage)
108111
}
109112
} catch (e: Exception) {
113+
logger.debug("Failed to fetching CMAB decision for ruleId=" + ruleId + " and userId=" + userId);
110114
val errorMessage: String =
111115
java.lang.String.format(cmabClientHelper.cmabFetchFailed, e.message)
112116
logger.error(errorMessage)

build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ allprojects {
6666
}
6767

6868
repositories {
69+
mavenLocal()
6970
google()
7071
mavenCentral()
7172
// SNAPSHOT support
@@ -95,7 +96,7 @@ ext {
9596
build_tools_version = "35.0.0"
9697
min_sdk_version = 21
9798
target_sdk_version = 35
98-
java_core_ver = "4.2.2"
99+
java_core_ver = "3.1.0-SNAPSHOT"
99100
android_logger_ver = "1.3.6"
100101
jacksonversion= "2.11.2"
101102
annotations_ver = "1.2.0"

test-app/src/main/java/com/optimizely/ab/android/test_app/Samples/APISamplesInJava.java

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,15 @@
6262
import java.util.List;
6363
import java.util.Map;
6464
import java.util.Set;
65+
import java.util.concurrent.CountDownLatch;
6566
import java.util.concurrent.TimeUnit;
6667

6768
public class APISamplesInJava {
6869

6970
static public void samplesAll(Context context) {
71+
samplesForCmab__local_datafile(context);
72+
samplesForCmab__cdn_datafile(context);
73+
7074
samplesForDecide(context);
7175
samplesForInitialization(context);
7276
samplesForOptimizelyConfig(context);
@@ -94,6 +98,130 @@ static public void samplesAll(Context context) {
9498
samplesForDoc_ODP_sync(context);
9599
}
96100

101+
102+
static public void samplesForCmab__local_datafile(Context context) {
103+
List<OptimizelyDecideOption> defaultDecideOptions = Arrays.asList(
104+
OptimizelyDecideOption.INCLUDE_REASONS,
105+
OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE
106+
);
107+
108+
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
109+
.withSDKKey("invalid-sdk-key-for-cmab-testing")
110+
.withDefaultDecideOptions(defaultDecideOptions)
111+
.build(context);
112+
// we use raw datafile for this testing
113+
OptimizelyClient optimizelyClient = optimizelyManager.initialize(context, R.raw.datafile_full);
114+
115+
String userId = "user_123";
116+
Map<String, Object> attributes = new HashMap<>();
117+
attributes.put("is_logged_in", false);
118+
attributes.put("app_version", "1.3.2");
119+
OptimizelyUserContext user = optimizelyClient.createUserContext(userId, attributes);
120+
121+
// decide (decideSync)
122+
123+
String flagKey = "cmab-1";
124+
125+
List<OptimizelyDecideOption> options = Arrays.asList(OptimizelyDecideOption.INCLUDE_REASONS);
126+
Log.d("Samples","=================================================================");
127+
Log.d("Samples","[CMAB Local Datafile] calling sync decision for cmab...");
128+
Log.d("Samples","=================================================================");
129+
OptimizelyDecision decision = user.decide(flagKey, options);
130+
131+
Log.d("Samples","=================================================================");
132+
Log.d("Samples","[CMAB Local Datafile] sync decision for cmab: " + decision.toString());
133+
if (decision.getEnabled()) {
134+
Log.e("Samples","[ERROR] " + flagKey + " is expected to be NOT enabled for this user!");
135+
}
136+
Log.d("Samples","=================================================================");
137+
138+
// decideAsync
139+
140+
Log.d("Samples","=================================================================");
141+
Log.d("Samples","[CMAB Local Datafile] calling async decision for cmab...");
142+
Log.d("Samples","=================================================================");
143+
final CountDownLatch latch = new CountDownLatch(1);
144+
user.decideAsync(flagKey, options, (OptimizelyDecision optDecision) -> {
145+
Log.d("Samples","=================================================================");
146+
Log.d("Samples","[CMAB Local Datafile] async decision for cmab: " + optDecision.toString());
147+
if (!optDecision.getEnabled()) {
148+
Log.e("Samples","[ERROR] " + flagKey + " is expected to be enabled for this user!");
149+
}
150+
Log.d("Samples","=================================================================");
151+
latch.countDown();
152+
});
153+
154+
try {
155+
latch.await(5, TimeUnit.SECONDS);
156+
Log.d("Samples", "[CMAB Local Datafile] Latch released. Async operation completed.");
157+
} catch (InterruptedException e) {
158+
e.printStackTrace();
159+
Thread.currentThread().interrupt();
160+
}
161+
}
162+
163+
164+
static public void samplesForCmab__cdn_datafile(Context context) {
165+
List<OptimizelyDecideOption> defaultDecideOptions = Arrays.asList(
166+
OptimizelyDecideOption.INCLUDE_REASONS,
167+
OptimizelyDecideOption.IGNORE_USER_PROFILE_SERVICE
168+
);
169+
170+
// we use project=4552646833471488 for CMAB testing
171+
OptimizelyManager optimizelyManager = OptimizelyManager.builder()
172+
.withSDKKey("4ft9p1vSXYM5hLATwWdRc")
173+
.withDefaultDecideOptions(defaultDecideOptions)
174+
.build(context);
175+
// we use raw datafile for this testing
176+
OptimizelyClient optimizelyClient = optimizelyManager.initialize(context, R.raw.datafile_full);
177+
178+
String userId = "user_20";
179+
Map<String, Object> attributes = new HashMap<>();
180+
attributes.put("country", "us");
181+
OptimizelyUserContext user = optimizelyClient.createUserContext(userId, attributes);
182+
183+
// decide (decideSync)
184+
185+
String flagKey = "cmab-flag";
186+
187+
List<OptimizelyDecideOption> options = Arrays.asList(OptimizelyDecideOption.INCLUDE_REASONS);
188+
Log.d("Samples","=================================================================");
189+
Log.d("Samples","[CMAB CDN Datafile] calling sync decision for cmab...");
190+
Log.d("Samples","=================================================================");
191+
OptimizelyDecision decision = user.decide(flagKey, options);
192+
193+
Log.d("Samples","=================================================================");
194+
Log.d("Samples","[CMAB CDN Datafile] sync decision for cmab: " + decision.toString());
195+
if (decision.getEnabled()) {
196+
Log.e("Samples","[ERROR] " + flagKey + " is expected to be NOT enabled for this user!");
197+
}
198+
Log.d("Samples","=================================================================");
199+
200+
// decideAsync
201+
202+
Log.d("Samples","=================================================================");
203+
Log.d("Samples","[CMAB CDN Datafile] calling async decision for cmab...");
204+
Log.d("Samples","=================================================================");
205+
final CountDownLatch latch = new CountDownLatch(1);
206+
user.decideAsync(flagKey, options, (OptimizelyDecision optDecision) -> {
207+
Log.d("Samples","=================================================================");
208+
Log.d("Samples","[CMAB CDN Datafile] async decision for cmab: " + optDecision.toString());
209+
if (!optDecision.getEnabled()) {
210+
Log.e("Samples","[ERROR] " + flagKey + " is expected to be enabled for this user!");
211+
}
212+
Log.d("Samples","=================================================================");
213+
latch.countDown();
214+
});
215+
216+
try {
217+
latch.await(5, TimeUnit.SECONDS);
218+
Log.d("Samples", "[CMAB CDN Datafile] Latch released. Async operation completed.");
219+
} catch (InterruptedException e) {
220+
e.printStackTrace();
221+
Thread.currentThread().interrupt();
222+
}
223+
}
224+
97225
static public void samplesForDecide(Context context) {
98226
// this default-options will be applied to all following decide calls.
99227
List<OptimizelyDecideOption> defaultDecideOptions = Arrays.asList(OptimizelyDecideOption.DISABLE_DECISION_EVENT);

test-app/src/main/java/com/optimizely/ab/android/test_app/SplashScreenActivity.kt

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -45,23 +45,27 @@ class SplashScreenActivity : AppCompatActivity() {
4545
override fun onStart() {
4646
super.onStart()
4747

48-
val INITIALIZE_ASYNCHRONOUSLY = true
49-
50-
// with the new Android O differences, you need to register the service for the intent filter you desire in code instead of
51-
// in the manifest.
52-
val eventRescheduler = EventRescheduler()
53-
applicationContext.registerReceiver(eventRescheduler, IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
54-
55-
if (INITIALIZE_ASYNCHRONOUSLY) {
56-
optimizelyManager!!.initialize(this, R.raw.datafile) { _ ->
57-
addNotificationListeners()
58-
startVariation()
59-
}
60-
} else {
61-
optimizelyManager!!.initialize(this, R.raw.datafile)
62-
addNotificationListeners()
63-
startVariation()
64-
}
48+
APISamplesInJava.samplesForCmab__local_datafile(this)
49+
APISamplesInJava.samplesForCmab__cdn_datafile(this)
50+
51+
//
52+
// val INITIALIZE_ASYNCHRONOUSLY = true
53+
//
54+
// // with the new Android O differences, you need to register the service for the intent filter you desire in code instead of
55+
// // in the manifest.
56+
// val eventRescheduler = EventRescheduler()
57+
// applicationContext.registerReceiver(eventRescheduler, IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
58+
//
59+
// if (INITIALIZE_ASYNCHRONOUSLY) {
60+
// optimizelyManager!!.initialize(this, R.raw.datafile) { _ ->
61+
// addNotificationListeners()
62+
// startVariation()
63+
// }
64+
// } else {
65+
// optimizelyManager!!.initialize(this, R.raw.datafile)
66+
// addNotificationListeners()
67+
// startVariation()
68+
// }
6569

6670
}
6771

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
{
2+
"accountId": "5030020721",
3+
"projectId": "5139960550391808",
4+
"revision": "7",
5+
"attributes": [
6+
{
7+
"id": "5179257152339968",
8+
"key": "age"
9+
}
10+
],
11+
"audiences": [
12+
{
13+
"id": "$opt_dummy_audience",
14+
"name": "Optimizely-Generated Audience for Backwards Compatibility",
15+
"conditions": "[\"or\", {\"match\": \"exact\", \"name\": \"$opt_dummy_attribute\", \"type\": \"custom_attribute\", \"value\": \"$opt_dummy_value\"}]"
16+
}
17+
],
18+
"version": "4",
19+
"events": [
20+
{
21+
"id": "6548971704287232",
22+
"experimentIds": [
23+
"9000003791039"
24+
],
25+
"key": "ev1"
26+
}
27+
],
28+
"integrations": [],
29+
"holdouts": [],
30+
"anonymizeIP": true,
31+
"botFiltering": false,
32+
"typedAudiences": [],
33+
"variables": [],
34+
"environmentKey": "development",
35+
"sdkKey": "AxbpgEqC9P2tRv9zC1cdu",
36+
"featureFlags": [
37+
{
38+
"id": "849323",
39+
"key": "cmab-1",
40+
"rolloutId": "rollout-849323-431750693605093",
41+
"experimentIds": [
42+
"90000001"
43+
],
44+
"variables": []
45+
}
46+
],
47+
"rollouts": [
48+
{
49+
"id": "rollout-849323-431750693605093",
50+
"experiments": [
51+
{
52+
"id": "default-rollout-849323-431750693605093",
53+
"key": "default-rollout-849323-431750693605093",
54+
"status": "Running",
55+
"layerId": "rollout-849323-431750693605093",
56+
"variations": [
57+
{
58+
"id": "1993173",
59+
"key": "off",
60+
"featureEnabled": false,
61+
"variables": []
62+
}
63+
],
64+
"trafficAllocation": [
65+
{
66+
"entityId": "1993173",
67+
"endOfRange": 10000
68+
}
69+
],
70+
"forcedVariations": {},
71+
"audienceIds": [],
72+
"audienceConditions": []
73+
}
74+
]
75+
},
76+
{}
77+
],
78+
"experiments": [
79+
{
80+
"id": "90000001",
81+
"key": "c1",
82+
"status": "Running",
83+
"layerId": "9000003768807",
84+
"variations": [
85+
{
86+
"id": "1993173",
87+
"key": "off",
88+
"featureEnabled": false,
89+
"variables": []
90+
},
91+
{
92+
"id": "1993174",
93+
"key": "on",
94+
"featureEnabled": true,
95+
"variables": []
96+
}
97+
],
98+
"trafficAllocation": [],
99+
"forcedVariations": {},
100+
"audienceIds": [],
101+
"audienceConditions": [],
102+
"cmab": {
103+
"attributeIds": [
104+
"5179257152339968"
105+
],
106+
"trafficAllocation": 10000
107+
}
108+
}
109+
],
110+
"groups": [],
111+
"region": "US"
112+
}

0 commit comments

Comments
 (0)