Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
21 changes: 21 additions & 0 deletions core-api/src/main/java/com/optimizely/ab/Optimizely.java
Original file line number Diff line number Diff line change
Expand Up @@ -1445,6 +1445,11 @@ public <T> int addNotificationHandler(Class<T> clazz, NotificationHandler<T> han
}

public List<String> fetchQualifiedSegments(String userId, @Nonnull List<ODPSegmentOption> segmentOptions) {
ProjectConfig projectConfig = getProjectConfig();
if (projectConfig == null) {
logger.error("Optimizely instance is not valid, failing fetchQualifiedSegments call.");
return null;
}
if (odpManager != null) {
synchronized (odpManager) {
return odpManager.getSegmentManager().getQualifiedSegments(userId, segmentOptions);
Expand All @@ -1455,6 +1460,12 @@ public List<String> fetchQualifiedSegments(String userId, @Nonnull List<ODPSegme
}

public void fetchQualifiedSegments(String userId, ODPSegmentManager.ODPSegmentFetchCallback callback, List<ODPSegmentOption> segmentOptions) {
ProjectConfig projectConfig = getProjectConfig();
if (projectConfig == null) {
logger.error("Optimizely instance is not valid, failing fetchQualifiedSegments call.");
callback.onCompleted(null);
return;
}
if (odpManager == null) {
logger.error("Audience segments fetch failed (ODP is not enabled).");
callback.onCompleted(null);
Expand All @@ -1478,6 +1489,11 @@ public ODPManager getODPManager() {
* @param data a dictionary for associated data. The default event data will be added to this data before sending to the ODP server.
*/
public void sendODPEvent(@Nullable String type, @Nonnull String action, @Nullable Map<String, String> identifiers, @Nullable Map<String, Object> data) {
ProjectConfig projectConfig = getProjectConfig();
if (projectConfig == null) {
logger.error("Optimizely instance is not valid, failing sendODPEvent call.");
return;
}
if (odpManager != null) {
ODPEvent event = new ODPEvent(type, action, identifiers, data);
odpManager.getEventManager().sendEvent(event);
Expand All @@ -1487,6 +1503,11 @@ public void sendODPEvent(@Nullable String type, @Nonnull String action, @Nullabl
}

public void identifyUser(@Nonnull String userId) {
ProjectConfig projectConfig = getProjectConfig();
if (projectConfig == null) {
logger.error("Optimizely instance is not valid, failing identifyUser call.");
return;
}
ODPManager odpManager = getODPManager();
if (odpManager != null) {
odpManager.getEventManager().identifyUser(userId);
Expand Down
31 changes: 30 additions & 1 deletion core-api/src/test/java/com/optimizely/ab/OptimizelyTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -4733,6 +4733,7 @@ public void initODPManagerWithProjectConfig() throws IOException {
@Test
public void sendODPEvent() {
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(validProjectConfig);
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
ODPManager mockODPManager = mock(ODPManager.class);

Expand Down Expand Up @@ -4763,9 +4764,36 @@ public void sendODPEvent() {
}

@Test
public void sendODPEventError() {
public void sendODPEventInvalidConfig() {
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(null);
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
ODPManager mockODPManager = mock(ODPManager.class);

Mockito.when(mockODPManager.getEventManager()).thenReturn(mockODPEventManager);
Optimizely optimizely = Optimizely.builder()
.withConfigManager(mockProjectConfigManager)
.withODPManager(mockODPManager)
.build();

verify(mockODPEventManager).start();

Map<String, String> identifiers = new HashMap<>();
identifiers.put("id1", "value1");
identifiers.put("id2", "value2");

Map<String, Object> data = new HashMap<>();
data.put("sdk", "java");
data.put("revision", 52);

optimizely.sendODPEvent("fullstack", "identify", identifiers, data);
logbackVerifier.expectMessage(Level.ERROR, "Optimizely instance is not valid, failing sendODPEvent call.");
}

@Test
public void sendODPEventError() {
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(validProjectConfig);
Optimizely optimizely = Optimizely.builder()
.withConfigManager(mockProjectConfigManager)
.build();
Expand All @@ -4785,6 +4813,7 @@ public void sendODPEventError() {
@Test
public void identifyUser() {
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(validProjectConfig);
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
ODPManager mockODPManager = mock(ODPManager.class);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1628,6 +1628,8 @@ public void fetchQualifiedSegments() {
Mockito.when(mockODPManager.getSegmentManager()).thenReturn(mockODPSegmentManager);

Optimizely optimizely = Optimizely.builder()
.withDatafile(datafile)
.withEventProcessor(new ForwardingEventProcessor(eventHandler, null))
.withODPManager(mockODPManager)
.build();

Expand All @@ -1640,9 +1642,33 @@ public void fetchQualifiedSegments() {
verify(mockODPSegmentManager).getQualifiedSegments("test-user", Collections.singletonList(ODPSegmentOption.RESET_CACHE));
}

@Test
public void fetchQualifiedSegmentsErrorWhenConfigIsInvalid() {
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(null);
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
ODPSegmentManager mockODPSegmentManager = mock(ODPSegmentManager.class);
ODPManager mockODPManager = mock(ODPManager.class);

Mockito.when(mockODPManager.getEventManager()).thenReturn(mockODPEventManager);
Mockito.when(mockODPManager.getSegmentManager()).thenReturn(mockODPSegmentManager);

Optimizely optimizely = Optimizely.builder()
.withConfigManager(mockProjectConfigManager)
.withODPManager(mockODPManager)
.build();

OptimizelyUserContext userContext = optimizely.createUserContext("test-user");

assertFalse(userContext.fetchQualifiedSegments());
logbackVerifier.expectMessage(Level.ERROR, "Optimizely instance is not valid, failing fetchQualifiedSegments call.");
}

@Test
public void fetchQualifiedSegmentsError() {
Optimizely optimizely = Optimizely.builder()
.withDatafile(datafile)
.withEventProcessor(new ForwardingEventProcessor(eventHandler, null))
.build();
OptimizelyUserContext userContext = optimizely.createUserContext("test-user");

Expand All @@ -1667,6 +1693,8 @@ public void fetchQualifiedSegmentsAsync() throws InterruptedException {
Mockito.when(mockODPManager.getSegmentManager()).thenReturn(mockODPSegmentManager);

Optimizely optimizely = Optimizely.builder()
.withDatafile(datafile)
.withEventProcessor(new ForwardingEventProcessor(eventHandler, null))
.withODPManager(mockODPManager)
.build();

Expand Down Expand Up @@ -1698,6 +1726,8 @@ public void fetchQualifiedSegmentsAsync() throws InterruptedException {
@Test
public void fetchQualifiedSegmentsAsyncError() throws InterruptedException {
Optimizely optimizely = Optimizely.builder()
.withDatafile(datafile)
.withEventProcessor(new ForwardingEventProcessor(eventHandler, null))
.build();

OptimizelyUserContext userContext = optimizely.createUserContext("test-user");
Expand All @@ -1713,6 +1743,57 @@ public void fetchQualifiedSegmentsAsyncError() throws InterruptedException {
logbackVerifier.expectMessage(Level.ERROR, "Audience segments fetch failed (ODP is not enabled).");
}

@Test
public void fetchQualifiedSegmentsAsyncErrorWhenConfigIsInvalid() throws InterruptedException {
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(null);
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
ODPSegmentManager mockODPSegmentManager = mock(ODPSegmentManager.class);
ODPManager mockODPManager = mock(ODPManager.class);

Mockito.when(mockODPManager.getEventManager()).thenReturn(mockODPEventManager);
Mockito.when(mockODPManager.getSegmentManager()).thenReturn(mockODPSegmentManager);

Optimizely optimizely = Optimizely.builder()
.withConfigManager(mockProjectConfigManager)
.withODPManager(mockODPManager)
.build();

OptimizelyUserContext userContext = optimizely.createUserContext("test-user");

CountDownLatch countDownLatch = new CountDownLatch(1);
userContext.fetchQualifiedSegments((Boolean isFetchSuccessful) -> {
assertFalse(isFetchSuccessful);
countDownLatch.countDown();
});

countDownLatch.await();
assertEquals(null, userContext.getQualifiedSegments());
logbackVerifier.expectMessage(Level.ERROR, "Optimizely instance is not valid, failing fetchQualifiedSegments call.");
}

@Test
public void identifyUserErrorWhenConfigIsInvalid() {
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
ODPSegmentManager mockODPSegmentManager = mock(ODPSegmentManager.class);
ODPManager mockODPManager = mock(ODPManager.class);
ProjectConfigManager mockProjectConfigManager = mock(ProjectConfigManager.class);
Mockito.when(mockProjectConfigManager.getConfig()).thenReturn(null);
Mockito.when(mockODPManager.getEventManager()).thenReturn(mockODPEventManager);
Mockito.when(mockODPManager.getSegmentManager()).thenReturn(mockODPSegmentManager);

Optimizely optimizely = Optimizely.builder()
.withConfigManager(mockProjectConfigManager)
.withODPManager(mockODPManager)
.build();

optimizely.createUserContext("test-user");
verify(mockODPEventManager, never()).identifyUser("test-user");
Mockito.reset(mockODPEventManager);

logbackVerifier.expectMessage(Level.ERROR, "Optimizely instance is not valid, failing identifyUser call.");
}

@Test
public void identifyUser() {
ODPEventManager mockODPEventManager = mock(ODPEventManager.class);
Expand All @@ -1723,6 +1804,8 @@ public void identifyUser() {
Mockito.when(mockODPManager.getSegmentManager()).thenReturn(mockODPSegmentManager);

Optimizely optimizely = Optimizely.builder()
.withDatafile(datafile)
.withEventProcessor(new ForwardingEventProcessor(eventHandler, null))
.withODPManager(mockODPManager)
.build();

Expand Down