diff --git a/pom.xml b/pom.xml index cf470f1..607de5c 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ com.coveo spring-boot-parameter-store-integration - 1.1.1 + 1.1.2 Spring Boot Parameter Store Integration An integration of Amazon Web Services' Systems Manager Parameter Store for Spring Boot's properties injection. @@ -41,7 +41,7 @@ com.fasterxml.jackson jackson-bom - 2.9.8 + 2.9.9 import pom @@ -52,19 +52,19 @@ org.springframework.boot spring-boot - 1.5.14.RELEASE + 1.5.21.RELEASE com.amazonaws aws-java-sdk-ssm - 1.11.351 + 1.11.566 org.springframework.boot spring-boot-starter-test - 1.5.14.RELEASE + 1.5.21.RELEASE test diff --git a/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java b/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java index 7e3d245..e6809e4 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java +++ b/src/main/java/com/coveo/configuration/parameterstore/ParameterStoreSource.java @@ -2,9 +2,10 @@ import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest; +import com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult; import com.amazonaws.services.simplesystemsmanagement.model.ParameterNotFoundException; -import com.coveo.configuration.parameterstore.exception.ParameterStoreParameterNotFoundError; import com.coveo.configuration.parameterstore.exception.ParameterStoreError; +import com.coveo.configuration.parameterstore.exception.ParameterStoreParameterNotFoundError; public class ParameterStoreSource { @@ -20,9 +21,10 @@ public ParameterStoreSource(AWSSimpleSystemsManagement ssmClient, boolean haltBo public Object getProperty(String propertyName) { try { - return ssmClient.getParameter(new GetParameterRequest().withName(propertyName).withWithDecryption(true)) - .getParameter() - .getValue(); + GetParameterResult getParameterResult = ssmClient.getParameter(new GetParameterRequest().withName(propertyName) + .withWithDecryption(true)); + validate(propertyName, getParameterResult); + return getParameterResult.getParameter().getValue(); } catch (ParameterNotFoundException e) { if (haltBoot) { throw new ParameterStoreParameterNotFoundError(propertyName, e); @@ -32,4 +34,28 @@ public Object getProperty(String propertyName) } return null; } + + private void validate(String propertyName, GetParameterResult getParameterResult) + { + String requestId = getParameterResult.getSdkResponseMetadata().getRequestId(); + int statusCode = getParameterResult.getSdkHttpMetadata().getHttpStatusCode(); + if (statusCode != 200) { + throw new ParameterStoreError(propertyName, + String.format("Invalid response code '%s' received from AWS. AWS Request ID : '%s'.", + statusCode, + requestId)); + } + + if (getParameterResult.getParameter() == null) { + throw new ParameterStoreError(propertyName, + String.format("A null Parameter was received from AWS. AWS Request ID : '%s'.", + requestId)); + } + + if (getParameterResult.getParameter().getValue() == null) { + throw new ParameterStoreError(propertyName, + String.format("A null Parameter value was received from AWS. AWS Request ID : '%s'.", + requestId)); + } + } } diff --git a/src/main/java/com/coveo/configuration/parameterstore/exception/ParameterStoreError.java b/src/main/java/com/coveo/configuration/parameterstore/exception/ParameterStoreError.java index e33c7b5..9675f09 100644 --- a/src/main/java/com/coveo/configuration/parameterstore/exception/ParameterStoreError.java +++ b/src/main/java/com/coveo/configuration/parameterstore/exception/ParameterStoreError.java @@ -4,6 +4,11 @@ public class ParameterStoreError extends Error { private static final long serialVersionUID = 1L; + public ParameterStoreError(String propertyName, String reason) + { + super(String.format("Accessing Parameter Store for parameter '%s' failed. %s", propertyName, reason)); + } + public ParameterStoreError(String propertyName, Exception e) { super(String.format("Accessing Parameter Store for parameter '%s' failed.", propertyName), e); diff --git a/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java b/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java index 384b3fd..745c242 100644 --- a/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java +++ b/src/test/java/com/coveo/configuration/parameterstore/ParameterStoreSourceTest.java @@ -10,6 +10,8 @@ import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import com.amazonaws.ResponseMetadata; +import com.amazonaws.http.SdkHttpMetadata; import com.amazonaws.services.simplesystemsmanagement.AWSSimpleSystemsManagement; import com.amazonaws.services.simplesystemsmanagement.model.GetParameterRequest; import com.amazonaws.services.simplesystemsmanagement.model.GetParameterResult; @@ -28,19 +30,25 @@ public class ParameterStoreSourceTest @Mock private AWSSimpleSystemsManagement ssmClientMock; + @Mock + private SdkHttpMetadata sdkHttpMetadataMock; + @Mock + private ResponseMetadata responseMetadataMock; private ParameterStoreSource parameterStoreSource; @Before public void setUp() { + when(sdkHttpMetadataMock.getHttpStatusCode()).thenReturn(200); + parameterStoreSource = new ParameterStoreSource(ssmClientMock, false); } @Test public void testGetProperty() { - when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(new GetParameterResult().withParameter(new Parameter().withValue(VALID_PROPERTY_VALUE))); + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult().withParameter(new Parameter().withValue(VALID_PROPERTY_VALUE))); Object value = parameterStoreSource.getProperty(VALID_PROPERTY_NAME); @@ -74,6 +82,42 @@ public void shouldThrowOnGetPropertyWhenNotFoundAndHaltBootIsTrue() parameterStoreSourceHaltingBoot.getProperty(INVALID_PROPERTY_NAME); } + @Test(expected = ParameterStoreError.class) + public void shouldThrowWhenStatusCodeIsNot200() + { + when(sdkHttpMetadataMock.getHttpStatusCode()).thenReturn(503); + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult()); + ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); + + parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME); + } + + @Test(expected = ParameterStoreError.class) + public void shouldThrowWhenParameterIsNull() + { + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult()); + ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); + + parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME); + } + + @Test(expected = ParameterStoreError.class) + public void shouldThrowWhenParameterValueIsNull() + { + when(ssmClientMock.getParameter(getParameterRequest(VALID_PROPERTY_NAME))).thenReturn(getGetParameterResult().withParameter(new Parameter())); + ParameterStoreSource parameterStoreSourceHaltingBoot = new ParameterStoreSource(ssmClientMock, true); + + parameterStoreSourceHaltingBoot.getProperty(VALID_PROPERTY_NAME); + } + + private GetParameterResult getGetParameterResult() + { + GetParameterResult getParameterResult = new GetParameterResult(); + getParameterResult.setSdkHttpMetadata(sdkHttpMetadataMock); + getParameterResult.setSdkResponseMetadata(responseMetadataMock); + return getParameterResult; + } + private GetParameterRequest getParameterRequest(String parameterName) { return new GetParameterRequest().withName(parameterName).withWithDecryption(true);