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

com.amazonaws.protocol.json.SdkJsonProtocolFactory Maven / Gradle / Ivy

Go to download

The AWS SDK for Java - Core module holds the classes that are used by the individual service clients to interact with Amazon Web Services. Users need to depend on aws-java-sdk artifact for accessing individual client classes.

There is a newer version: 1.12.778
Show newest version
/*
 *
 * Copyright (c) 2016 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 com.amazonaws.AmazonServiceException;
import com.amazonaws.AmazonWebServiceResponse;
import com.amazonaws.SDKGlobalConfiguration;
import com.amazonaws.annotation.SdkProtectedApi;
import com.amazonaws.annotation.ThreadSafe;
import com.amazonaws.http.HttpResponseHandler;
import com.amazonaws.protocol.OperationInfo;
import com.amazonaws.protocol.Protocol;
import com.amazonaws.protocol.ProtocolRequestMarshaller;
import com.amazonaws.protocol.json.internal.EmptyBodyJsonMarshaller;
import com.amazonaws.transform.JsonErrorUnmarshaller;
import com.amazonaws.transform.JsonUnmarshallerContext;
import com.amazonaws.transform.Unmarshaller;
import java.util.ArrayList;
import java.util.List;

/**
 * Factory to generate the various JSON protocol handlers and generators depending on the wire protocol to be used for
 * communicating with the AWS service.
 */
@ThreadSafe
@SdkProtectedApi
public class SdkJsonProtocolFactory implements SdkJsonMarshallerFactory {

    private final JsonClientMetadata metadata;

    private final List errorUnmarshallers = new ArrayList();

    public SdkJsonProtocolFactory(JsonClientMetadata metadata) {
        this.metadata = metadata;
        createErrorUnmarshallers();
    }

    @Override
    public StructuredJsonGenerator createGenerator() {
        return getSdkFactory().createWriter(getContentType());
    }

    @Override
    public String getContentType() {
        return getContentTypeResolver().resolveContentType(metadata);
    }

    public  ProtocolRequestMarshaller createProtocolMarshaller(OperationInfo operationInfo, T origRequest) {
        return JsonProtocolMarshallerBuilder.standard()
                .jsonGenerator(createGenerator(operationInfo))
                .contentType(getContentType())
                .operationInfo(operationInfo)
                .originalRequest(origRequest)
                .emptyBodyMarshaller(createEmptyBodyMarshaller(operationInfo))
                .build();
    }

    private StructuredJsonGenerator createGenerator(OperationInfo operationInfo) {
        if (operationInfo.hasPayloadMembers() || operationInfo.protocol() == Protocol.AWS_JSON) {
            return createGenerator();
        } else {
            return StructuredJsonGenerator.NO_OP;
        }
    }

    /**
     * For requests with payloads, if it has an explicit payload member and that member is null,
     * the body should be rendered as empty JSON.
     *
     * The API Gateway protocol has it's own factory and should not appear here.
     */
    private EmptyBodyJsonMarshaller createEmptyBodyMarshaller(OperationInfo operationInfo) {
        if (operationInfo.protocol() == Protocol.API_GATEWAY) {
            throw new IllegalStateException("Detected the API_GATEWAY protocol which should not be used with this "
                                            + "protocol factory.");
        }
        if (!operationInfo.hasPayloadMembers() || operationInfo.protocol() == Protocol.API_GATEWAY) {
            return EmptyBodyJsonMarshaller.NULL;
        } else {
            return EmptyBodyJsonMarshaller.EMPTY;
        }
    }

    /**
     * Returns the response handler to be used for handling a successful response.
     *
     * @param operationMetadata Additional context information about an operation to create the appropriate response handler.
     */
    public  HttpResponseHandler> createResponseHandler(
            JsonOperationMetadata operationMetadata,
            Unmarshaller responseUnmarshaller) {
        return getSdkFactory().createResponseHandler(operationMetadata, responseUnmarshaller);
    }

    /**
     * Creates a response handler for handling a error response (non 2xx response).
     */
    public HttpResponseHandler createErrorResponseHandler(
            JsonErrorResponseMetadata errorResponsMetadata) {
        return getSdkFactory().createErrorResponseHandler(errorResponsMetadata, errorUnmarshallers);
    }

    @SuppressWarnings("unchecked")
    private void createErrorUnmarshallers() {
        for (JsonErrorShapeMetadata errorMetadata : metadata.getErrorShapeMetadata()) {
            if (errorMetadata.getExceptionUnmarshaller() != null) {
                errorUnmarshallers.add(errorMetadata.getExceptionUnmarshaller());
            } else if (errorMetadata.getModeledClass() != null) {
                errorUnmarshallers.add(new JsonErrorUnmarshaller(
                        (Class) errorMetadata.getModeledClass(),
                        errorMetadata.getErrorCode()));
            }
        }

        if (metadata.getBaseServiceExceptionClass() != null) {
            errorUnmarshallers.add(new JsonErrorUnmarshaller(
                    (Class) metadata.getBaseServiceExceptionClass(), null));
        }
    }

    /**
     * @return Instance of {@link SdkStructuredJsonFactory} to use in creating handlers.
     */
    private SdkStructuredJsonFactory getSdkFactory() {
        if (isCborEnabled()) {
            return SdkStructuredCborFactory.SDK_CBOR_FACTORY;
        } else {
            return SdkStructuredPlainJsonFactory.SDK_JSON_FACTORY;
        }
    }

    /**
     * @return Content type resolver implementation to use.
     */
    private JsonContentTypeResolver getContentTypeResolver() {
        if (isCborEnabled()) {
            return JsonContentTypeResolver.CBOR;
        } else {
            return JsonContentTypeResolver.JSON;
        }
    }

    private boolean isCborEnabled() {
        return metadata.isSupportsCbor() && !SDKGlobalConfiguration.isCborDisabled();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy