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

software.amazon.awssdk.awscore.eventstream.EventStreamExceptionJsonUnmarshaller Maven / Gradle / Ivy

Go to download

A single bundled dependency that includes all service and dependent JARs with third-party libraries relocated to different namespaces.

There is a newer version: 2.5.20
Show newest version
/*
 * Copyright 2010-2018 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 software.amazon.awssdk.awscore.eventstream;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.function.Supplier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import software.amazon.awssdk.annotations.SdkProtectedApi;
import software.amazon.awssdk.awscore.exception.AwsErrorDetails;
import software.amazon.awssdk.awscore.exception.AwsServiceException;
import software.amazon.awssdk.core.SdkBytes;
import software.amazon.awssdk.core.runtime.transform.JsonUnmarshallerContext;
import software.amazon.awssdk.core.runtime.transform.Unmarshaller;

@SdkProtectedApi
public class EventStreamExceptionJsonUnmarshaller
    implements Unmarshaller {

    private static final Logger log = LoggerFactory.getLogger(EventStreamExceptionJsonUnmarshaller.class);

    private final Map> unmarshallers;
    private final Unmarshaller defaultUnmarshaller;

    private EventStreamExceptionJsonUnmarshaller(Builder builder) {
        this.unmarshallers = new HashMap<>(builder.unmarshallers);
        this.defaultUnmarshaller = builder.defaultUnmarshaller;
    }

    public static  Builder builder() {
        return new Builder<>();
    }

    public static AwsServiceException populateDefaultException(
        Supplier exceptionBuilderSupplier, JsonUnmarshallerContext context) {
        String errorMessage;
        String errorCode;

        String messageType = context.getHeader(":message-type");
        if ("error".equals(messageType)) {
            errorMessage = context.getHeader(":error-message");
            errorCode = context.getHeader(":error-code");
        } else if ("exception".equals(messageType)) {
            errorMessage = extractErrorMessageFromPayload(context);
            errorCode = context.getHeader(":exception-type");
        } else {
            throw new IllegalStateException("Unexpected exception message type: " + messageType);
        }

        SdkBytes rawResponse = SdkBytes.fromInputStream(context.getHttpResponse().getContent());
        return exceptionBuilderSupplier.get()
                                       .awsErrorDetails(AwsErrorDetails.builder()
                                                                       .errorMessage(errorMessage)
                                                                       .errorCode(errorCode)
                                                                       .rawResponse(rawResponse)
                                                                       .build())
                                       .build();
    }

    @Override
    public T unmarshall(JsonUnmarshallerContext in) throws Exception {
        String exceptionType = Optional.ofNullable(in.getHeader(":exception-type")).orElse("");
        return unmarshallers.getOrDefault(exceptionType, defaultUnmarshaller).unmarshall(in);
    }

    private static String extractErrorMessageFromPayload(JsonUnmarshallerContext context) {
        try {
            do {
                if (context.testExpression("message", 1)) {
                    context.nextToken();
                    return context.getUnmarshaller(String.class).unmarshall(context);
                }
            } while (context.nextToken() != null);
        } catch (IOException e) {
            log.info("Could not parse error message from content");
        } catch (Exception e) {
            // Find bugs doesn't like one catch clause for some reason
            log.info("Could not parse error message from content");
        }
        return null;
    }

    public static final class Builder {
        private final Map> unmarshallers =
            new HashMap<>();

        private Unmarshaller defaultUnmarshaller;

        private Builder() {
        }

        /**
         * Registers a new {@link Unmarshaller} with the given type.
         *
         * @param type Value of ':exception-type' header this unmarshaller handles.
         * @param unmarshaller Unmarshaller of a event subtype.
         * @return This object for method chaining.
         */
        public Builder addUnmarshaller(String type,
                                          Unmarshaller unmarshaller) {
            unmarshallers.put(type, unmarshaller);
            return this;
        }

        /**
         * Registers the default unmarshaller. Used when the value in the ':exception-type' header does not match
         * a registered unmarshaller (i.e. this is a new event that this version of the SDK doesn't know about).
         *
         * @param defaultUnmarshaller Default unmarshaller to use when exception-type doesn't match a registered unmarshaller.
         * @return This object for method chaining.
         */
        public Builder defaultUnmarshaller(Unmarshaller
                                                  defaultUnmarshaller) {
            this.defaultUnmarshaller = defaultUnmarshaller;
            return this;
        }

        public EventStreamExceptionJsonUnmarshaller build() {
            return new EventStreamExceptionJsonUnmarshaller<>(this);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy