Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
2640eaa
Cmab datafile parsed
FarhanAnjum-opti Aug 11, 2025
ad048df
Merge branch 'master' into farhan-anjum/FSSDK-11134-cmab-datafile-par…
FarhanAnjum-opti Aug 11, 2025
2d21ee2
Add CMAB configuration and parsing tests with cmab datafile
FarhanAnjum-opti Aug 12, 2025
0d3a88d
Add copyright notice to CmabTest and CmabParsingTest files
FarhanAnjum-opti Aug 12, 2025
50334f1
Refactor cmab parsing logic to simplify null check in JsonConfigParser
FarhanAnjum-opti Aug 12, 2025
87c553c
Merge branch 'master' into farhan-anjum/FSSDK-11134-cmab-datafile-par…
FarhanAnjum-opti Aug 12, 2025
8258bb0
update: implement remove method in DefaultLRUCache for cache entry re…
FarhanAnjum-opti Aug 12, 2025
4fa8cbe
add: implement remove method tests in DefaultLRUCacheTest for various…
FarhanAnjum-opti Aug 13, 2025
85b26d4
Merge branch 'master' into farhan-anjum/FSSDK-11152-update-lru-cache-…
FarhanAnjum-opti Aug 13, 2025
aa955eb
refactor: remove unused methods from Cache interface
FarhanAnjum-opti Aug 14, 2025
d3fc4bb
update: add reset method to Cache interface
FarhanAnjum-opti Aug 14, 2025
044c230
add: implement CmabClient, CmabClientConfig, and RetryConfig with fet…
FarhanAnjum-opti Aug 20, 2025
8eb694e
update: improve error logging in DefaultCmabClient for fetchDecision …
FarhanAnjum-opti Aug 20, 2025
50e2f7d
add: implement unit tests for DefaultCmabClient with various scenario…
FarhanAnjum-opti Aug 20, 2025
254d308
Merge branch 'master' into farhan-anjum/FSSDK-11143-implement-cmab-cl…
FarhanAnjum-opti Aug 20, 2025
04bb6f4
update: add missing license header to DefaultCmabClient.java
FarhanAnjum-opti Aug 20, 2025
7e9487c
update: add missing license headers to CmabClient, CmabClientConfig, …
FarhanAnjum-opti Aug 20, 2025
d41c775
refactor: update DefaultCmabClient to use synchronous fetchDecision m…
FarhanAnjum-opti Aug 25, 2025
208dbde
add: implement CmabDecision class and CmabService interface for CMAB …
FarhanAnjum-opti Aug 25, 2025
f4852e8
add: implement CmabCacheValue and CmabServiceOptions classes for CMAB…
FarhanAnjum-opti Aug 25, 2025
0201c53
add: extend OptimizelyDecideOption with new cache management options …
FarhanAnjum-opti Aug 25, 2025
3ab4324
add: implement DefaultCmabService with decision retrieval and attribu…
FarhanAnjum-opti Aug 27, 2025
1269180
add: implement fetchDecision method in DefaultCmabService for decisio…
FarhanAnjum-opti Aug 27, 2025
59c871d
add: enhance getDecision method in DefaultCmabService with caching lo…
FarhanAnjum-opti Aug 27, 2025
475432c
refactor: optimize hashAttributes method using MurmurHash3 and improv…
FarhanAnjum-opti Aug 27, 2025
7d6bab9
chore: add Apache License 2.0 header to multiple service classes
FarhanAnjum-opti Aug 27, 2025
34193cc
add: implement unit tests for DefaultCmabService with caching and dec…
FarhanAnjum-opti Aug 27, 2025
974cb0e
Merge branch 'master' into farhan-anjum/FSSDK-11161-implement-cmab-se…
FarhanAnjum-opti Aug 27, 2025
48bb54f
Empty commit to trigger tests
FarhanAnjum-opti Aug 27, 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright 2025, Optimizely
*
* 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
*
* https://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.cmab.service;

import java.util.Objects;

public class CmabCacheValue {
private final String attributesHash;
private final String variationId;
private final String cmabUUID;

public CmabCacheValue(String attributesHash, String variationId, String cmabUUID) {
this.attributesHash = attributesHash;
this.variationId = variationId;
this.cmabUUID = cmabUUID;
}

public String getAttributesHash() {
return attributesHash;
}

public String getVariationId() {
return variationId;
}

public String getCmabUuid() {
return cmabUUID;
}

@Override
public String toString() {
return "CmabCacheValue{" +
"attributesHash='" + attributesHash + '\'' +
", variationId='" + variationId + '\'' +
", cmabUuid='" + cmabUUID + '\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CmabCacheValue that = (CmabCacheValue) o;
return Objects.equals(attributesHash, that.attributesHash) &&
Objects.equals(variationId, that.variationId) &&
Objects.equals(cmabUUID, that.cmabUUID);
}

@Override
public int hashCode() {
return Objects.hash(attributesHash, variationId, cmabUUID);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* Copyright 2025, Optimizely
*
* 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
*
* https://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.cmab.service;

import java.util.Objects;

public class CmabDecision {
private final String variationId;
private final String cmabUUID;

public CmabDecision(String variationId, String cmabUUID) {
this.variationId = variationId;
this.cmabUUID = cmabUUID;
}

public String getVariationId() {
return variationId;
}

public String getCmabUUID() {
return cmabUUID;
}

@Override
public String toString() {
return "CmabDecision{" +
"variationId='" + variationId + '\'' +
", cmabUUID='" + cmabUUID + '\'' +
'}';
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CmabDecision that = (CmabDecision) o;
return Objects.equals(variationId, that.variationId) &&
Objects.equals(cmabUUID, that.cmabUUID);
}

@Override
public int hashCode() {
return Objects.hash(variationId, cmabUUID);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Copyright 2025, Optimizely
*
* 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
*
* https://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.cmab.service;

import java.util.List;

import com.optimizely.ab.OptimizelyUserContext;
import com.optimizely.ab.config.ProjectConfig;
import com.optimizely.ab.optimizelydecision.OptimizelyDecideOption;

public interface CmabService {
/**
* Get variation id for the user
* @param projectConfig the project configuration
* @param userContext the user context
* @param ruleId the rule identifier
* @param options list of decide options
* @return CompletableFuture containing the CMAB decision
*/
CmabDecision getDecision(
ProjectConfig projectConfig,
OptimizelyUserContext userContext,
String ruleId,
List<OptimizelyDecideOption> options
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/**
* Copyright 2025, Optimizely
*
* 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
*
* https://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.cmab.service;

import org.slf4j.Logger;

import com.optimizely.ab.cmab.client.CmabClient;
import com.optimizely.ab.internal.DefaultLRUCache;

public class CmabServiceOptions {
private final Logger logger;
private final DefaultLRUCache<CmabCacheValue> cmabCache;
private final CmabClient cmabClient;

public CmabServiceOptions(DefaultLRUCache<CmabCacheValue> cmabCache, CmabClient cmabClient) {
this(null, cmabCache, cmabClient);
}

public CmabServiceOptions(Logger logger, DefaultLRUCache<CmabCacheValue> cmabCache, CmabClient cmabClient) {
this.logger = logger;
this.cmabCache = cmabCache;
this.cmabClient = cmabClient;
}

public Logger getLogger() {
return logger;
}

public DefaultLRUCache<CmabCacheValue> getCmabCache() {
return cmabCache;
}

public CmabClient getCmabClient() {
return cmabClient;
}
}
Loading
Loading