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 ed40e37f..dee9413d 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 @@ -19,4 +19,6 @@ public interface ODPApiManager { String fetchQualifiedSegments(String apiKey, String apiEndpoint, String userKey, String userValue, List segmentsToCheck); + + Integer sendEvents(String apiKey, String apiEndpoint, String eventPayload); } 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 new file mode 100644 index 00000000..34bd340b --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/ODPEvent.java @@ -0,0 +1,64 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp; + +import java.util.Map; + +public class ODPEvent { + private String type; + private String action; + private Map identifiers; + private Map data; + + public ODPEvent(String type, String action, Map identifiers, Map data) { + this.type = type; + this.action = action; + this.identifiers = identifiers; + this.data = data; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getAction() { + return action; + } + + public void setAction(String action) { + this.action = action; + } + + public Map getIdentifiers() { + return identifiers; + } + + public void setIdentifiers(Map identifiers) { + this.identifiers = identifiers; + } + + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } +} diff --git a/core-api/src/main/java/com/optimizely/ab/odp/serializer/ODPJsonSerializer.java b/core-api/src/main/java/com/optimizely/ab/odp/serializer/ODPJsonSerializer.java new file mode 100644 index 00000000..4f392234 --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/serializer/ODPJsonSerializer.java @@ -0,0 +1,24 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer; + +import com.optimizely.ab.odp.ODPEvent; + +import java.util.List; + +public interface ODPJsonSerializer { + public String serializeEvents(List events); +} diff --git a/core-api/src/main/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerFactory.java b/core-api/src/main/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerFactory.java new file mode 100644 index 00000000..ca47e3bf --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerFactory.java @@ -0,0 +1,49 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer; + +import com.optimizely.ab.internal.JsonParserProvider; +import com.optimizely.ab.odp.serializer.impl.GsonSerializer; +import com.optimizely.ab.odp.serializer.impl.JacksonSerializer; +import com.optimizely.ab.odp.serializer.impl.JsonSerializer; +import com.optimizely.ab.odp.serializer.impl.JsonSimpleSerializer; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class ODPJsonSerializerFactory { + private static final Logger logger = LoggerFactory.getLogger(ODPJsonSerializerFactory.class); + + public static ODPJsonSerializer getSerializer() { + JsonParserProvider parserProvider = JsonParserProvider.getDefaultParser(); + ODPJsonSerializer jsonSerializer = null; + switch (parserProvider) { + case GSON_CONFIG_PARSER: + jsonSerializer = new GsonSerializer(); + break; + case JACKSON_CONFIG_PARSER: + jsonSerializer = new JacksonSerializer(); + break; + case JSON_CONFIG_PARSER: + jsonSerializer = new JsonSerializer(); + break; + case JSON_SIMPLE_CONFIG_PARSER: + jsonSerializer = new JsonSimpleSerializer(); + break; + } + logger.info("Using " + parserProvider.toString() + " serializer"); + return jsonSerializer; + } +} diff --git a/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/GsonSerializer.java b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/GsonSerializer.java new file mode 100644 index 00000000..d7296326 --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/GsonSerializer.java @@ -0,0 +1,31 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer.impl; + +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.optimizely.ab.odp.ODPEvent; +import com.optimizely.ab.odp.serializer.ODPJsonSerializer; + +import java.util.List; + +public class GsonSerializer implements ODPJsonSerializer { + @Override + public String serializeEvents(List events) { + Gson gson = new GsonBuilder().serializeNulls().create(); + return gson.toJson(events); + } +} diff --git a/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JacksonSerializer.java b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JacksonSerializer.java new file mode 100644 index 00000000..80cffa7d --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JacksonSerializer.java @@ -0,0 +1,36 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer.impl; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.optimizely.ab.odp.ODPEvent; +import com.optimizely.ab.odp.serializer.ODPJsonSerializer; + +import java.util.List; + +public class JacksonSerializer implements ODPJsonSerializer { + @Override + public String serializeEvents(List events) { + ObjectMapper objectMapper = new ObjectMapper(); + try { + return objectMapper.writeValueAsString(events); + } catch (JsonProcessingException e) { + // log error here + } + return null; + } +} diff --git a/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JsonSerializer.java b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JsonSerializer.java new file mode 100644 index 00000000..c65c1fda --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JsonSerializer.java @@ -0,0 +1,59 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer.impl; + +import com.optimizely.ab.odp.ODPEvent; +import com.optimizely.ab.odp.serializer.ODPJsonSerializer; +import org.json.JSONArray; +import org.json.JSONObject; + +import java.util.List; +import java.util.Map; + +public class JsonSerializer implements ODPJsonSerializer { + @Override + public String serializeEvents(List events) { + JSONArray jsonArray = new JSONArray(); + for (ODPEvent event: events) { + JSONObject eventObject = new JSONObject(); + eventObject.put("type", event.getType()); + eventObject.put("action", event.getAction()); + + if (event.getIdentifiers() != null) { + JSONObject identifiers = new JSONObject(); + for (Map.Entry identifier : event.getIdentifiers().entrySet()) { + identifiers.put(identifier.getKey(), identifier.getValue()); + } + eventObject.put("identifiers", identifiers); + } + + if (event.getData() != null) { + JSONObject data = new JSONObject(); + for (Map.Entry dataEntry : event.getData().entrySet()) { + data.put(dataEntry.getKey(), getJSONObjectValue(dataEntry.getValue())); + } + eventObject.put("data", data); + } + + jsonArray.put(eventObject); + } + return jsonArray.toString(); + } + + private static Object getJSONObjectValue(Object value) { + return value == null ? JSONObject.NULL : value; + } +} diff --git a/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JsonSimpleSerializer.java b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JsonSimpleSerializer.java new file mode 100644 index 00000000..96e5a735 --- /dev/null +++ b/core-api/src/main/java/com/optimizely/ab/odp/serializer/impl/JsonSimpleSerializer.java @@ -0,0 +1,55 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer.impl; + +import com.optimizely.ab.odp.ODPEvent; +import com.optimizely.ab.odp.serializer.ODPJsonSerializer; +import org.json.simple.JSONArray; +import org.json.simple.JSONObject; + +import java.util.List; +import java.util.Map; + +public class JsonSimpleSerializer implements ODPJsonSerializer { + @Override + public String serializeEvents(List events) { + JSONArray jsonArray = new JSONArray(); + for (ODPEvent event: events) { + JSONObject eventObject = new JSONObject(); + eventObject.put("type", event.getType()); + eventObject.put("action", event.getAction()); + + if (event.getIdentifiers() != null) { + JSONObject identifiers = new JSONObject(); + for (Map.Entry identifier : event.getIdentifiers().entrySet()) { + identifiers.put(identifier.getKey(), identifier.getValue()); + } + eventObject.put("identifiers", identifiers); + } + + if (event.getData() != null) { + JSONObject data = new JSONObject(); + for (Map.Entry dataEntry : event.getData().entrySet()) { + data.put(dataEntry.getKey(), dataEntry.getValue()); + } + eventObject.put("data", data); + } + + jsonArray.add(eventObject); + } + return jsonArray.toJSONString(); + } +} diff --git a/core-api/src/test/java/com/optimizely/ab/odp/parser/ResponseJsonParserFactoryTest.java b/core-api/src/test/java/com/optimizely/ab/odp/parser/ResponseJsonParserFactoryTest.java index f5d8e8c8..a4f51a3a 100644 --- a/core-api/src/test/java/com/optimizely/ab/odp/parser/ResponseJsonParserFactoryTest.java +++ b/core-api/src/test/java/com/optimizely/ab/odp/parser/ResponseJsonParserFactoryTest.java @@ -15,7 +15,6 @@ */ package com.optimizely.ab.odp.parser; -import com.optimizely.ab.internal.JsonParserProvider; import com.optimizely.ab.internal.PropertyUtils; import com.optimizely.ab.odp.parser.impl.GsonParser; import com.optimizely.ab.odp.parser.impl.JsonParser; diff --git a/core-api/src/test/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerFactoryTest.java b/core-api/src/test/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerFactoryTest.java new file mode 100644 index 00000000..5c47a1f4 --- /dev/null +++ b/core-api/src/test/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerFactoryTest.java @@ -0,0 +1,64 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer; + +import com.optimizely.ab.internal.PropertyUtils; +import com.optimizely.ab.odp.serializer.impl.GsonSerializer; +import com.optimizely.ab.odp.serializer.impl.JacksonSerializer; +import com.optimizely.ab.odp.serializer.impl.JsonSerializer; +import com.optimizely.ab.odp.serializer.impl.JsonSimpleSerializer; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public class ODPJsonSerializerFactoryTest { + @Before + @After + public void clearParserSystemProperty() { + PropertyUtils.clear("default_parser"); + } + + @Test + public void getGsonSerializerWhenNoDefaultIsSet() { + assertEquals(GsonSerializer.class, ODPJsonSerializerFactory.getSerializer().getClass()); + } + + @Test + public void getCorrectSerializerWhenValidDefaultIsProvidedIsJson() { + PropertyUtils.set("default_parser", "JSON_CONFIG_PARSER"); + assertEquals(JsonSerializer.class, ODPJsonSerializerFactory.getSerializer().getClass()); + } + + @Test + public void getCorrectSerializerWhenValidDefaultIsProvidedIsJsonSimple() { + PropertyUtils.set("default_parser", "JSON_SIMPLE_CONFIG_PARSER"); + assertEquals(JsonSimpleSerializer.class, ODPJsonSerializerFactory.getSerializer().getClass()); + } + + @Test + public void getCorrectSerializerWhenValidDefaultIsProvidedIsJackson() { + PropertyUtils.set("default_parser", "JACKSON_CONFIG_PARSER"); + assertEquals(JacksonSerializer.class, ODPJsonSerializerFactory.getSerializer().getClass()); + } + + @Test + public void getGsonSerializerWhenGivenDefaultSerializerDoesNotExist() { + PropertyUtils.set("default_parser", "GARBAGE_VALUE"); + assertEquals(GsonSerializer.class, ODPJsonSerializerFactory.getSerializer().getClass()); + } +} diff --git a/core-api/src/test/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerTest.java b/core-api/src/test/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerTest.java new file mode 100644 index 00000000..7a9538a8 --- /dev/null +++ b/core-api/src/test/java/com/optimizely/ab/odp/serializer/ODPJsonSerializerTest.java @@ -0,0 +1,85 @@ +/** + * Copyright 2022, 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. + * You may obtain a copy of the License at + * + * http://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.odp.serializer; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.optimizely.ab.odp.ODPEvent; +import com.optimizely.ab.odp.serializer.impl.*; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; + +import java.util.*; + +import static junit.framework.TestCase.assertEquals; + +@RunWith(Parameterized.class) +public class ODPJsonSerializerTest { + private final ODPJsonSerializer jsonSerializer; + + public ODPJsonSerializerTest(ODPJsonSerializer jsonSerializer) { + super(); + this.jsonSerializer = jsonSerializer; + } + + @Parameterized.Parameters + public static List input() { + return Arrays.asList(new GsonSerializer(), new JsonSerializer(), new JsonSimpleSerializer(), new JacksonSerializer()); + } + + @Test + public void serializeMultipleEvents() throws JsonProcessingException { + List events = Arrays.asList( + createTestEvent("1"), + createTestEvent("2"), + createTestEvent("3") + ); + + ObjectMapper mapper = new ObjectMapper(); + + String expectedResult = "[{\"type\":\"type-1\",\"action\":\"action-1\",\"identifiers\":{\"vuid-1-3\":\"fs-1-3\",\"vuid-1-1\":\"fs-1-1\",\"vuid-1-2\":\"fs-1-2\"},\"data\":{\"source\":\"java-sdk\",\"data-1\":\"data-value-1\",\"data-num\":1,\"data-bool-true\":true,\"data-bool-false\":false,\"data-float\":2.33,\"data-null\":null}},{\"type\":\"type-2\",\"action\":\"action-2\",\"identifiers\":{\"vuid-2-3\":\"fs-2-3\",\"vuid-2-2\":\"fs-2-2\",\"vuid-2-1\":\"fs-2-1\"},\"data\":{\"source\":\"java-sdk\",\"data-1\":\"data-value-2\",\"data-num\":2,\"data-bool-true\":true,\"data-bool-false\":false,\"data-float\":2.33,\"data-null\":null}},{\"type\":\"type-3\",\"action\":\"action-3\",\"identifiers\":{\"vuid-3-3\":\"fs-3-3\",\"vuid-3-2\":\"fs-3-2\",\"vuid-3-1\":\"fs-3-1\"},\"data\":{\"source\":\"java-sdk\",\"data-1\":\"data-value-3\",\"data-num\":3,\"data-bool-true\":true,\"data-bool-false\":false,\"data-float\":2.33,\"data-null\":null}}]"; + String serializedString = jsonSerializer.serializeEvents(events); + assertEquals(mapper.readTree(expectedResult), mapper.readTree(serializedString)); + } + + @Test + public void serializeEmptyList() throws JsonProcessingException { + List events = Collections.emptyList(); + String expectedResult = "[]"; + String serializedString = jsonSerializer.serializeEvents(events); + assertEquals(expectedResult, serializedString); + } + + private static ODPEvent createTestEvent(String index) { + Map identifiers = new HashMap<>(); + identifiers.put("vuid-" + index + "-1", "fs-" + index + "-1"); + identifiers.put("vuid-" + index + "-2", "fs-" + index + "-2"); + identifiers.put("vuid-" + index + "-3", "fs-" + index + "-3"); + + Map data = new HashMap<>(); + data.put("source", "java-sdk"); + data.put("data-1", "data-value-" + index); + data.put("data-num", Integer.parseInt(index)); + data.put("data-float", 2.33); + data.put("data-bool-true", true); + data.put("data-bool-false", false); + data.put("data-null", null); + + + return new ODPEvent("type-" + index, "action-" + index, identifiers, data); + } +} 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 f0703dcb..07ee1b3e 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,7 +17,6 @@ import com.optimizely.ab.OptimizelyHttpClient; import com.optimizely.ab.annotations.VisibleForTesting; -import org.apache.http.HttpStatus; import org.apache.http.StatusLine; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpPost; @@ -167,6 +166,62 @@ public String fetchQualifiedSegments(String apiKey, String apiEndpoint, String u return null; } + /* + 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. + 3. HTTPStatus code if httpclient was able to make the request and was able to receive response. + It is recommended to retry if status code was 5xx. + */ + @Override + public Integer sendEvents(String apiKey, String apiEndpoint, String eventPayload) { + HttpPost request = new HttpPost(apiEndpoint); + + try { + request.setEntity(new StringEntity(eventPayload)); + } catch (UnsupportedEncodingException e) { + logger.error("ODP event send failed (Error encoding request payload)", e); + return null; + } + request.setHeader("x-api-key", apiKey); + request.setHeader("content-type", "application/json"); + + CloseableHttpResponse response = null; + try { + response = httpClient.execute(request); + } catch (IOException e) { + logger.error("Error retrieving response from event request", e); + return 0; + } + + int statusCode = response.getStatusLine().getStatusCode(); + if ( statusCode >= 400) { + StatusLine statusLine = response.getStatusLine(); + logger.error(String.format("ODP event send failed (Response code: %d, %s)", statusLine.getStatusCode(), statusLine.getReasonPhrase())); + } else { + logger.debug("ODP Event Dispatched successfully"); + } + + closeHttpResponse(response); + return statusCode; + } + private static void closeHttpResponse(CloseableHttpResponse response) { if (response != null) { try { 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 c81af2dc..77440f80 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 @@ -111,6 +111,21 @@ public void returnNullWhenStatusIsNot200AndLogError() throws Exception { String responseString = apiManager.fetchQualifiedSegments("key", "endPoint", "fs_user_id", "test_user", 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"); - assertEquals(null, responseString); + assertNull(responseString); + } + + @Test + public void eventDispatchSuccess() { + ODPApiManager apiManager = new DefaultODPApiManager(mockHttpClient); + apiManager.sendEvents("testKey", "testEndpoint", "[]"); + logbackVerifier.expectMessage(Level.DEBUG, "ODP Event Dispatched successfully"); + } + + @Test + public void eventDispatchFailStatus() throws Exception { + setupHttpClient(400); + ODPApiManager apiManager = new DefaultODPApiManager(mockHttpClient); + apiManager.sendEvents("testKey", "testEndpoint", "[]]"); + logbackVerifier.expectMessage(Level.ERROR, "ODP event send failed (Response code: 400, null)"); } }