From 59c9246a02388a23d9e65475dd7fb640813d3143 Mon Sep 17 00:00:00 2001 From: mnoman09 Date: Fri, 27 Jan 2023 20:43:25 +0500 Subject: [PATCH 1/7] Changed accessor of augmentCommonData and augmentCommonIdentifiers so that it can be accessable in customODPEventManager --- .../src/main/java/com/optimizely/ab/odp/ODPEventManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 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 fbd39ffaf..091a08dc1 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 @@ -125,7 +125,7 @@ public void sendEvent(ODPEvent event) { } @VisibleForTesting - Map augmentCommonData(Map sourceData) { + protected Map augmentCommonData(Map sourceData) { // priority: sourceData > userCommonData > sdkCommonData Map data = new HashMap<>(); @@ -140,7 +140,7 @@ Map augmentCommonData(Map sourceData) { } @VisibleForTesting - Map augmentCommonIdentifiers(Map sourceIdentifiers) { + protected Map augmentCommonIdentifiers(Map sourceIdentifiers) { // priority: sourceIdentifiers > userCommonIdentifiers Map identifiers = new HashMap<>(); From 060ff794cc07bdff5c37d222b05315c21381f3db Mon Sep 17 00:00:00 2001 From: mnoman09 Date: Wed, 1 Feb 2023 15:08:04 +0500 Subject: [PATCH 2/7] Moved parsing of fetchSegment http response inside DefaultODPAPiManager and returing list of string means segments --- .../com/optimizely/ab/odp/ODPApiManager.java | 3 +- .../optimizely/ab/odp/ODPSegmentManager.java | 11 +------ .../com/optimizely/ab/odp/ODPManagerTest.java | 3 +- .../ab/odp/ODPSegmentManagerTest.java | 2 +- .../ab/odp/DefaultODPApiManager.java | 29 +++++++------------ .../ab/odp/DefaultODPApiManagerTest.java | 14 +++++---- 6 files changed, 25 insertions(+), 37 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java index 6385d2b7b..dc2cbcf4d 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java @@ -15,10 +15,11 @@ */ package com.optimizely.ab.odp; +import java.util.List; import java.util.Set; public interface ODPApiManager { - String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, Set segmentsToCheck); + List fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, Set segmentsToCheck); Integer sendEvents(String apiKey, String apiEndpoint, String eventPayload); } diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java index 90a36fa5d..99ff2e232 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java @@ -89,16 +89,7 @@ public List getQualifiedSegments(ODPUserKey userKey, String userValue, L logger.debug("ODP Cache Miss. Making a call to ODP Server."); - ResponseJsonParser parser = ResponseJsonParserFactory.getParser(); - String qualifiedSegmentsResponse = apiManager.fetchQualifiedSegments(odpConfig.getApiKey(), odpConfig.getApiHost() + SEGMENT_URL_PATH, userKey.getKeyString(), userValue, odpConfig.getAllSegments()); - try { - qualifiedSegments = parser.parseQualifiedSegments(qualifiedSegmentsResponse); - } catch (Exception e) { - logger.error("Audience segments fetch failed (Error Parsing Response)"); - logger.debug(e.getMessage()); - qualifiedSegments = null; - } - + qualifiedSegments = apiManager.fetchQualifiedSegments(odpConfig.getApiKey(), odpConfig.getApiHost() + SEGMENT_URL_PATH, userKey.getKeyString(), userValue, odpConfig.getAllSegments()); if (qualifiedSegments != null && !options.contains(ODPSegmentOption.IGNORE_CACHE)) { segmentsCache.save(cacheKey, qualifiedSegments); } diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java index 02abe88a1..feac3bc44 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java @@ -24,13 +24,14 @@ import java.util.Arrays; import java.util.Collections; import java.util.HashSet; +import java.util.List; import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; import static org.junit.Assert.*; public class ODPManagerTest { - private static final String API_RESPONSE = "{\"data\":{\"customer\":{\"audiences\":{\"edges\":[{\"node\":{\"name\":\"segment1\",\"state\":\"qualified\"}},{\"node\":{\"name\":\"segment2\",\"state\":\"qualified\"}}]}}}}"; + private static final List API_RESPONSE = Arrays.asList(new String[]{"segment1", "segment2"}); @Mock ODPApiManager mockApiManager; diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java index 4d34d49b9..cc207515d 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java @@ -43,7 +43,7 @@ public class ODPSegmentManagerTest { @Mock ODPApiManager mockApiManager; - private static final String API_RESPONSE = "{\"data\":{\"customer\":{\"audiences\":{\"edges\":[{\"node\":{\"name\":\"segment1\",\"state\":\"qualified\"}},{\"node\":{\"name\":\"segment2\",\"state\":\"qualified\"}}]}}}}"; + private static final List API_RESPONSE = Arrays.asList(new String[]{"segment1", "segment2"}); @Before public void setup() { diff --git a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java index 636ed8eec..a5a14b0e5 100644 --- a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java +++ b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java @@ -17,6 +17,8 @@ import com.optimizely.ab.OptimizelyHttpClient; import com.optimizely.ab.annotations.VisibleForTesting; +import com.optimizely.ab.odp.parser.ResponseJsonParser; +import com.optimizely.ab.odp.parser.ResponseJsonParserFactory; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; @@ -28,6 +30,7 @@ import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.Iterator; +import java.util.List; import java.util.Set; public class DefaultODPApiManager implements ODPApiManager { @@ -144,7 +147,7 @@ String getSegmentsStringForRequest(Set segmentsList) { } */ @Override - public String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, Set segmentsToCheck) { + public List fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, Set segmentsToCheck) { HttpPost request = new HttpPost(apiEndpoint); String segmentsString = getSegmentsStringForRequest(segmentsToCheck); @@ -174,12 +177,15 @@ public String fetchQualifiedSegments(String apiKey, String apiEndpoint, String u closeHttpResponse(response); return null; } - + ResponseJsonParser parser = ResponseJsonParserFactory.getParser(); try { - return EntityUtils.toString(response.getEntity()); + return parser.parseQualifiedSegments(EntityUtils.toString(response.getEntity())); } catch (IOException e) { logger.error("Error converting ODP segments response to string", e); - } finally { + } catch (Exception e) { + logger.error("Audience segments fetch failed (Error Parsing Response)"); + logger.debug(e.getMessage()); + }finally { closeHttpResponse(response); } return null; @@ -187,20 +193,7 @@ public String fetchQualifiedSegments(String apiKey, String apiEndpoint, String u /* eventPayload Format - [ - { - "action": "identified", - "identifiers": {"vuid": , "fs_user_id": , ....}, - "data": {“source”: , ....}, - "type": " fullstack " - }, - { - "action": "client_initialized", - "identifiers": {"vuid": , ....}, - "data": {“source”: , ....}, - "type": "fullstack" - } - ] + Returns: 1. null, When there was a non-recoverable error and no retry is needed. diff --git a/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java b/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java index 93b728fba..5bdbbcba8 100644 --- a/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java +++ b/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java @@ -30,13 +30,15 @@ import java.util.Arrays; import java.util.HashSet; +import java.util.List; import static org.junit.Assert.*; import static org.mockito.Matchers.any; import static org.mockito.Mockito.*; public class DefaultODPApiManagerTest { - private static final String validResponse = "{\"data\":{\"customer\":{\"audiences\":{\"edges\":[{\"node\":{\"name\":\"has_email\",\"state\":\"qualified\"}},{\"node\":{\"name\":\"has_email_opted_in\",\"state\":\"qualified\"}}]}}}}"; + private static final List validResponse = Arrays.asList(new String[]{"has_email", "has_email_opted_in"}); + private static final String validRequestResponse = "{\"data\":{\"customer\":{\"audiences\":{\"edges\":[{\"node\":{\"name\":\"has_email\",\"state\":\"qualified\"}},{\"node\":{\"name\":\"has_email_opted_in\",\"state\":\"qualified\"}}]}}}}"; @Rule public LogbackVerifier logbackVerifier = new LogbackVerifier(); @@ -55,7 +57,7 @@ private void setupHttpClient(int statusCode) throws Exception { when(statusLine.getStatusCode()).thenReturn(statusCode); when(httpResponse.getStatusLine()).thenReturn(statusLine); - when(httpResponse.getEntity()).thenReturn(new StringEntity(validResponse)); + when(httpResponse.getEntity()).thenReturn(new StringEntity(validRequestResponse)); when(mockHttpClient.execute(any(HttpPost.class))) .thenReturn(httpResponse); @@ -99,19 +101,19 @@ public void generateCorrectRequestBody() throws Exception { @Test public void returnResponseStringWhenStatusIs200() throws Exception { ODPApiManager apiManager = new DefaultODPApiManager(mockHttpClient); - String responseString = apiManager.fetchQualifiedSegments("key", "endPoint", "fs_user_id", "test_user", new HashSet<>(Arrays.asList("segment_1", "segment_2"))); + List response = apiManager.fetchQualifiedSegments("key", "endPoint", "fs_user_id", "test_user", new HashSet<>(Arrays.asList("segment_1", "segment_2"))); verify(mockHttpClient, times(1)).execute(any(HttpPost.class)); - assertEquals(validResponse, responseString); + assertEquals(validResponse, response); } @Test public void returnNullWhenStatusIsNot200AndLogError() throws Exception { setupHttpClient(500); ODPApiManager apiManager = new DefaultODPApiManager(mockHttpClient); - String responseString = apiManager.fetchQualifiedSegments("key", "endPoint", "fs_user_id", "test_user", new HashSet<>(Arrays.asList("segment_1", "segment_2"))); + List response = apiManager.fetchQualifiedSegments("key", "endPoint", "fs_user_id", "test_user", new HashSet<>(Arrays.asList("segment_1", "segment_2"))); verify(mockHttpClient, times(1)).execute(any(HttpPost.class)); logbackVerifier.expectMessage(Level.ERROR, "Unexpected response from ODP server, Response code: 500, null"); - assertNull(responseString); + assertNull(response); } @Test From 477f02d831c13de39a111949f044d777c07f5cff Mon Sep 17 00:00:00 2001 From: mnoman09 Date: Wed, 1 Feb 2023 15:21:16 +0500 Subject: [PATCH 3/7] nit fix --- .../main/java/com/optimizely/ab/odp/DefaultODPApiManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java index a5a14b0e5..dc139642a 100644 --- a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java +++ b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java @@ -185,7 +185,7 @@ public List fetchQualifiedSegments(String apiKey, String apiEndpoint, St } catch (Exception e) { logger.error("Audience segments fetch failed (Error Parsing Response)"); logger.debug(e.getMessage()); - }finally { + } finally { closeHttpResponse(response); } return null; From bdca9be994f9171965723b7b9e48d576e6e0bbd7 Mon Sep 17 00:00:00 2001 From: mnoman09 Date: Thu, 2 Feb 2023 19:23:53 +0500 Subject: [PATCH 4/7] Header fixes --- .../src/main/java/com/optimizely/ab/odp/ODPApiManager.java | 2 +- .../main/java/com/optimizely/ab/odp/ODPSegmentManager.java | 2 +- .../src/test/java/com/optimizely/ab/odp/ODPManagerTest.java | 2 +- .../java/com/optimizely/ab/odp/ODPSegmentManagerTest.java | 2 +- .../main/java/com/optimizely/ab/odp/DefaultODPApiManager.java | 2 +- .../java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java index dc2cbcf4d..b45bd937f 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPApiManager.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/ODPSegmentManager.java b/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java index 99ff2e232..275c45ee1 100644 --- a/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.java +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPSegmentManager.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. diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java index feac3bc44..9673bfa69 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPManagerTest.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. diff --git a/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java index cc207515d..2e6aa611e 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/ODPSegmentManagerTest.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. diff --git a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java index dc139642a..cb8675a0b 100644 --- a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java +++ b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.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-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java b/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java index 5bdbbcba8..a268cacc7 100644 --- a/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.java +++ b/core-httpclient-impl/src/test/java/com/optimizely/ab/odp/DefaultODPApiManagerTest.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. @@ -37,7 +37,7 @@ import static org.mockito.Mockito.*; public class DefaultODPApiManagerTest { - private static final List validResponse = Arrays.asList(new String[]{"has_email", "has_email_opted_in"}); + private static final List validResponse = Arrays.asList(new String[] {"has_email", "has_email_opted_in"}); private static final String validRequestResponse = "{\"data\":{\"customer\":{\"audiences\":{\"edges\":[{\"node\":{\"name\":\"has_email\",\"state\":\"qualified\"}},{\"node\":{\"name\":\"has_email_opted_in\",\"state\":\"qualified\"}}]}}}}"; @Rule From 726abf44396fa6d7f5e44d8e28ca7363dfe4821c Mon Sep 17 00:00:00 2001 From: mnoman09 Date: Thu, 2 Feb 2023 19:25:11 +0500 Subject: [PATCH 5/7] revert change --- .../optimizely/ab/odp/DefaultODPApiManager.java | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java index cb8675a0b..040709d39 100644 --- a/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java +++ b/core-httpclient-impl/src/main/java/com/optimizely/ab/odp/DefaultODPApiManager.java @@ -193,8 +193,20 @@ public List fetchQualifiedSegments(String apiKey, String apiEndpoint, St /* eventPayload Format - - + [ + { + "action": "identified", + "identifiers": {"vuid": , "fs_user_id": , ....}, + "data": {“source”: , ....}, + "type": " fullstack " + }, + { + "action": "client_initialized", + "identifiers": {"vuid": , ....}, + "data": {“source”: , ....}, + "type": "fullstack" + } + ] Returns: 1. null, When there was a non-recoverable error and no retry is needed. 2. 0 If an unexpected error occurred and retrying can be useful. From 4fc92081a615af3bc41657422db22035d8776afa Mon Sep 17 00:00:00 2001 From: mnoman09 Date: Mon, 6 Feb 2023 19:37:59 +0500 Subject: [PATCH 6/7] Added isVuid check --- .../main/java/com/optimizely/ab/odp/ODPEventManager.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) 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 091a08dc1..dab92c52a 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 @@ -107,7 +107,7 @@ public void identifyUser(@Nullable String vuid, @Nullable String userId) { if (vuid != null) { identifiers.put(ODPUserKey.VUID.getKeyString(), vuid); } - if (userId != null) { + if (userId != null && !isVuid(userId)) { identifiers.put(ODPUserKey.FS_USER_ID.getKeyString(), userId); } ODPEvent event = new ODPEvent("fullstack", "identified", identifiers, null); @@ -149,6 +149,10 @@ protected Map augmentCommonIdentifiers(Map sourc return identifiers; } + private boolean isVuid(String userId) { + return userId.startsWith("vuid_"); + } + private void processEvent(ODPEvent event) { if (!isRunning) { logger.warn("Failed to Process ODP Event. ODPEventManager is not running"); From bb39ff287be5fa382a5e0b4d33a893fef9443cdb Mon Sep 17 00:00:00 2001 From: Muhammad Noman Date: Wed, 8 Feb 2023 00:52:01 +0500 Subject: [PATCH 7/7] Update core-api/src/main/java/com/optimizely/ab/odp/ODPEventManager.java Co-authored-by: Jae Kim <45045038+jaeopt@users.noreply.github.com> --- .../main/java/com/optimizely/ab/odp/ODPEventManager.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 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 dab92c52a..ce218ed9d 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 @@ -107,8 +107,12 @@ public void identifyUser(@Nullable String vuid, @Nullable String userId) { if (vuid != null) { identifiers.put(ODPUserKey.VUID.getKeyString(), vuid); } - if (userId != null && !isVuid(userId)) { - identifiers.put(ODPUserKey.FS_USER_ID.getKeyString(), userId); + if (userId != null) { + if (isVuid(userId)) { + identifiers.put(ODPUserKey.VUID.getKeyString(), userId); + } else { + identifiers.put(ODPUserKey.FS_USER_ID.getKeyString(), userId); + } } ODPEvent event = new ODPEvent("fullstack", "identified", identifiers, null); sendEvent(event);