/* * Copyright 2016-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"). * You may not use this file except in compliance with the License. * A copy of the License is located at * * http://aws.amazon.com/apache2.0 * * or in the "license" file accompanying this file. This file 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.amazonaws.protocol.json; import static org.hamcrest.Matchers.instanceOf; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertThat; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.util.LinkedList; import java.util.List; import org.apache.http.client.methods.HttpRequestBase; import org.junit.BeforeClass; import org.junit.Test; import com.amazonaws.AmazonClientException; import com.amazonaws.AmazonServiceException; import com.amazonaws.DefaultRequest; import com.amazonaws.http.HttpResponse; import com.amazonaws.http.JsonErrorResponseHandler; import com.amazonaws.transform.JsonErrorUnmarshaller; import software.amazon.ion.IonStruct; import software.amazon.ion.IonSystem; import software.amazon.ion.IonWriter; import software.amazon.ion.Timestamp; import software.amazon.ion.system.IonSystemBuilder; public class SdkStructuredIonFactoryTest { private static final String ERROR_PREFIX = "aws-type:"; private static final String ERROR_TYPE = "InvalidParameterException"; private static final String ERROR_MESSAGE = "foo"; private static final String NO_SERVICE_NAME = null; private static final HttpRequestBase NO_HTTP_REQUEST = null; private static final String NO_CUSTOM_ERROR_CODE_FIELD_NAME = null; private static IonSystem system; @BeforeClass public static void beforeClass() { system = IonSystemBuilder.standard().build(); } @Test public void handlesErrorsUsingHttpHeader() throws Exception { IonStruct payload = createPayload(); HttpResponse error = createResponse(payload); error.addHeader("x-amzn-ErrorType", ERROR_TYPE); AmazonServiceException exception = handleError(error); assertThat(exception, instanceOf(InvalidParameterException.class)); assertEquals(ERROR_MESSAGE, exception.getErrorMessage()); } @Test public void handlesErrorsUsingMagicField() throws Exception { IonStruct payload = createPayload(); payload.add("__type", system.newString(ERROR_TYPE)); HttpResponse error = createResponse(payload); AmazonServiceException exception = handleError(error); assertThat(exception, instanceOf(InvalidParameterException.class)); assertEquals(ERROR_MESSAGE, exception.getErrorMessage()); } @Test public void handlesErrorsUsingAnnotation() throws Exception { IonStruct payload = createPayload(); payload.addTypeAnnotation(ERROR_PREFIX + ERROR_TYPE); HttpResponse error = createResponse(payload); AmazonServiceException exception = handleError(error); assertThat(exception, instanceOf(InvalidParameterException.class)); assertEquals(ERROR_MESSAGE, exception.getErrorMessage()); } @Test(expected = AmazonClientException.class) public void rejectPayloadsWithMultipleErrorAnnotations() throws Exception { IonStruct payload = createPayload(); payload.addTypeAnnotation(ERROR_PREFIX + ERROR_TYPE); payload.addTypeAnnotation(ERROR_PREFIX + "foo"); HttpResponse error = createResponse(payload); handleError(error); } @Test public void handlesErrorsWithMutipleAnnotations() throws Exception { IonStruct payload = createPayload(); payload.addTypeAnnotation("foo"); payload.addTypeAnnotation(ERROR_PREFIX + ERROR_TYPE); payload.addTypeAnnotation("bar"); HttpResponse error = createResponse(payload); AmazonServiceException exception = handleError(error); assertThat(exception, instanceOf(InvalidParameterException.class)); assertEquals(ERROR_MESSAGE, exception.getErrorMessage()); } private static IonStruct createPayload() { IonStruct payload = system.newEmptyStruct(); payload.add("NotValidJson", system.newTimestamp(Timestamp.nowZ())); payload.add("ErrorMessage", system.newString(ERROR_MESSAGE)); return payload; } private static HttpResponse createResponse(IonStruct payload) throws Exception { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); IonWriter writer = system.newBinaryWriter(bytes); payload.writeTo(writer); writer.close(); HttpResponse error = new HttpResponse(new DefaultRequest(NO_SERVICE_NAME), NO_HTTP_REQUEST); error.setContent(new ByteArrayInputStream(bytes.toByteArray())); return error; } private AmazonServiceException handleError(HttpResponse error) throws Exception { List<JsonErrorUnmarshaller> unmarshallers = new LinkedList<JsonErrorUnmarshaller>(); unmarshallers.add(new JsonErrorUnmarshaller(InvalidParameterException.class, ERROR_TYPE)); JsonErrorResponseHandler handler = SdkStructuredIonFactory.SDK_ION_BINARY_FACTORY.createErrorResponseHandler(unmarshallers, NO_CUSTOM_ERROR_CODE_FIELD_NAME); return handler.handle(error); } private static class InvalidParameterException extends AmazonServiceException { private static final long serialVersionUID = 0; public InvalidParameterException(String errorMessage) { super(errorMessage); } } }