All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.opensdk.internal.protocol.ApiGatewayErrorResponseHandler Maven / Gradle / Ivy

There is a newer version: 1.12.778
Show newest version
/*
 * Copyright 2015-2024 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.opensdk.internal.protocol;

import com.amazonaws.SdkBaseException;
import com.amazonaws.SdkClientException;
import com.amazonaws.annotation.SdkInternalApi;
import com.amazonaws.http.HttpResponse;
import com.amazonaws.http.HttpResponseHandler;
import com.amazonaws.opensdk.internal.BaseException;
import com.amazonaws.opensdk.SdkErrorHttpMetadata;
import com.amazonaws.http.SdkHttpMetadata;
import com.amazonaws.internal.http.JsonErrorMessageParser;
import com.amazonaws.protocol.json.JsonContent;
import com.amazonaws.util.ValidationUtils;
import com.fasterxml.jackson.core.JsonFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.List;

/**
 * Error response handler for API Gateway clients. API Gateway errors are identified by their HTTP
 * status code.
 */
@SdkInternalApi
public class ApiGatewayErrorResponseHandler implements HttpResponseHandler {

    private static final Log LOG = LogFactory.getLog(ApiGatewayErrorResponseHandler.class);

    private final List unmarshallers;
    private final JsonFactory jsonFactory;
    private final JsonErrorMessageParser messageParser = JsonErrorMessageParser.DEFAULT_ERROR_MESSAGE_PARSER;

    public ApiGatewayErrorResponseHandler(List errorUnmarshallers,
                                          JsonFactory jsonFactory) {
        this.unmarshallers = ValidationUtils
                .assertNotNull(errorUnmarshallers, "errorUnmarshallers");
        this.jsonFactory = ValidationUtils.assertNotNull(jsonFactory, "jsonFactory");
    }

    @Override
    public boolean needsConnectionLeftOpen() {
        return false;
    }

    @Override
    public SdkBaseException handle(HttpResponse response) throws Exception {
        JsonContent jsonContent = JsonContent.createJsonContent(response, jsonFactory);
        BaseException exception = createException(response.getStatusCode(), jsonContent);

        exception.sdkHttpMetadata(new SdkErrorHttpMetadata(SdkHttpMetadata.from(response), jsonContent.getRawContent()));
        exception.setMessage(messageParser.parseErrorMessage(jsonContent.getJsonNode()));

        // Wrap in ASE, will be unwrapped when caught in the service client.
        return (SdkBaseException) exception;
    }

    /**
     * Create an AmazonServiceException using the chain of unmarshallers. This method will never
     * return null, it will always return a valid exception.
     *
     * @param httpStatusCode Http status code to find an appropriate unmarshaller
     * @param jsonContent    JsonContent of HTTP response
     * @return Unmarshalled exception
     */
    private BaseException createException(int httpStatusCode, JsonContent jsonContent) {
        return unmarshallers.stream()
                .filter(u -> u.matches(httpStatusCode))
                .findFirst()
                .map(u -> safeUnmarshall(jsonContent, u))
                .orElseThrow(this::createUnknownException);
    }

    private BaseException safeUnmarshall(JsonContent jsonContent,
                                                   ApiGatewayErrorUnmarshaller unmarshaller) {
        try {
            return unmarshaller.unmarshall(jsonContent.getJsonNode());
        } catch (Exception e) {
            LOG.info("Unable to unmarshall exception content", e);
            throw new SdkClientException(e.getCause());
        }
    }

    /**
     * The default unmarshaller should always work but if it doesn't we fall back to creating an
     * exception explicitly.
     */
    private SdkClientException createUnknownException() {
        return new SdkClientException(
                "Unable to unmarshall exception response with the unmarshallers provided");
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy