Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
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;
Expand Down Expand Up @@ -313,6 +314,8 @@ public void setQualifiedSegments(List<String> qualifiedSegments) {
* Fetch all qualified segments for the user context.
* <p>
* The segments fetched will be saved and can be accessed at any time by calling {@link #getQualifiedSegments()}.
*
* @return a boolean value for fetch success or failure.
*/
public Boolean fetchQualifiedSegments() {
return fetchQualifiedSegments(Collections.emptyList());
Expand All @@ -324,6 +327,7 @@ public Boolean fetchQualifiedSegments() {
* The segments fetched will be saved and can be accessed at any time by calling {@link #getQualifiedSegments()}.
*
* @param segmentOptions A set of options for fetching qualified segments.
* @return a boolean value for fetch success or failure.
*/
public Boolean fetchQualifiedSegments(@Nonnull List<ODPSegmentOption> segmentOptions) {
List<String> segments = optimizely.fetchQualifiedSegments(userId, segmentOptions);
Expand Down
4 changes: 2 additions & 2 deletions core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright 2022, Optimizely Inc. and contributors
* Copyright 2022-2023, 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.
Expand All @@ -26,7 +26,7 @@ public class ODPEvent {

private String type;
private String action;
private Map<String, String > identifiers;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update the header as this is nit fix?

private Map<String, String> identifiers;
private Map<String, Object> data;

public ODPEvent(@Nullable String type, @Nonnull String action, @Nullable Map<String, String> identifiers, @Nullable Map<String, Object> data) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
*/
package com.optimizely.ab.odp;

import com.optimizely.ab.annotations.VisibleForTesting;
import com.optimizely.ab.event.internal.BuildVersionInfo;
import com.optimizely.ab.event.internal.ClientEngineInfo;
import com.optimizely.ab.odp.serializer.ODPJsonSerializerFactory;
Expand All @@ -38,6 +39,8 @@ public class ODPEventManager {
private final int queueSize;
private final int batchSize;
private final int flushInterval;
@Nonnull private Map<String, Object> userCommonData = Collections.emptyMap();
@Nonnull private Map<String, String> userCommonIdentifiers = Collections.emptyMap();

private Boolean isRunning = false;

Expand All @@ -63,6 +66,16 @@ public ODPEventManager(@Nonnull ODPApiManager apiManager, @Nullable Integer queu
this.batchSize = (flushInterval != null && flushInterval == 0) ? 1 : DEFAULT_BATCH_SIZE;
}

// these user-provided common data are included in all ODP events in addition to the SDK-generated common data.
public void setUserCommonData(@Nullable Map<String, Object> commonData) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks confusing, at line 42 and 43 there is a NonNull tag and here it is nullable. I think it should be NonNull to keep it consistent. Same goes for line 75.

if (commonData != null) this.userCommonData = commonData;
}

// these user-provided common identifiers are included in all ODP events in addition to the SDK-generated identifiers.
public void setUserCommonIdentifiers(@Nullable Map<String, String> commonIdentifiers) {
if (commonIdentifiers != null) this.userCommonIdentifiers = commonIdentifiers;
}

public void start() {
if (eventDispatcherThread == null) {
eventDispatcherThread = new EventDispatcherThread();
Expand Down Expand Up @@ -107,19 +120,35 @@ public void sendEvent(ODPEvent event) {
return;
}
event.setData(augmentCommonData(event.getData()));
event.setIdentifiers(augmentCommonIdentifiers(event.getIdentifiers()));
processEvent(event);
}

private Map<String, Object> augmentCommonData(Map<String, Object> sourceData) {
@VisibleForTesting
Map<String, Object> augmentCommonData(Map<String, Object> sourceData) {
// priority: sourceData > userCommonData > sdkCommonData

Map<String, Object> data = new HashMap<>();
data.put("idempotence_id", UUID.randomUUID().toString());
data.put("data_source_type", "sdk");
data.put("data_source", ClientEngineInfo.getClientEngine().getClientEngineValue());
data.put("data_source_version", BuildVersionInfo.getClientVersion());

data.putAll(userCommonData);
data.putAll(sourceData);
return data;
}

@VisibleForTesting
Map<String, String> augmentCommonIdentifiers(Map<String, String> sourceIdentifiers) {
// priority: sourceIdentifiers > userCommonIdentifiers

Map<String, String> identifiers = new HashMap<>();
identifiers.putAll(userCommonIdentifiers);
identifiers.putAll(sourceIdentifiers);
return identifiers;
}

private void processEvent(ODPEvent event) {
if (!isRunning) {
logger.warn("Failed to Process ODP Event. ODPEventManager is not running");
Expand Down
32 changes: 32 additions & 0 deletions core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class ODPManager implements AutoCloseable {
Expand Down Expand Up @@ -77,6 +79,8 @@ public static class Builder {
private Integer cacheSize;
private Integer cacheTimeoutSeconds;
private Cache<List<String>> cacheImpl;
private Map<String, Object> userCommonData;
private Map<String, String> userCommonIdentifiers;

/**
* Provide a custom {@link ODPManager} instance which makes http calls to fetch segments and send events.
Expand Down Expand Up @@ -156,6 +160,32 @@ public Builder withSegmentCache(Cache<List<String>> cacheImpl) {
return this;
}

/**
* Provide an optional group of user data that should be included in all ODP events.
*
* Note that this is in addition to the default data that is automatically included in all ODP events by this SDK (sdk-name, sdk-version, etc).
*
* @param commonData A key-value map of common user data.
* @return ODPManager builder
*/
public Builder withUserCommonData(@Nonnull Map<String, Object> commonData) {
this.userCommonData = commonData;
return this;
}

/**
* Provide an optional group of identifiers that should be included in all ODP events.
*
* Note that this is in addition to the identifiers that is automatically included in all ODP events by this SDK.
*
* @param commonIdentifiers A key-value map of common identifiers.
* @return ODPManager builder
*/
public Builder withUserCommonIdentifiers(@Nonnull Map<String, String> commonIdentifiers) {
this.userCommonIdentifiers = commonIdentifiers;
return this;
}

public ODPManager build() {
if ((segmentManager == null || eventManager == null) && apiManager == null) {
logger.warn("ApiManager instance is needed when using default EventManager or SegmentManager");
Expand All @@ -182,6 +212,8 @@ public ODPManager build() {
if (eventManager == null) {
eventManager = new ODPEventManager(apiManager);
}
eventManager.setUserCommonData(userCommonData);
eventManager.setUserCommonIdentifiers(userCommonIdentifiers);

return new ODPManager(segmentManager, eventManager);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/****************************************************************************
* Copyright 2020-2021, Optimizely, Inc. and contributors *
* Copyright 2020-2021, 2023, 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. *
Expand Down Expand Up @@ -63,6 +63,8 @@ public String getKey() {

/**
* @deprecated use {@link #getExperimentRules()} and {@link #getDeliveryRules()} instead
*
* @return a map of ExperimentKey to OptimizelyExperiment
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update header.

*/
@Deprecated
public Map<String, OptimizelyExperiment> getExperimentsMap() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import com.optimizely.ab.event.EventHandler;
import com.optimizely.ab.event.LogEvent;
import com.optimizely.ab.event.internal.BuildVersionInfo;
import com.optimizely.ab.event.internal.ClientEngineInfo;
import com.optimizely.ab.event.internal.payload.Event;
import com.optimizely.ab.event.internal.payload.EventBatch;
import com.optimizely.ab.odp.ODPEventManager;
import com.optimizely.ab.odp.ODPManager;
Expand Down Expand Up @@ -241,6 +243,10 @@ public void withClientInfo() throws Exception {
verify(eventHandler, timeout(5000)).dispatchEvent(argument.capture());
assertEquals(argument.getValue().getEventBatch().getClientName(), "android-sdk");
assertEquals(argument.getValue().getEventBatch().getClientVersion(), "1.2.3");

// restore the default values for other tests
ClientEngineInfo.setClientEngine(ClientEngineInfo.DEFAULT);
BuildVersionInfo.setClientVersion(BuildVersionInfo.VERSION);
}

@Test
Expand Down
Loading