Search in sources :

Example 1 with ApolloWSMessage

use of io.vertx.ext.web.handler.graphql.ApolloWSMessage in project vertx-web by vert-x3.

the class ApolloWSConnectionHandler method start.

private void start(ApolloWSMessage message) {
    String opId = message.content().getString("id");
    // Unsubscribe if it's subscribed
    if (subscriptions.containsKey(opId)) {
        stop(opId);
    }
    GraphQLQuery payload = new GraphQLQuery(message.content().getJsonObject("payload"));
    ExecutionInput.Builder builder = ExecutionInput.newExecutionInput();
    builder.query(payload.getQuery());
    builder.context(apolloWSHandler.getQueryContext().apply(message));
    DataLoaderRegistry registry = apolloWSHandler.getDataLoaderRegistry().apply(message);
    if (registry != null) {
        builder.dataLoaderRegistry(registry);
    }
    Locale locale = apolloWSHandler.getLocale().apply(message);
    if (locale != null) {
        builder.locale(locale);
    }
    String operationName = payload.getOperationName();
    if (operationName != null) {
        builder.operationName(operationName);
    }
    Map<String, Object> variables = payload.getVariables();
    if (variables != null) {
        builder.variables(variables);
    }
    Object initialValue = payload.getInitialValue();
    if (initialValue != null) {
        builder.root(initialValue);
    }
    Handler<ExecutionInputBuilderWithContext<ApolloWSMessage>> beforeExecute = apolloWSHandler.getBeforeExecute();
    if (beforeExecute != null) {
        beforeExecute.handle(new ExecutionInputBuilderWithContext<ApolloWSMessage>() {

            @Override
            public ApolloWSMessage context() {
                return message;
            }

            @Override
            public ExecutionInput.Builder builder() {
                return builder;
            }
        });
    }
    builder.graphQLContext(Collections.singletonMap(ApolloWSMessage.class, message));
    apolloWSHandler.getGraphQL().executeAsync(builder).whenCompleteAsync((executionResult, throwable) -> {
        if (throwable == null) {
            if (executionResult.getData() instanceof Publisher) {
                subscribe(opId, executionResult);
            } else {
                sendMessage(opId, DATA, new JsonObject(executionResult.toSpecification()));
                sendMessage(opId, COMPLETE, null);
            }
        } else {
            if (log.isDebugEnabled()) {
                log.debug("Failed to execute GraphQL query, opId=" + opId, throwable);
            }
            sendMessage(opId, ERROR, toJsonObject(throwable));
        }
    }, executor);
}
Also used : Locale(java.util.Locale) ApolloWSMessage(io.vertx.ext.web.handler.graphql.ApolloWSMessage) JsonObject(io.vertx.core.json.JsonObject) ErrorUtil.toJsonObject(io.vertx.ext.web.handler.graphql.impl.ErrorUtil.toJsonObject) Publisher(org.reactivestreams.Publisher) ExecutionInputBuilderWithContext(io.vertx.ext.web.handler.graphql.ExecutionInputBuilderWithContext) DataLoaderRegistry(org.dataloader.DataLoaderRegistry) JsonObject(io.vertx.core.json.JsonObject) ErrorUtil.toJsonObject(io.vertx.ext.web.handler.graphql.impl.ErrorUtil.toJsonObject) ExecutionInput(graphql.ExecutionInput)

Example 2 with ApolloWSMessage

use of io.vertx.ext.web.handler.graphql.ApolloWSMessage in project vertx-web by vert-x3.

the class ApolloWSConnectionHandler method handleMessage.

private void handleMessage(JsonObject jsonObject) {
    String opId = jsonObject.getString("id");
    ApolloWSMessageType type = from(jsonObject.getString("type"));
    if (type == null) {
        sendMessage(opId, ERROR, "Unknown message type: " + jsonObject.getString("type"));
        return;
    }
    ApolloWSMessageImpl message = new ApolloWSMessageImpl(serverWebSocket, type, jsonObject);
    Handler<ApolloWSMessage> mh = apolloWSHandler.getMessageHandler();
    if (mh != null) {
        mh.handle(message);
    }
    Handler<ApolloWSConnectionInitEvent> connectionInitHandler = apolloWSHandler.getConnectionInitHandler();
    switch(type) {
        case CONNECTION_INIT:
            if (!connectionInitialized.compareAndSet(false, true)) {
                sendMessage(opId, ERROR, "CONNECTION_INIT can only be sent once").onComplete(v -> serverWebSocket.close(WS_INTERNAL_ERROR));
                break;
            }
            if (connectionInitHandler != null) {
                connectionInitHandler.handle(new ApolloWSConnectionInitEvent() {

                    @Override
                    public ApolloWSMessage message() {
                        return message;
                    }

                    @Override
                    public boolean tryComplete(Object o) {
                        return connectionPromise.tryComplete(o);
                    }

                    @Override
                    public boolean tryFail(Throwable throwable) {
                        return connectionPromise.tryFail(throwable);
                    }

                    @Override
                    public Future<Object> future() {
                        return connectionPromise.future();
                    }
                });
            } else {
                connectionPromise.complete();
            }
            connectionPromise.future().onComplete(ar -> {
                if (ar.succeeded()) {
                    connect();
                } else {
                    sendMessage(opId, CONNECTION_ERROR, ar.cause().getMessage()).onComplete(v -> serverWebSocket.close(WS_INTERNAL_ERROR));
                }
            });
            break;
        case CONNECTION_TERMINATE:
            serverWebSocket.close();
            break;
        case START:
            if (!connectionInitialized.get()) {
                sendMessage(opId, ERROR, "CONNECTION_INIT has to be sent before START").onComplete(v -> serverWebSocket.close(WS_INTERNAL_ERROR));
                break;
            }
            connectionPromise.future().onComplete(ar -> {
                if (ar.succeeded()) {
                    ApolloWSMessage messageWithParams = new ApolloWSMessageImpl(serverWebSocket, type, jsonObject, ar.result());
                    start(messageWithParams);
                } else {
                    sendMessage(opId, ERROR, ar.cause().getMessage());
                    stop(opId);
                }
            });
            break;
        case STOP:
            stop(opId);
            break;
        default:
            sendMessage(opId, ERROR, "Unsupported message type: " + type);
            break;
    }
}
Also used : ApolloWSConnectionInitEvent(io.vertx.ext.web.handler.graphql.ApolloWSConnectionInitEvent) ApolloWSMessageType(io.vertx.ext.web.handler.graphql.ApolloWSMessageType) ApolloWSMessage(io.vertx.ext.web.handler.graphql.ApolloWSMessage) Future(io.vertx.core.Future) JsonObject(io.vertx.core.json.JsonObject) ErrorUtil.toJsonObject(io.vertx.ext.web.handler.graphql.impl.ErrorUtil.toJsonObject)

Aggregations

JsonObject (io.vertx.core.json.JsonObject)2 ApolloWSMessage (io.vertx.ext.web.handler.graphql.ApolloWSMessage)2 ErrorUtil.toJsonObject (io.vertx.ext.web.handler.graphql.impl.ErrorUtil.toJsonObject)2 ExecutionInput (graphql.ExecutionInput)1 Future (io.vertx.core.Future)1 ApolloWSConnectionInitEvent (io.vertx.ext.web.handler.graphql.ApolloWSConnectionInitEvent)1 ApolloWSMessageType (io.vertx.ext.web.handler.graphql.ApolloWSMessageType)1 ExecutionInputBuilderWithContext (io.vertx.ext.web.handler.graphql.ExecutionInputBuilderWithContext)1 Locale (java.util.Locale)1 DataLoaderRegistry (org.dataloader.DataLoaderRegistry)1 Publisher (org.reactivestreams.Publisher)1