diff --git a/src/main/java/com/proofpoint/event/collector/ConfigLoadingException.java b/src/main/java/com/proofpoint/event/collector/ConfigLoadingException.java new file mode 100644 index 0000000..8a27246 --- /dev/null +++ b/src/main/java/com/proofpoint/event/collector/ConfigLoadingException.java @@ -0,0 +1,9 @@ +package com.proofpoint.event.collector; + +public class ConfigLoadingException extends Exception +{ + public ConfigLoadingException(String message, Exception ex) + { + super(message, ex); + } +} diff --git a/src/main/java/com/proofpoint/event/collector/FlowConfiguration.java b/src/main/java/com/proofpoint/event/collector/FlowConfiguration.java new file mode 100644 index 0000000..3723386 --- /dev/null +++ b/src/main/java/com/proofpoint/event/collector/FlowConfiguration.java @@ -0,0 +1,25 @@ +package com.proofpoint.event.collector; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; + +import javax.validation.constraints.NotNull; +import java.util.Set; + +public class FlowConfiguration +{ + private Set propertiesToSerialize; + + @JsonCreator + public FlowConfiguration(@JsonProperty("propertiesToSerialize") Set propertiesToSerialize) + { + this.propertiesToSerialize = propertiesToSerialize; + } + + @NotNull(message = "is missing") + @JsonProperty + public Set getPropertiesToSerialize() + { + return propertiesToSerialize; + } +} diff --git a/src/main/java/com/proofpoint/event/collector/FlowConfigurationLoader.java b/src/main/java/com/proofpoint/event/collector/FlowConfigurationLoader.java new file mode 100644 index 0000000..04a84f5 --- /dev/null +++ b/src/main/java/com/proofpoint/event/collector/FlowConfigurationLoader.java @@ -0,0 +1,9 @@ +package com.proofpoint.event.collector; + +import java.net.URI; + +public interface FlowConfigurationLoader +{ + public FlowConfiguration loadConfiguration(URI configurationLocation) + throws ConfigLoadingException; +} diff --git a/src/main/java/com/proofpoint/event/collector/ForFlowConfigurationLoader.java b/src/main/java/com/proofpoint/event/collector/ForFlowConfigurationLoader.java new file mode 100644 index 0000000..f82299a --- /dev/null +++ b/src/main/java/com/proofpoint/event/collector/ForFlowConfigurationLoader.java @@ -0,0 +1,5 @@ +package com.proofpoint.event.collector; + +public @interface ForFlowConfigurationLoader +{ +} diff --git a/src/main/java/com/proofpoint/event/collector/HttpFlowConfigurationLoader.java b/src/main/java/com/proofpoint/event/collector/HttpFlowConfigurationLoader.java new file mode 100644 index 0000000..59e2799 --- /dev/null +++ b/src/main/java/com/proofpoint/event/collector/HttpFlowConfigurationLoader.java @@ -0,0 +1,43 @@ +package com.proofpoint.event.collector; + +import com.proofpoint.http.client.HttpClient; +import com.proofpoint.http.client.Request; +import com.proofpoint.json.JsonCodec; + +import javax.inject.Inject; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import java.net.URI; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.proofpoint.http.client.JsonResponseHandler.createJsonResponseHandler; +import static java.lang.String.format; + + +public class HttpFlowConfigurationLoader + implements FlowConfigurationLoader +{ + private static final String LOADING_EXCEPTION_MESSAGE = "Config could not be loaded from location %s"; + private static final JsonCodec FLOW_CONFIGURATION_CODEC = JsonCodec.jsonCodec(FlowConfiguration.class); + private final HttpClient httpClient; + + @Inject + public HttpFlowConfigurationLoader(@ForFlowConfigurationLoader HttpClient httpClient) + { + this.httpClient = checkNotNull(httpClient, "httpClient is null"); + } + + @Override + public FlowConfiguration loadConfiguration(URI configurationLocation) + throws ConfigLoadingException + { + checkNotNull(configurationLocation, "configurationLocation is null"); + try { + Request.Builder requestBuilder = Request.builder().prepareGet().setUri(configurationLocation).setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); + return httpClient.execute(requestBuilder.build(), createJsonResponseHandler(FLOW_CONFIGURATION_CODEC)); + } + catch (Exception ex) { + throw new ConfigLoadingException(format(LOADING_EXCEPTION_MESSAGE, configurationLocation), ex); + } + } +} diff --git a/src/test/java/com/proofpoint/event/collector/TestFlowConfiguration.java b/src/test/java/com/proofpoint/event/collector/TestFlowConfiguration.java new file mode 100644 index 0000000..fdcb7c0 --- /dev/null +++ b/src/test/java/com/proofpoint/event/collector/TestFlowConfiguration.java @@ -0,0 +1,64 @@ +package com.proofpoint.event.collector; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Maps; +import com.proofpoint.json.JsonCodec; +import org.testng.annotations.BeforeMethod; +import org.testng.annotations.Test; + +import javax.validation.constraints.NotNull; +import java.util.Map; + +import static com.proofpoint.json.JsonCodec.jsonCodec; +import static com.proofpoint.json.testing.JsonTester.assertJsonEncode; +import static com.proofpoint.json.testing.JsonTester.decodeJson; +import static com.proofpoint.testing.ValidationAssertions.assertFailsValidation; +import static com.proofpoint.testing.ValidationAssertions.assertValidates; + + +public class TestFlowConfiguration +{ + private final JsonCodec codec = jsonCodec(FlowConfiguration.class); + private Map map; + + @BeforeMethod + public void setup() { + map = Maps.newHashMap(ImmutableMap.of("propertiesToSerialize", ImmutableList.of("property1"))); + } + + @Test + public void testNoPropertiesToSerializeInJsonDecode() + { + map.remove("propertiesToSerialize"); + assertFailsValidation(decodeJson(codec, map), "propertiesToSerialize", "is missing", NotNull.class); + } + + @Test + public void testJsonEncode() + { + assertJsonEncode(assertValidates(new FlowConfiguration(ImmutableSet.of("property1"))), map); + } + + @Test + public void testNullPropertiesToSerialize() + { + FlowConfiguration flowConfig = new FlowConfiguration(null); + assertFailsValidation(flowConfig, "propertiesToSerialize", "is missing", NotNull.class); + } + + @Test + public void testPassesValidation() + { + FlowConfiguration flowConfig = new FlowConfiguration(ImmutableSet.of("foo")); + assertValidates(flowConfig); + } + + @Test + public void testEmptyPropertiesPassesValidation() + { + FlowConfiguration flowConfig = new FlowConfiguration(ImmutableSet.of()); + assertValidates(flowConfig); + } +} diff --git a/src/test/java/com/proofpoint/event/collector/TestHttpFlowConfigurationLoader.java b/src/test/java/com/proofpoint/event/collector/TestHttpFlowConfigurationLoader.java new file mode 100644 index 0000000..4889682 --- /dev/null +++ b/src/test/java/com/proofpoint/event/collector/TestHttpFlowConfigurationLoader.java @@ -0,0 +1,67 @@ +package com.proofpoint.event.collector; + +import com.google.common.collect.ImmutableSet; +import com.proofpoint.http.client.HttpClient; +import com.proofpoint.http.client.Request; +import com.proofpoint.http.client.ResponseHandler; +import org.testng.annotations.Test; + +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; +import java.net.URI; + +import static java.lang.String.format; +import static org.mockito.Matchers.anyObject; +import static org.mockito.Matchers.eq; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; +import static org.testng.Assert.assertEquals; +import static org.testng.Assert.assertSame; +import static org.testng.Assert.fail; + +public class TestHttpFlowConfigurationLoader +{ + FlowConfiguration remoteConfig = new FlowConfiguration(ImmutableSet.of("")); + + @Test + public void testBasicRemoteConfigurationLoad() + throws Exception + { + HttpClient client = mock(HttpClient.class); + URI configLocation = URI.create("http://www.remoteconfiglocation.com/"); + Request.Builder requestBuilder = Request.builder().prepareGet().setUri(configLocation).setHeader(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON); + when(client.execute(eq(requestBuilder.build()), (ResponseHandler) anyObject())).thenReturn(remoteConfig); + + FlowConfigurationLoader loader = new HttpFlowConfigurationLoader(client); + assertEquals(loader.loadConfiguration(configLocation), remoteConfig); + } + + @Test(expectedExceptions = NullPointerException.class) + public void testNoRemoteConfigurationLocationLoad() + throws Exception + { + FlowConfigurationLoader loader = new HttpFlowConfigurationLoader(mock(HttpClient.class)); + loader.loadConfiguration(null); + fail("Should have thrown", new NullPointerException("Config location was null")); + } + + @Test() + public void testConfigLoadingExceptionMessage() + throws Exception + { + String configLocation = "http://www.remoteconfiglocation.com/foo.json"; + HttpClient client = mock(HttpClient.class); + Exception thrownException = new Exception("Bad!"); + when(client.execute((Request) anyObject(), (ResponseHandler) anyObject())).thenThrow(thrownException); + + FlowConfigurationLoader loader = new HttpFlowConfigurationLoader(client); + try { + loader.loadConfiguration(URI.create(configLocation)); + fail("expected ConfigLoadingException"); + } + catch (ConfigLoadingException ex) { + assertEquals(ex.getMessage(), format("Config could not be loaded from location http://www.remoteconfiglocation.com/foo.json", configLocation)); + assertSame(ex.getCause(), thrownException); + } + } +}