From 6f7c8462f2ff879fa6f32900b9111e9088d7659a Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Tue, 10 Jan 2023 14:07:20 -0800 Subject: [PATCH 1/7] add support for android opd events --- .../java/com/optimizely/ab/odp/ODPEvent.java | 2 +- .../optimizely/ab/odp/ODPEventManager.java | 31 +++- .../com/optimizely/ab/odp/ODPManager.java | 31 ++++ .../ab/odp/ODPEventManagerTest.java | 151 ++++++++++++++++++ .../ab/odp/ODPManagerBuilderTest.java | 25 ++- 5 files changed, 235 insertions(+), 5 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java index a4dd37f2b..ccf55271b 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java @@ -26,7 +26,7 @@ public class ODPEvent { private String type; private String action; - private Map identifiers; + private Map identifiers; private Map data; public ODPEvent(@Nullable String type, @Nonnull String action, @Nullable Map identifiers, @Nullable Map data) { diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java index ae034fd68..81fe15eb5 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java @@ -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; @@ -38,6 +39,8 @@ public class ODPEventManager { private final int queueSize; private final int batchSize; private final int flushInterval; + @Nonnull private Map userCommonData = Collections.emptyMap(); + @Nonnull private Map userCommonIdentifiers = Collections.emptyMap(); private Boolean isRunning = false; @@ -63,6 +66,16 @@ public ODPEventManager(@Nonnull ODPApiManager apiManager, @Nullable Integer batc this.flushInterval = (flushInterval != null && flushInterval > 0) ? flushInterval : DEFAULT_FLUSH_INTERVAL; } + // these user-provided common data are included in all ODP events in addition to the SDK-generated common data. + public void setUserCommonData(@Nullable Map commonData) { + 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 commonIdentifiers) { + if (commonIdentifiers != null) this.userCommonIdentifiers = commonIdentifiers; + } + public void start() { if (eventDispatcherThread == null) { eventDispatcherThread = new EventDispatcherThread(); @@ -107,19 +120,35 @@ public void sendEvent(ODPEvent event) { return; } event.setData(augmentCommonData(event.getData())); + event.setIdentifiers(augmentCommonIdentifiers(event.getIdentifiers())); processEvent(event); } - private Map augmentCommonData(Map sourceData) { + @VisibleForTesting + Map augmentCommonData(Map sourceData) { + // priority: sourceData > userCommonData > sdkCommonData + Map 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 augmentCommonIdentifiers(Map sourceIdentifiers) { + // priority: sourceIdentifiers > userCommonIdentifiers + + Map 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"); diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java index 3e198a209..32a9e8557 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java @@ -22,6 +22,7 @@ import javax.annotation.Nonnull; import java.util.List; +import java.util.Map; import java.util.Set; public class ODPManager implements AutoCloseable { @@ -77,6 +78,8 @@ public static class Builder { private Integer cacheSize; private Integer cacheTimeoutSeconds; private Cache> cacheImpl; + private Map userCommonData; + private Map userCommonIdentifiers; /** * Provide a custom {@link ODPManager} instance which makes http calls to fetch segments and send events. @@ -156,6 +159,32 @@ public Builder withSegmentCache(Cache> 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 set of common user data. + * @return ODPManager builder + */ + public Builder withUserCommonData(@Nonnull Map 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 commonData A key-value set of common identifiers. + * @return ODPManager builder + */ + public Builder withUserCommonIdentifiers(@Nonnull Map 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"); @@ -182,6 +211,8 @@ public ODPManager build() { if (eventManager == null) { eventManager = new ODPEventManager(apiManager); } + eventManager.setUserCommonData(userCommonData); + eventManager.setUserCommonIdentifiers(userCommonIdentifiers); return new ODPManager(segmentManager, eventManager); } diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java index 17c489dd4..40f71fabe 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java @@ -255,6 +255,157 @@ public void validateEventData() { assertFalse(event.isDataValid()); } + @Test + public void validateAugmentCommonData() { + Map sourceData = new HashMap<>(); + sourceData.put("k1", "source-1"); + sourceData.put("k2", "source-2"); + Map userCommonData = new HashMap<>(); + userCommonData.put("k3", "common-1"); + userCommonData.put("k4", "common-2"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + eventManager.setUserCommonData(userCommonData); + + Map merged = eventManager.augmentCommonData(sourceData); + + // event-sourceData + assertEquals(merged.get("k1"), "source-1"); + assertEquals(merged.get("k2"), "source-2"); + // userCommonData + assertEquals(merged.get("k3"), "common-1"); + assertEquals(merged.get("k4"), "common-2"); + // sdk-generated common data + assertNotNull(merged.get("idempotence_id")); + assertEquals(merged.get("data_source_type"), "sdk"); + assertNotNull(merged.get("data_source")); + assertNotNull(merged.get("data_source_version")); + + assertEquals(merged.size(), 8); + } + + @Test + public void validateAugmentCommonData_keyConflicts1() { + Map sourceData = new HashMap<>(); + sourceData.put("k1", "source-1"); + sourceData.put("k2", "source-2"); + Map userCommonData = new HashMap<>(); + userCommonData.put("k1", "common-1"); + userCommonData.put("k2", "common-2"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + eventManager.setUserCommonData(userCommonData); + + Map merged = eventManager.augmentCommonData(sourceData); + + // event-sourceData overrides userCommonData + assertEquals(merged.get("k1"), "source-1"); + assertEquals(merged.get("k2"), "source-2"); + // sdk-generated common data + assertNotNull(merged.get("idempotence_id")); + assertEquals(merged.get("data_source_type"), "sdk"); + assertNotNull(merged.get("data_source")); + assertNotNull(merged.get("data_source_version")); + + assertEquals(merged.size(), 6); + } + + @Test + public void validateAugmentCommonData_keyConflicts2() { + Map sourceData = new HashMap<>(); + sourceData.put("data_source_type", "source-1"); + Map userCommonData = new HashMap<>(); + userCommonData.put("data_source_type", "common-1"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + eventManager.setUserCommonData(userCommonData); + + Map merged = eventManager.augmentCommonData(sourceData); + + // event-sourceData overrides userCommonData and sdk-generated common data + assertEquals(merged.get("data_source_type"), "source-1"); + // sdk-generated common data + assertNotNull(merged.get("idempotence_id")); + assertNotNull(merged.get("data_source")); + assertNotNull(merged.get("data_source_version")); + + assertEquals(merged.size(), 4); + } + + @Test + public void validateAugmentCommonData_keyConflicts3() { + Map sourceData = new HashMap<>(); + sourceData.put("k1", "source-1"); + Map userCommonData = new HashMap<>(); + userCommonData.put("data_source_type", "common-1"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + eventManager.setUserCommonData(userCommonData); + + Map merged = eventManager.augmentCommonData(sourceData); + + // userCommonData overrides sdk-generated common data + assertEquals(merged.get("data_source_type"), "common-1"); + assertEquals(merged.get("k1"), "source-1"); + // sdk-generated common data + assertNotNull(merged.get("idempotence_id")); + assertNotNull(merged.get("data_source")); + assertNotNull(merged.get("data_source_version")); + + assertEquals(merged.size(), 5); + } + + @Test + public void validateAugmentCommonIdentifiers() { + Map sourceIdentifiers = new HashMap<>(); + sourceIdentifiers.put("k1", "source-1"); + sourceIdentifiers.put("k2", "source-2"); + Map userCommonIdentifiers = new HashMap<>(); + userCommonIdentifiers.put("k3", "common-1"); + userCommonIdentifiers.put("k4", "common-2"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + eventManager.setUserCommonIdentifiers(userCommonIdentifiers); + + Map merged = eventManager.augmentCommonIdentifiers(sourceIdentifiers); + + // event-sourceIdentifiers + assertEquals(merged.get("k1"), "source-1"); + assertEquals(merged.get("k2"), "source-2"); + // userCommonIdentifiers + assertEquals(merged.get("k3"), "common-1"); + assertEquals(merged.get("k4"), "common-2"); + + assertEquals(merged.size(), 4); + } + + @Test + public void validateAugmentCommonIdentifiers_keyConflicts() { + Map sourceIdentifiers = new HashMap<>(); + sourceIdentifiers.put("k1", "source-1"); + sourceIdentifiers.put("k2", "source-2"); + Map userCommonIdentifiers = new HashMap<>(); + userCommonIdentifiers.put("k1", "common-1"); + userCommonIdentifiers.put("k2", "common-2"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + eventManager.setUserCommonIdentifiers(userCommonIdentifiers); + + Map merged = eventManager.augmentCommonIdentifiers(sourceIdentifiers); + + // event-sourceIdentifiers overrides userCommonIdentifiers + assertEquals(merged.get("k1"), "source-1"); + assertEquals(merged.get("k2"), "source-2"); + + assertEquals(merged.size(), 2); + } + private ODPEvent getEvent(int id) { Map identifiers = new HashMap<>(); identifiers.put("identifier1", "value1-" + id); diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java index 0f7f59ae9..fba1c1f0f 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java @@ -19,9 +19,7 @@ import com.optimizely.ab.internal.Cache; import org.junit.Test; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; +import java.util.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; @@ -73,4 +71,25 @@ public void withSegmentCache() { odpManager.getSegmentManager().getQualifiedSegments("test-user"); verify(mockCache).lookup("fs_user_id-$-test-user"); } + + @Test + public void withUserCommonDataAndCommonIdentifiers() { + Map data = new HashMap<>(); + data.put("k1", "v1"); + Map identifiers = new HashMap<>(); + identifiers.put("k2", "v2"); + + ODPEventManager mockEventManager = mock(ODPEventManager.class); + ODPSegmentManager mockSegmentManager = mock(ODPSegmentManager.class); + ODPManager odpManager = ODPManager.builder() + .withUserCommonData(data) + .withUserCommonIdentifiers(identifiers) + .withEventManager(mockEventManager) + .withSegmentManager(mockSegmentManager) + .build(); + + verify(mockEventManager).setUserCommonData(eq(data)); + verify(mockEventManager).setUserCommonIdentifiers(eq(identifiers)); + } + } From ef5dfca6026ce18ee70cfc081abcbfb19e8948ec Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Wed, 11 Jan 2023 11:14:10 -0800 Subject: [PATCH 2/7] fix a lint --- .../test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java index fba1c1f0f..466886fea 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java @@ -81,7 +81,7 @@ public void withUserCommonDataAndCommonIdentifiers() { ODPEventManager mockEventManager = mock(ODPEventManager.class); ODPSegmentManager mockSegmentManager = mock(ODPSegmentManager.class); - ODPManager odpManager = ODPManager.builder() + ODPManager.builder() .withUserCommonData(data) .withUserCommonIdentifiers(identifiers) .withEventManager(mockEventManager) From 30c44046d8bada58cb9e624bec0f677f61fcd5ee Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Wed, 11 Jan 2023 12:37:47 -0800 Subject: [PATCH 3/7] fix doc format errors --- .../main/java/com/optimizely/ab/OptimizelyUserContext.java | 4 ++++ core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java | 4 ++-- .../com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java | 2 ++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/OptimizelyUserContext.java b/core-api/src/main/java/com/optimizely/ab/OptimizelyUserContext.java index 7cb8753f4..e2c03b147 100644 --- a/core-api/src/main/java/com/optimizely/ab/OptimizelyUserContext.java +++ b/core-api/src/main/java/com/optimizely/ab/OptimizelyUserContext.java @@ -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; @@ -313,6 +314,8 @@ public void setQualifiedSegments(List qualifiedSegments) { * Fetch all qualified segments for the user context. *

* 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()); @@ -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 segmentOptions) { List segments = optimizely.fetchQualifiedSegments(userId, segmentOptions); diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java index 32a9e8557..38057e903 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java @@ -164,7 +164,7 @@ public Builder withSegmentCache(Cache> cacheImpl) { * * 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 set of common user data. + * @param commonData A key-value map of common user data. * @return ODPManager builder */ public Builder withUserCommonData(@Nonnull Map commonData) { @@ -177,7 +177,7 @@ public Builder withUserCommonData(@Nonnull Map commonData) { * * Note that this is in addition to the identifiers that is automatically included in all ODP events by this SDK. * - * @param commonData A key-value set of common identifiers. + * @param commonIdentifiers A key-value map of common identifiers. * @return ODPManager builder */ public Builder withUserCommonIdentifiers(@Nonnull Map commonIdentifiers) { diff --git a/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java b/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java index 77a1f67fd..bd377fdb4 100644 --- a/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java +++ b/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java @@ -63,6 +63,8 @@ public String getKey() { /** * @deprecated use {@link #getExperimentRules()} and {@link #getDeliveryRules()} instead + * + * @return a map of ExperimentKey to OptimizelyExperiment */ @Deprecated public Map getExperimentsMap() { From 4d553acab1417a20635ab5f593ef15b25e106c2f Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Thu, 12 Jan 2023 10:27:31 -0800 Subject: [PATCH 4/7] fix per reviews --- .../java/com/optimizely/ab/odp/ODPEvent.java | 2 +- .../optimizely/ab/odp/ODPEventManager.java | 8 ++-- .../com/optimizely/ab/odp/ODPManager.java | 5 ++- .../optimizelyconfig/OptimizelyFeature.java | 2 +- .../ab/odp/ODPEventManagerTest.java | 40 ++++++++++++++++--- .../ab/odp/ODPManagerBuilderTest.java | 2 +- 6 files changed, 45 insertions(+), 14 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java index ccf55271b..2ed2c1e76 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java @@ -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. diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java index 81fe15eb5..764f3cbb6 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java @@ -67,13 +67,13 @@ public ODPEventManager(@Nonnull ODPApiManager apiManager, @Nullable Integer batc } // these user-provided common data are included in all ODP events in addition to the SDK-generated common data. - public void setUserCommonData(@Nullable Map commonData) { - if (commonData != null) this.userCommonData = commonData; + public void setUserCommonData(@Nonnull Map commonData) { + 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 commonIdentifiers) { - if (commonIdentifiers != null) this.userCommonIdentifiers = commonIdentifiers; + public void setUserCommonIdentifiers(@Nonnull Map commonIdentifiers) { + this.userCommonIdentifiers = commonIdentifiers; } public void start() { diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java index 38057e903..fe369c758 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java @@ -21,6 +21,7 @@ import org.slf4j.LoggerFactory; import javax.annotation.Nonnull; +import java.util.Collections; import java.util.List; import java.util.Map; import java.util.Set; @@ -211,8 +212,8 @@ public ODPManager build() { if (eventManager == null) { eventManager = new ODPEventManager(apiManager); } - eventManager.setUserCommonData(userCommonData); - eventManager.setUserCommonIdentifiers(userCommonIdentifiers); + eventManager.setUserCommonData(userCommonData != null ? userCommonData : Collections.emptyMap()); + eventManager.setUserCommonIdentifiers(userCommonIdentifiers != null ? userCommonIdentifiers : Collections.emptyMap()); return new ODPManager(segmentManager, eventManager); } diff --git a/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java b/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java index bd377fdb4..7dec828a6 100644 --- a/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java +++ b/core-api/src/main/java/com/optimizely/ab/optimizelyconfig/OptimizelyFeature.java @@ -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. * diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java index 40f71fabe..a76287491 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2022, Optimizely + * Copyright 2022-2023, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,9 @@ package com.optimizely.ab.odp; import ch.qos.logback.classic.Level; +import com.optimizely.ab.event.internal.BuildVersionInfo; +import com.optimizely.ab.event.internal.ClientEngineInfo; +import com.optimizely.ab.event.internal.payload.EventBatch; import com.optimizely.ab.internal.LogbackVerifier; import org.json.JSONArray; import org.json.JSONObject; @@ -30,10 +33,7 @@ import org.mockito.Mockito; import org.mockito.runners.MockitoJUnitRunner; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; @@ -255,6 +255,36 @@ public void validateEventData() { assertFalse(event.isDataValid()); } + @Test + public void validateEventCommonData() { + Map sourceData = new HashMap<>(); + sourceData.put("k1", "v1"); + + Mockito.reset(mockApiManager); + ODPEventManager eventManager = new ODPEventManager(mockApiManager); + Map merged = eventManager.augmentCommonData(sourceData); + + assertEquals(merged.get("k1"), "v1"); + assertTrue(merged.get("idempotence_id").toString().length() > 16); + assertEquals(merged.get("data_source_type"), "sdk"); + assertEquals(merged.get("data_source"), "java-sdk"); + assertTrue(merged.get("data_source_version").toString().length() > 0); + assertEquals(merged.size(), 5); + + // when clientInfo is overriden (android-sdk): + + ClientEngineInfo.setClientEngine(EventBatch.ClientEngine.ANDROID_SDK); + BuildVersionInfo.setClientVersion("1.2.3"); + merged = eventManager.augmentCommonData(sourceData); + + assertEquals(merged.get("k1"), "v1"); + assertTrue(merged.get("idempotence_id").toString().length() > 16); + assertEquals(merged.get("data_source_type"), "sdk"); + assertEquals(merged.get("data_source"), "android-sdk"); + assertEquals(merged.get("data_source_version"), "1.2.3"); + assertEquals(merged.size(), 5); + } + @Test public void validateAugmentCommonData() { Map sourceData = new HashMap<>(); diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java index 466886fea..0dcc9104a 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerBuilderTest.java @@ -1,6 +1,6 @@ /** * - * Copyright 2022, Optimizely + * Copyright 2022-2023, Optimizely * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. From 73fa3663504a8900e631da4fb22ee2ded7bac221 Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Thu, 12 Jan 2023 11:58:58 -0800 Subject: [PATCH 5/7] clean up tests --- .../java/com/optimizely/ab/odp/ODPEventManagerTest.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java index a76287491..e3907bc13 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java @@ -271,8 +271,8 @@ public void validateEventCommonData() { assertTrue(merged.get("data_source_version").toString().length() > 0); assertEquals(merged.size(), 5); - // when clientInfo is overriden (android-sdk): - + // when clientInfo is overridden (android-sdk): + ClientEngineInfo.setClientEngine(EventBatch.ClientEngine.ANDROID_SDK); BuildVersionInfo.setClientVersion("1.2.3"); merged = eventManager.augmentCommonData(sourceData); @@ -283,6 +283,9 @@ public void validateEventCommonData() { assertEquals(merged.get("data_source"), "android-sdk"); assertEquals(merged.get("data_source_version"), "1.2.3"); assertEquals(merged.size(), 5); + + // restore the default value for other tests + ClientEngineInfo.setClientEngine(ClientEngineInfo.DEFAULT); } @Test From e7d4f272a30d0d149f32529ccb2bd87976d678da Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Thu, 12 Jan 2023 12:17:38 -0800 Subject: [PATCH 6/7] clean up tests --- .../test/java/com/optimizely/ab/OptimizelyBuilderTest.java | 6 ++++++ .../java/com/optimizely/ab/odp/ODPEventManagerTest.java | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core-api/src/test/java/com/optimizely/ab/OptimizelyBuilderTest.java b/core-api/src/test/java/com/optimizely/ab/OptimizelyBuilderTest.java index 79382a5b7..566eec635 100644 --- a/core-api/src/test/java/com/optimizely/ab/OptimizelyBuilderTest.java +++ b/core-api/src/test/java/com/optimizely/ab/OptimizelyBuilderTest.java @@ -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; @@ -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 diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java index e3907bc13..519386d3e 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPEventManagerTest.java @@ -284,8 +284,9 @@ public void validateEventCommonData() { assertEquals(merged.get("data_source_version"), "1.2.3"); assertEquals(merged.size(), 5); - // restore the default value for other tests + // restore the default values for other tests ClientEngineInfo.setClientEngine(ClientEngineInfo.DEFAULT); + BuildVersionInfo.setClientVersion(BuildVersionInfo.VERSION); } @Test From b6d7e750b39a07ab05dada829188836d502ca9be Mon Sep 17 00:00:00 2001 From: Jae Kim Date: Tue, 17 Jan 2023 08:58:01 -0800 Subject: [PATCH 7/7] fix per review --- .../main/java/com/optimizely/ab/odp/ODPEventManager.java | 8 ++++---- .../src/main/java/com/optimizely/ab/odp/ODPManager.java | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java index 764f3cbb6..81fe15eb5 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java @@ -67,13 +67,13 @@ public ODPEventManager(@Nonnull ODPApiManager apiManager, @Nullable Integer batc } // these user-provided common data are included in all ODP events in addition to the SDK-generated common data. - public void setUserCommonData(@Nonnull Map commonData) { - this.userCommonData = commonData; + public void setUserCommonData(@Nullable Map commonData) { + 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(@Nonnull Map commonIdentifiers) { - this.userCommonIdentifiers = commonIdentifiers; + public void setUserCommonIdentifiers(@Nullable Map commonIdentifiers) { + if (commonIdentifiers != null) this.userCommonIdentifiers = commonIdentifiers; } public void start() { diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java index fe369c758..cacbcad0d 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPManager.java @@ -212,8 +212,8 @@ public ODPManager build() { if (eventManager == null) { eventManager = new ODPEventManager(apiManager); } - eventManager.setUserCommonData(userCommonData != null ? userCommonData : Collections.emptyMap()); - eventManager.setUserCommonIdentifiers(userCommonIdentifiers != null ? userCommonIdentifiers : Collections.emptyMap()); + eventManager.setUserCommonData(userCommonData); + eventManager.setUserCommonIdentifiers(userCommonIdentifiers); return new ODPManager(segmentManager, eventManager); }