Search in sources :

Example 1 with MessageType

use of software.amazon.awssdk.crt.eventstream.MessageType in project aws-iot-device-sdk-java-v2 by aws.

the class ServiceOperationMappingContinuationHandler method onConnectRequest.

/**
 * Post: authenticationData should not be null
 * @param headers
 * @param payload
 */
protected void onConnectRequest(List<Header> headers, byte[] payload) {
    final int[] responseMessageFlag = { 0 };
    final MessageType acceptResponseType = MessageType.ConnectAck;
    final AuthenticationHandler authentication = serviceHandler.getAuthenticationHandler();
    final AuthorizationHandler authorization = serviceHandler.getAuthorizationHandler();
    try {
        final Optional<String> versionHeader = headers.stream().filter(header -> header.getHeaderType() == HeaderType.String && header.getName().equals(EventStreamRPCServiceModel.VERSION_HEADER)).map(header -> header.getValueAsString()).findFirst();
        if (versionHeader.isPresent() && Version.fromString(versionHeader.get()).equals(Version.getInstance())) {
            // version matches
            if (authentication == null) {
                throw new IllegalStateException(String.format("%s has null authentication handler!", serviceHandler.getServiceName()));
            }
            if (authorization == null) {
                throw new IllegalStateException(String.format("%s has null authorization handler!", serviceHandler.getServiceName()));
            }
            LOGGER.trace(String.format("%s running authentication handler", serviceHandler.getServiceName()));
            authenticationData = authentication.apply(headers, payload);
            if (authenticationData == null) {
                throw new IllegalStateException(String.format("%s authentication handler returned null", serviceHandler.getServiceName()));
            }
            LOGGER.info(String.format("%s authenticated identity: %s", serviceHandler.getServiceName(), authenticationData.getIdentityLabel()));
            final Authorization authorizationDecision = authorization.apply(authenticationData);
            switch(authorizationDecision) {
                case ACCEPT:
                    LOGGER.info("Connection accepted for " + authenticationData.getIdentityLabel());
                    responseMessageFlag[0] = MessageFlags.ConnectionAccepted.getByteValue();
                    break;
                case REJECT:
                    LOGGER.info("Connection rejected for: " + authenticationData.getIdentityLabel());
                    break;
                default:
                    // got a big problem if this is the outcome. Someone forgot to update this switch-case
                    throw new RuntimeException("Unknown authorization decision for " + authenticationData.getIdentityLabel());
            }
        } else {
            // version mismatch
            LOGGER.warn(String.format("Client version {%s} mismatches server version {%s}", versionHeader.isPresent() ? versionHeader.get() : "null", Version.getInstance().getVersionString()));
        }
    } catch (Exception e) {
        LOGGER.error(String.format("%s occurred while attempting to authN/authZ connect: %s", e.getClass(), e.getMessage()), e);
    } finally {
        final String authLabel = authenticationData != null ? authenticationData.getIdentityLabel() : "null";
        LOGGER.info("Sending connect response for " + authLabel);
        connection.sendProtocolMessage(null, null, acceptResponseType, responseMessageFlag[0]).whenComplete((res, ex) -> {
            // TODO: removing log statements due to known issue of locking up
            if (ex != null) {
            // LOGGER.severe(String.format("Sending connection response for %s threw exception (%s): %s",
            // authLabel, ex.getClass().getCanonicalName(), ex.getMessage()));
            } else {
            // LOGGER.info("Successfully sent connection response for: " + authLabel);
            }
            if (responseMessageFlag[0] != MessageFlags.ConnectionAccepted.getByteValue()) {
                // LOGGER.info("Closing connection due to connection not being accepted...");
                connection.closeConnection(0);
            }
        });
    }
}
Also used : Logger(org.slf4j.Logger) HeaderType(software.amazon.awssdk.crt.eventstream.HeaderType) MessageFlags(software.amazon.awssdk.crt.eventstream.MessageFlags) LoggerFactory(org.slf4j.LoggerFactory) CompletableFuture(java.util.concurrent.CompletableFuture) MessageType(software.amazon.awssdk.crt.eventstream.MessageType) Function(java.util.function.Function) Collectors(java.util.stream.Collectors) StandardCharsets(java.nio.charset.StandardCharsets) ArrayList(java.util.ArrayList) List(java.util.List) ServerConnectionContinuationHandler(software.amazon.awssdk.crt.eventstream.ServerConnectionContinuationHandler) ServerConnectionContinuation(software.amazon.awssdk.crt.eventstream.ServerConnectionContinuation) Optional(java.util.Optional) Header(software.amazon.awssdk.crt.eventstream.Header) ServerConnection(software.amazon.awssdk.crt.eventstream.ServerConnection) ServerConnectionHandler(software.amazon.awssdk.crt.eventstream.ServerConnectionHandler) MessageType(software.amazon.awssdk.crt.eventstream.MessageType)

Example 2 with MessageType

use of software.amazon.awssdk.crt.eventstream.MessageType in project aws-iot-device-sdk-java-v2 by aws.

the class ServiceOperationMappingContinuationHandler method onIncomingStream.

@Override
protected ServerConnectionContinuationHandler onIncomingStream(ServerConnectionContinuation continuation, String operationName) {
    final OperationContinuationHandlerContext operationContext = new OperationContinuationHandlerContext(connection, continuation, authenticationData);
    final Function<OperationContinuationHandlerContext, ? extends ServerConnectionContinuationHandler> registeredOperationHandlerFn = serviceHandler.getOperationHandler(operationName);
    if (registeredOperationHandlerFn != null) {
        return registeredOperationHandlerFn.apply(operationContext);
    } else {
        return new ServerConnectionContinuationHandler(continuation) {

            @Override
            protected void onContinuationClosed() {
                close();
            }

            @Override
            protected void onContinuationMessage(List<Header> headers, byte[] payload, MessageType messageType, int messageFlags) {
                int responseMessageFlag = MessageFlags.TerminateStream.getByteValue();
                MessageType responseMessageType = MessageType.ApplicationError;
                String responsePayload = "{ \"error\": \"Unsupported Operation\", " + "\"message\": \"" + operationName + " is an unsupported operation.\" }";
                Header contentTypeHeader = Header.createHeader(":content-type", "application/json");
                List<Header> responseHeaders = new ArrayList<>();
                responseHeaders.add(contentTypeHeader);
                continuation.sendMessage(responseHeaders, responsePayload.getBytes(StandardCharsets.UTF_8), responseMessageType, responseMessageFlag);
            }
        };
    }
}
Also used : ServerConnectionContinuationHandler(software.amazon.awssdk.crt.eventstream.ServerConnectionContinuationHandler) Header(software.amazon.awssdk.crt.eventstream.Header) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) MessageType(software.amazon.awssdk.crt.eventstream.MessageType)

Example 3 with MessageType

use of software.amazon.awssdk.crt.eventstream.MessageType in project aws-iot-device-sdk-java-v2 by aws.

the class ServiceOperationMappingContinuationHandler method onProtocolMessage.

@Override
protected void onProtocolMessage(List<Header> headers, byte[] payload, MessageType messageType, int messageFlags) {
    if (messageType == MessageType.Ping) {
        int responseMessageFlag = 0;
        MessageType responseMessageType = MessageType.PingResponse;
        connection.sendProtocolMessage(headers.stream().filter(header -> !header.getName().startsWith(":")).collect(Collectors.toList()), payload, responseMessageType, responseMessageFlag);
    } else if (messageType == MessageType.Connect) {
        onConnectRequest(headers, payload);
    } else if (messageType != MessageType.PingResponse) {
        int responseMessageFlag = 0;
        MessageType responseMessageType = MessageType.ServerError;
        String responsePayload = "{ \"error\": \"Unrecognized Message Type\" }" + "\"message\": \" message type value: " + messageType.getEnumValue() + " is not recognized as a valid request path.\" }";
        Header contentTypeHeader = Header.createHeader(":content-type", "application/json");
        List<Header> responseHeaders = new ArrayList<>();
        responseHeaders.add(contentTypeHeader);
        CompletableFuture<Void> voidCompletableFuture = connection.sendProtocolMessage(responseHeaders, responsePayload.getBytes(StandardCharsets.UTF_8), responseMessageType, responseMessageFlag);
        voidCompletableFuture.thenAccept(result -> {
            connection.closeConnection(0);
            this.close();
        });
    }
}
Also used : Header(software.amazon.awssdk.crt.eventstream.Header) ArrayList(java.util.ArrayList) MessageType(software.amazon.awssdk.crt.eventstream.MessageType)

Aggregations

ArrayList (java.util.ArrayList)3 Header (software.amazon.awssdk.crt.eventstream.Header)3 MessageType (software.amazon.awssdk.crt.eventstream.MessageType)3 List (java.util.List)2 ServerConnectionContinuationHandler (software.amazon.awssdk.crt.eventstream.ServerConnectionContinuationHandler)2 StandardCharsets (java.nio.charset.StandardCharsets)1 Optional (java.util.Optional)1 CompletableFuture (java.util.concurrent.CompletableFuture)1 Function (java.util.function.Function)1 Collectors (java.util.stream.Collectors)1 Logger (org.slf4j.Logger)1 LoggerFactory (org.slf4j.LoggerFactory)1 HeaderType (software.amazon.awssdk.crt.eventstream.HeaderType)1 MessageFlags (software.amazon.awssdk.crt.eventstream.MessageFlags)1 ServerConnection (software.amazon.awssdk.crt.eventstream.ServerConnection)1 ServerConnectionContinuation (software.amazon.awssdk.crt.eventstream.ServerConnectionContinuation)1 ServerConnectionHandler (software.amazon.awssdk.crt.eventstream.ServerConnectionHandler)1