Search in sources :

Example 1 with Error

use of com.graphql_java_generator.client.response.Error in project graphql-maven-plugin-project by graphql-java-generator.

the class GraphQLReactiveWebSocketHandler method onNext.

/**
 * The callback that will receive the messages from the web socket. It will map these JSON messages to the relevant
 * java class, and call the application callback with this java objects. This message can be any valid message,
 * according to the <a href="https://github.com/enisdenjo/graphql-ws/blob/master/PROTOCOL.md">graphql-transport-ws
 * protocol</a>
 *
 * @param message
 *            The received JSON message
 */
@SuppressWarnings("unchecked")
public void onNext(WebSocketMessage message) {
    Map<String, Object> map;
    try {
        map = objectMapper.readValue(message.getPayloadAsText(), HashMap.class);
    } catch (JsonProcessingException e) {
        throw new RuntimeException("Error while reading '" + message.getPayloadAsText() + "' as a Map", e);
    }
    String id = (String) map.get("id");
    RequestData<?, ?> subData = null;
    if (id != null) {
        // Let's find the subscription that manages this uniqueIdOperation
        subData = registeredSubscriptions.get(id);
    }
    String type = (String) map.get("type");
    MessageType messageType = MessageType.resolve(type);
    if (messageType == null) {
        // Invalid message. We close the whole session, as described in the protocol
        GraphQlStatus.closeSession(this, session, GraphQlStatus.INVALID_MESSAGE_STATUS, "Invalid message: " + message.getPayloadAsText());
        return;
    }
    switch(messageType) {
        case CONNECTION_ACK:
            logger.trace("Received 'connection_ack' on web socket {}", session);
            // Ok, the connectionInit message has been sent. It's now allowed to send GraphQL
            // subscription on this web socket (see #executeSubscription() in this class)
            webSocketConnectionInitializationLatch.countDown();
            break;
        case NEXT:
            if (logger.isTraceEnabled())
                logger.trace("Received 'next' for id {} on web socket {} (payload={})", id, session, message.getPayloadAsText());
            if (id == null) {
                // Invalid message. We close the whole session, as described in the protocol
                GraphQlStatus.closeSession(this, session, GraphQlStatus.INVALID_MESSAGE_STATUS, "Invalid message (id is null): " + message.getPayloadAsText());
                return;
            }
            if (subData == null) {
                // Oups! The server sent a message with a uniqueIdOperation that is unknown by the client
                // There is nothing in the protocol for this case...
                // We ignore this message, and mark this unknown uniqueIdOperation as complete so that we receive no
                // other message for this uniqueIdOperation
                logger.warn("[graphql-transport-ws] Unknown uniqueIdOperation {} for web socket session {} (a 'complete' message is sent to the server to that he stops managing this uniqueIdOperation)", id, session);
                webSocketEmitter.emit(subData, session.textMessage(encode(id, MessageType.COMPLETE, null)));
            } else if (subData.isCompleted()) {
                logger.warn("Receive a message for a closed uniqueIdOperation ({}) on web socket {}", id, session);
            } else if (map.get("payload") == null) {
                String msg = "payload is mandatory for 'next' messages";
                logger.error(msg);
                subData.onError(new GraphQLRequestExecutionException(msg));
            } else if (!(map.get("payload") instanceof Map)) {
                String msg = "payload should be a Map, but <" + map.get("payload") + "> is not a Map";
                logger.error(msg);
                subData.onError(new GraphQLRequestExecutionException(msg));
            } else {
                subData.onNext((Map<String, Object>) map.get("payload"));
            }
            break;
        case COMPLETE:
            logger.trace("Received 'complete' for id {} on web socket {} (payload={})", id, session, message);
            subData.onComplete();
            break;
        case ERROR:
            logger.warn("Received 'error' for id {} on web socket {} (payload={})", id, session, message.getPayloadAsText());
            // The payload is a list of GraphQLErrors
            if (map.get("payload") instanceof Map) {
                // The payload is one error
                String msg = (String) ((Map<?, ?>) map.get("payload")).get("message");
                subData.onError(new GraphQLRequestExecutionException(msg));
            } else {
                // The payload is a list of errors
                List<Map<String, Object>> errors = (List<Map<String, Object>>) map.get("payload");
                List<String> errorMessages = errors.stream().map(e -> (String) e.get("message")).collect(Collectors.toList());
                subData.onError(new GraphQLRequestExecutionException(errorMessages));
            }
            break;
        default:
            logger.warn("Received non managed message '{}' for id {} on web socket {} (payload={})", type, id, session, message);
            // Oups! This message type exists in MessageType, but is not properly managed here.
            // This is an internal error.
            String msg = "Non managed message type '" + type + "'";
            if (subData != null) {
                subData.onError(new GraphQLRequestExecutionException(msg));
            } else {
                logger.error(msg);
            }
    }
}
Also used : Arrays(java.util.Arrays) Logger(org.slf4j.Logger) WebSocketSession(org.springframework.web.reactive.socket.WebSocketSession) JsonResponseWrapper(com.graphql_java_generator.client.response.JsonResponseWrapper) GraphQLRequestExecutionException(com.graphql_java_generator.exception.GraphQLRequestExecutionException) GraphqlUtils(com.graphql_java_generator.util.GraphqlUtils) CloseStatus(org.springframework.web.reactive.socket.CloseStatus) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) LoggerFactory(org.slf4j.LoggerFactory) IOException(java.io.IOException) HashMap(java.util.HashMap) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Mono(reactor.core.publisher.Mono) Collectors(java.util.stream.Collectors) ArrayList(java.util.ArrayList) TimeUnit(java.util.concurrent.TimeUnit) CountDownLatch(java.util.concurrent.CountDownLatch) Flux(reactor.core.publisher.Flux) List(java.util.List) Map(java.util.Map) WebSocketMessage(org.springframework.web.reactive.socket.WebSocketMessage) Error(com.graphql_java_generator.client.response.Error) Nullable(org.springframework.lang.Nullable) WebSocketHandler(org.springframework.web.reactive.socket.WebSocketHandler) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) List(java.util.List) GraphQLRequestExecutionException(com.graphql_java_generator.exception.GraphQLRequestExecutionException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) Map(java.util.Map)

Aggregations

JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 Error (com.graphql_java_generator.client.response.Error)1 JsonResponseWrapper (com.graphql_java_generator.client.response.JsonResponseWrapper)1 GraphQLRequestExecutionException (com.graphql_java_generator.exception.GraphQLRequestExecutionException)1 GraphqlUtils (com.graphql_java_generator.util.GraphqlUtils)1 IOException (java.io.IOException)1 ArrayList (java.util.ArrayList)1 Arrays (java.util.Arrays)1 HashMap (java.util.HashMap)1 List (java.util.List)1 Map (java.util.Map)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 CountDownLatch (java.util.concurrent.CountDownLatch)1 TimeUnit (java.util.concurrent.TimeUnit)1 Collectors (java.util.stream.Collectors)1 Logger (org.slf4j.Logger)1 LoggerFactory (org.slf4j.LoggerFactory)1 Nullable (org.springframework.lang.Nullable)1 CloseStatus (org.springframework.web.reactive.socket.CloseStatus)1 WebSocketHandler (org.springframework.web.reactive.socket.WebSocketHandler)1