Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
26e6393
update: add CmabService to Optimizely class and builder
FarhanAnjum-opti Sep 19, 2025
ad63201
update: integrate CMAB service into OptimizelyFactory
FarhanAnjum-opti Sep 19, 2025
fbed362
update: change CmabService field to non-nullable in Optimizely class
FarhanAnjum-opti Sep 19, 2025
53d754a
update: add CmabService to DecisionService and its tests
FarhanAnjum-opti Sep 19, 2025
9905026
update: implement CMAB traffic allocation in Bucketer and DecisionSer…
FarhanAnjum-opti Sep 23, 2025
78f45bf
update: enhance DecisionService, FeatureDecision, and DecisionRespons…
FarhanAnjum-opti Sep 24, 2025
9757d49
update: enhance DecisionService and DecisionMessage to handle errors …
FarhanAnjum-opti Sep 24, 2025
ecf9199
update: add validConfigJsonCMAB method to DatafileProjectConfigTestUt…
FarhanAnjum-opti Sep 24, 2025
5e0808f
update: add tests to verify precedence of whitelisted and forced vari…
FarhanAnjum-opti Sep 24, 2025
36d2b4c
update: add test to verify error handling in getVariation for CMAB se…
FarhanAnjum-opti Sep 24, 2025
5796cb7
update: modify DecisionResponse to include additional error handling …
FarhanAnjum-opti Sep 24, 2025
d8b0134
update: fix error handling assertion in DecisionServiceTest to correc…
FarhanAnjum-opti Sep 24, 2025
b2f270f
update: add tests for CMAB experiment variations in DecisionService
FarhanAnjum-opti Sep 24, 2025
a4c3f1c
update: implement decision-making methods to skip CMAB logic in Optim…
FarhanAnjum-opti Sep 24, 2025
e4fe788
update: add methods to OptimizelyUserContext for decision-making with…
FarhanAnjum-opti Sep 24, 2025
e75693d
update: add asynchronous decision-making methods in OptimizelyUserCon…
FarhanAnjum-opti Sep 24, 2025
af210d8
update: add decision-making methods without CMAB logic in OptimizelyU…
FarhanAnjum-opti Sep 24, 2025
42053e4
update: remove unused parameter 'useCmab' from DecisionService method…
FarhanAnjum-opti Sep 24, 2025
9a12d72
update: rename methods to use 'Sync' suffix for clarity in decision-m…
FarhanAnjum-opti Sep 25, 2025
a4419a4
update: add cmabUUID parameter to impression event methods and relate…
FarhanAnjum-opti Sep 26, 2025
416bcbd
update: return cmab error decision whenever found
FarhanAnjum-opti Sep 30, 2025
0213b60
Merge branch 'farhan-anjum/FSSDK-11170-decision-service-methods-for-c…
FarhanAnjum-opti Sep 30, 2025
64f378f
update: enhance error handling by specifying CMAB error messages in d…
FarhanAnjum-opti Oct 1, 2025
d0a2b59
Merge branch 'farhan-anjum/FSSDK-11170-decision-service-methods-for-c…
FarhanAnjum-opti Oct 1, 2025
8539166
update: improve error handling by checking for null values in experim…
FarhanAnjum-opti Oct 1, 2025
16a70cc
Merge branch 'farhan-anjum/FSSDK-11170-decision-service-methods-for-c…
FarhanAnjum-opti Oct 1, 2025
3cee65c
update: fix CMAB error handling by providing a valid Experiment in Fe…
FarhanAnjum-opti Oct 1, 2025
59b90d7
Merge branch 'farhan-anjum/FSSDK-11170-decision-service-methods-for-c…
FarhanAnjum-opti Oct 1, 2025
47c65b5
update: add Javadoc comments for async decision methods and config cr…
FarhanAnjum-opti Oct 1, 2025
fe75a85
update: refactor build to use cmabClient instead of default service
FarhanAnjum-opti Oct 3, 2025
b0d5090
update: refactor DefaultCmabClient to utilize CmabClientHelper
FarhanAnjum-opti Oct 3, 2025
6db2e88
update: refactor AsyncDecisionsFetcher to AsyncDecisionFetcher and en…
FarhanAnjum-opti Oct 3, 2025
6fc6446
update: add missing copyright notice and license information to CmabC…
FarhanAnjum-opti Oct 3, 2025
a80c0d3
update: enhance CMAB handling in bucketing and decision services, add…
FarhanAnjum-opti Oct 15, 2025
a9ae805
update: add backward compatibility support for Android sync and async…
FarhanAnjum-opti Oct 15, 2025
f25f824
update: add empty list parameter to decision methods in OptimizelyUse…
FarhanAnjum-opti Oct 15, 2025
7363a2f
update: replace null with empty list parameter in async decision meth…
FarhanAnjum-opti Oct 15, 2025
1c52366
update: add useCmab parameter to decideForKeys methods for enhanced d…
FarhanAnjum-opti Oct 15, 2025
b2dcf9e
Update core-api/src/main/java/com/optimizely/ab/Optimizely.java
FarhanAnjum-opti Oct 17, 2025
89771bc
update: refactor decision-making logic to use DecisionPath enum for c…
FarhanAnjum-opti Oct 23, 2025
73d5673
Update core-api/src/main/java/com/optimizely/ab/Optimizely.java
FarhanAnjum-opti Oct 23, 2025
690379c
Update core-api/src/main/java/com/optimizely/ab/Optimizely.java
FarhanAnjum-opti Oct 23, 2025
9c8dd8f
update: modify OptimizelyUserContext to change optimizely field to pa…
FarhanAnjum-opti Oct 27, 2025
a17becd
update: implement asynchronous decision-making methods in Optimizely …
FarhanAnjum-opti Oct 27, 2025
ba575ce
update: refactor DefaultCmabService to remove CmabServiceOptions depe…
FarhanAnjum-opti Oct 27, 2025
ad474c8
update: refactor DefaultCmabService to use a generic Cache interface …
FarhanAnjum-opti Oct 27, 2025
9f7ea59
fix to support android-sdk
jaeopt Oct 30, 2025
93cdaba
clean up
jaeopt Oct 30, 2025
e459321
update: refactor bucketing logic to remove CMAB handling from Decisio…
FarhanAnjum-opti Nov 5, 2025
8c96222
update: introduce CacheWithRemove interface and refactor DefaultCmabS…
FarhanAnjum-opti Nov 6, 2025
7c97734
update: implement CacheWithRemove interface in DefaultLRUCache class
FarhanAnjum-opti Nov 6, 2025
4feb857
update: refactor OptimizelyFactory to remove CMAB cache methods and a…
FarhanAnjum-opti Nov 6, 2025
4b35768
update: refactor DefaultCmabService to streamline logger initializati…
FarhanAnjum-opti Nov 6, 2025
c4c07a6
Merge branch 'farhan-anjum/FSSDK-11170-decision-service-methods-for-c…
FarhanAnjum-opti Nov 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 184 additions & 22 deletions core-api/src/main/java/com/optimizely/ab/Optimizely.java

Large diffs are not rendered by default.

68 changes: 58 additions & 10 deletions core-api/src/main/java/com/optimizely/ab/OptimizelyUserContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,26 @@
*/
package com.optimizely.ab;

import com.optimizely.ab.config.ProjectConfig;
import com.optimizely.ab.odp.ODPManager;
import com.optimizely.ab.odp.ODPSegmentCallback;
import com.optimizely.ab.odp.ODPSegmentOption;
import com.optimizely.ab.optimizelydecision.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

import com.optimizely.ab.annotations.VisibleForTesting;
import com.optimizely.ab.optimizelydecision.OptimizelyDecisionCallback;
import com.optimizely.ab.optimizelydecision.OptimizelyDecisionsCallback;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.optimizely.ab.odp.ODPSegmentCallback;
import com.optimizely.ab.odp.ODPSegmentOption;
import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption;
import com.optimizely.ab.optimizelydecision.OptimizelyDecision;

public class OptimizelyUserContext {
// OptimizelyForcedDecisionsKey mapped to variationKeys
Expand All @@ -42,7 +50,7 @@ public class OptimizelyUserContext {
private List<String> qualifiedSegments;

@Nonnull
private final Optimizely optimizely;
final Optimizely optimizely;

private static final Logger logger = LoggerFactory.getLogger(OptimizelyUserContext.class);

Expand Down Expand Up @@ -390,4 +398,44 @@ public String toString() {
", attributes='" + attributes + '\'' +
'}';
}

// sync decision support for android-sdk backward compatibility only

@VisibleForTesting // protected, open for testing only
public OptimizelyDecision decideSync(@Nonnull String key,
@Nonnull List<OptimizelyDecideOption> options) {
return optimizely.decideSync(copy(), key, options);
}

@VisibleForTesting // protected, open for testing only
public Map<String, OptimizelyDecision> decideForKeysSync(@Nonnull List<String> keys,
@Nonnull List<OptimizelyDecideOption> options) {
return optimizely.decideForKeysSync(copy(), keys, options);
}

@VisibleForTesting // protected, open for testing only
public Map<String, OptimizelyDecision> decideAllSync(@Nonnull List<OptimizelyDecideOption> options) {
return optimizely.decideAllSync(copy(), options);
}

@VisibleForTesting // protected, open for testing only
public void decideAsync(@Nonnull String key,
@Nonnull List<OptimizelyDecideOption> options,
@Nonnull OptimizelyDecisionCallback callback) {
optimizely.decideAsync(copy(), key, options, callback);
}

@VisibleForTesting // protected, open for testing only
public void decideForKeysAsync(@Nonnull List<String> keys,
@Nonnull List<OptimizelyDecideOption> options,
@Nonnull OptimizelyDecisionsCallback callback) {
optimizely.decideForKeysAsync(copy(), keys, options, callback);
}

@VisibleForTesting // protected, open for testing only
public void decideAllAsync(@Nonnull List<OptimizelyDecideOption> options,
@Nonnull OptimizelyDecisionsCallback callback) {
optimizely.decideAllAsync(copy(), options, callback);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,4 @@ int generateBucketValue(int hashCode) {
return (int) Math.floor(MAX_TRAFFIC_VALUE * ratio);
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/****************************************************************************
* Copyright 2025 Optimizely, Inc. and contributors *
* *
* Licensed under the Apache License, Version 2.0 (the "License"); *
* you may not use this file except in compliance with the License. *
* You may obtain a copy of the License at *
* *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an "AS IS" BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
***************************************************************************/
package com.optimizely.ab.bucketing;

public enum DecisionPath {
WITH_CMAB, // Use CMAB logic
WITHOUT_CMAB // Skip CMAB logic (traditional A/B testing)
}
Loading
Loading