Search in sources :

Example 41 with Uni

use of io.smallrye.mutiny.Uni in project smallrye-graphql by smallrye.

the class ReflectionInvoker method invoke.

public <T> T invoke(Object... arguments) throws Exception {
    if (this.injectContextAt > -1) {
        arguments = injectContext(arguments);
    }
    try {
        ManagedInstance<?> operationInstance = lookupService.getInstance(operationClass);
        Object operationInstance1 = operationInstance.get();
        eventEmitter.fireBeforeMethodInvoke(new InvokeInfo(operationInstance1, method, arguments));
        T result = (T) method.invoke(operationInstance1, arguments);
        if (result instanceof Uni) {
            return (T) ((Uni) result).onTermination().invoke(() -> {
                operationInstance.destroyIfNecessary();
            });
        } else if (result instanceof Multi) {
            return (T) ((Multi) result).onTermination().invoke(() -> {
                operationInstance.destroyIfNecessary();
            });
        } else {
            operationInstance.destroyIfNecessary();
            return result;
        }
    } catch (InvocationTargetException ex) {
        // Invoked method has thrown something, unwrap
        Throwable throwable = ex.getCause();
        if (throwable instanceof Error) {
            throw (Error) throwable;
        } else if (throwable instanceof GraphQLException) {
            throw (GraphQLException) throwable;
        } else if (throwable instanceof Exception) {
            throw (Exception) throwable;
        } else {
            throw msg.generalDataFetcherException(operationClass.getName() + ": " + method.getName(), throwable);
        }
    }
}
Also used : Uni(io.smallrye.mutiny.Uni) InvokeInfo(io.smallrye.graphql.execution.event.InvokeInfo) Multi(io.smallrye.mutiny.Multi) GraphQLException(org.eclipse.microprofile.graphql.GraphQLException) InvocationTargetException(java.lang.reflect.InvocationTargetException) PrivilegedActionException(java.security.PrivilegedActionException) GraphQLException(org.eclipse.microprofile.graphql.GraphQLException) InvocationTargetException(java.lang.reflect.InvocationTargetException)

Example 42 with Uni

use of io.smallrye.mutiny.Uni in project smallrye-graphql by smallrye.

the class VertxDynamicGraphQLClient method webSocketHandler.

private Uni<WebSocketSubprotocolHandler> webSocketHandler() {
    return webSocketHandler.updateAndGet(currentValue -> {
        if (currentValue == null) {
            // if we don't have a handler, create a new one
            return Uni.createFrom().<WebSocketSubprotocolHandler>emitter(handlerEmitter -> {
                List<String> subprotocolIds = subprotocols.stream().map(i -> i.getProtocolId()).collect(toList());
                httpClient.webSocketAbs(websocketUrl, headers, WebsocketVersion.V13, subprotocolIds, result -> {
                    if (result.succeeded()) {
                        WebSocket webSocket = result.result();
                        WebSocketSubprotocolHandler handler = BuiltinWebsocketSubprotocolHandlers.createHandlerFor(webSocket.subProtocol(), webSocket, subscriptionInitializationTimeout, () -> {
                            // if the websocket disconnects, remove the handler so we can try
                            // connecting again with a new websocket and handler
                            webSocketHandler.set(null);
                        });
                        handlerEmitter.complete(handler);
                        log.debug("Using websocket subprotocol handler: " + handler);
                    } else {
                        handlerEmitter.fail(result.cause());
                    }
                });
            }).memoize().indefinitely();
        } else {
            return currentValue;
        }
    });
}
Also used : WebClientOptions(io.vertx.ext.web.client.WebClientOptions) WebSocketSubprotocolHandler(io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler) WebClient(io.vertx.ext.web.client.WebClient) Logger(org.jboss.logging.Logger) MultiMap(io.vertx.core.MultiMap) Response(io.smallrye.graphql.client.Response) WebsocketVersion(io.vertx.core.http.WebsocketVersion) AtomicReference(java.util.concurrent.atomic.AtomicReference) Multi(io.smallrye.mutiny.Multi) Uni(io.smallrye.mutiny.Uni) ResponseReader(io.smallrye.graphql.client.impl.ResponseReader) Document(io.smallrye.graphql.client.core.Document) Map(java.util.Map) WebsocketSubprotocol(io.smallrye.graphql.client.websocket.WebsocketSubprotocol) JsonObject(javax.json.JsonObject) RequestImpl(io.smallrye.graphql.client.impl.RequestImpl) BuiltinWebsocketSubprotocolHandlers(io.smallrye.graphql.client.vertx.websocket.BuiltinWebsocketSubprotocolHandlers) DynamicGraphQLClient(io.smallrye.graphql.client.dynamic.api.DynamicGraphQLClient) Vertx(io.vertx.core.Vertx) WebSocket(io.vertx.core.http.WebSocket) Collectors(java.util.stream.Collectors) Request(io.smallrye.graphql.client.Request) ExecutionException(java.util.concurrent.ExecutionException) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List) Buffer(io.vertx.core.buffer.Buffer) Collections(java.util.Collections) HttpClient(io.vertx.core.http.HttpClient) WebSocketSubprotocolHandler(io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler) WebSocket(io.vertx.core.http.WebSocket)

Example 43 with Uni

use of io.smallrye.mutiny.Uni in project smallrye-graphql by smallrye.

the class VertxTypesafeGraphQLClientProxy method webSocketHandler.

private Uni<WebSocketSubprotocolHandler> webSocketHandler() {
    return webSocketHandler.updateAndGet(currentValue -> {
        if (currentValue == null) {
            return Uni.createFrom().<WebSocketSubprotocolHandler>emitter(handlerEmitter -> {
                List<String> subprotocolIds = subprotocols.stream().map(i -> i.getProtocolId()).collect(toList());
                MultiMap headers = HeadersMultiMap.headers().addAll(new HeaderBuilder(api, null, additionalHeaders).build());
                httpClient.webSocketAbs(websocketUrl, headers, WebsocketVersion.V13, subprotocolIds, result -> {
                    if (result.succeeded()) {
                        WebSocket webSocket = result.result();
                        WebSocketSubprotocolHandler handler = BuiltinWebsocketSubprotocolHandlers.createHandlerFor(webSocket.subProtocol(), webSocket, subscriptionInitializationTimeout, () -> {
                            webSocketHandler.set(null);
                        });
                        handlerEmitter.complete(handler);
                        log.debug("Using websocket subprotocol handler: " + handler);
                    } else {
                        handlerEmitter.fail(result.cause());
                    }
                });
            }).memoize().indefinitely();
        } else {
            return currentValue;
        }
    });
}
Also used : WebSocketSubprotocolHandler(io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler) Arrays(java.util.Arrays) Array(java.lang.reflect.Array) JsonArrayBuilder(javax.json.JsonArrayBuilder) HttpResponse(io.vertx.ext.web.client.HttpResponse) WebClient(io.vertx.ext.web.client.WebClient) Date(java.util.Date) JsonBuilderFactory(javax.json.JsonBuilderFactory) Logger(org.jboss.logging.Logger) MultiMap(io.vertx.core.MultiMap) HashMap(java.util.HashMap) WebsocketVersion(io.vertx.core.http.WebsocketVersion) AtomicReference(java.util.concurrent.atomic.AtomicReference) Multi(io.smallrye.mutiny.Multi) ArrayList(java.util.ArrayList) Uni(io.smallrye.mutiny.Uni) HeadersMultiMap(io.vertx.core.http.impl.headers.HeadersMultiMap) JsonValue(javax.json.JsonValue) BigDecimal(java.math.BigDecimal) Map(java.util.Map) Json(javax.json.Json) MethodInvocation(io.smallrye.graphql.client.impl.typesafe.reflection.MethodInvocation) BigInteger(java.math.BigInteger) HeaderBuilder(io.smallrye.graphql.client.impl.typesafe.HeaderBuilder) URI(java.net.URI) InvalidResponseException(io.smallrye.graphql.client.InvalidResponseException) WebsocketSubprotocol(io.smallrye.graphql.client.websocket.WebsocketSubprotocol) JsonObject(javax.json.JsonObject) BuiltinWebsocketSubprotocolHandlers(io.smallrye.graphql.client.vertx.websocket.BuiltinWebsocketSubprotocolHandlers) FieldInfo(io.smallrye.graphql.client.impl.typesafe.reflection.FieldInfo) Collection(java.util.Collection) ResultBuilder(io.smallrye.graphql.client.impl.typesafe.ResultBuilder) JsonArray(javax.json.JsonArray) WebSocket(io.vertx.core.http.WebSocket) Future(io.vertx.core.Future) ExecutionException(java.util.concurrent.ExecutionException) Collectors.toList(java.util.stream.Collectors.toList) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) Stream(java.util.stream.Stream) Buffer(io.vertx.core.buffer.Buffer) QueryBuilder(io.smallrye.graphql.client.impl.typesafe.QueryBuilder) TypeInfo(io.smallrye.graphql.client.impl.typesafe.reflection.TypeInfo) JsonObjectBuilder(javax.json.JsonObjectBuilder) HttpClient(io.vertx.core.http.HttpClient) MultiMap(io.vertx.core.MultiMap) HeadersMultiMap(io.vertx.core.http.impl.headers.HeadersMultiMap) HeaderBuilder(io.smallrye.graphql.client.impl.typesafe.HeaderBuilder) WebSocketSubprotocolHandler(io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler) WebSocket(io.vertx.core.http.WebSocket)

Example 44 with Uni

use of io.smallrye.mutiny.Uni in project smallrye-graphql by smallrye.

the class GraphQLWSSubprotocolHandler method initialize.

private Uni<Void> initialize() {
    return Uni.createFrom().emitter(initializationEmitter -> {
        if (log.isTraceEnabled()) {
            log.trace("Initializing websocket with graphql-ws protocol");
        }
        webSocket.closeHandler((v) -> {
            onClose.run();
            if (webSocket.closeStatusCode() != null) {
                if (webSocket.closeStatusCode() == 1000) {
                    log.debug("WebSocket closed with status code 1000");
                    // even if the status code is OK, any unfinished single-result operation
                    // should be marked as failed
                    uniOperations.forEach((id, emitter) -> emitter.fail(new InvalidResponseException("Connection closed before data was received")));
                    multiOperations.forEach((id, emitter) -> emitter.complete());
                } else {
                    InvalidResponseException exception = new InvalidResponseException("Server closed the websocket connection with code: " + webSocket.closeStatusCode() + " and reason: " + webSocket.closeReason());
                    uniOperations.forEach((id, emitter) -> emitter.fail(exception));
                    multiOperations.forEach((id, emitter) -> emitter.fail(exception));
                }
            } else {
                InvalidResponseException exception = new InvalidResponseException("Connection closed");
                uniOperations.forEach((id, emitter) -> emitter.fail(exception));
                multiOperations.forEach((id, emitter) -> emitter.fail(exception));
            }
        });
        webSocket.exceptionHandler(this::failAllActiveOperationsWith);
        send(webSocket, createConnectionInitMessage());
        // set up a timeout for subscription initialization
        Cancellable timeoutWaitingForConnectionAckMessage = null;
        if (subscriptionInitializationTimeout != null) {
            timeoutWaitingForConnectionAckMessage = Uni.createFrom().item(1).onItem().delayIt().by(Duration.ofMillis(subscriptionInitializationTimeout)).subscribe().with(timeout -> {
                initializationEmitter.fail(new InvalidResponseException("Server did not send a connection_ack message"));
                webSocket.close((short) 1002, "Timeout waiting for a connection_ack message");
            });
        }
        // make an effectively final copy of this value to use it in a lambda expression
        Cancellable finalTimeoutWaitingForConnectionAckMessage = timeoutWaitingForConnectionAckMessage;
        webSocket.handler(text -> {
            if (log.isTraceEnabled()) {
                log.trace("<<< " + text);
            }
            try {
                JsonObject message = parseIncomingMessage(text.toString());
                MessageType messageType = getMessageType(message);
                switch(messageType) {
                    case GQL_CONNECTION_ERROR:
                        failAllActiveOperationsWith(new InvalidResponseException(message.get("payload").toString()));
                        webSocket.close();
                        break;
                    case GQL_CONNECTION_ACK:
                        if (finalTimeoutWaitingForConnectionAckMessage != null) {
                            finalTimeoutWaitingForConnectionAckMessage.cancel();
                        }
                        initializationEmitter.complete(null);
                        break;
                    case GQL_DATA:
                        handleData(message.getString("id"), message.getJsonObject("payload"));
                        break;
                    case GQL_ERROR:
                        handleOperationError(message.getString("id"), message.getJsonObject("payload"));
                        break;
                    case GQL_COMPLETE:
                        handleComplete(message.getString("id"));
                        break;
                    case GQL_START:
                    case GQL_STOP:
                    case GQL_CONNECTION_KEEP_ALIVE:
                    case GQL_CONNECTION_INIT:
                    case GQL_CONNECTION_TERMINATE:
                        break;
                }
            } catch (JsonParsingException | IllegalArgumentException e) {
                log.error("Unexpected message from server: " + text);
            // should we fail the operations here?
            }
        });
    });
}
Also used : JsonObject(javax.json.JsonObject) WebSocketSubprotocolHandler(io.smallrye.graphql.client.vertx.websocket.WebSocketSubprotocolHandler) GraphQLClientException(io.smallrye.graphql.client.GraphQLClientException) MultiEmitter(io.smallrye.mutiny.subscription.MultiEmitter) Logger(org.jboss.logging.Logger) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) UniEmitter(io.smallrye.mutiny.subscription.UniEmitter) CompletableFuture(java.util.concurrent.CompletableFuture) WebSocket(io.vertx.core.http.WebSocket) JsonString(javax.json.JsonString) Uni(io.smallrye.mutiny.Uni) JsonValue(javax.json.JsonValue) ResponseReader(io.smallrye.graphql.client.impl.ResponseReader) IncrementingNumberOperationIDGenerator(io.smallrye.graphql.client.vertx.websocket.opid.IncrementingNumberOperationIDGenerator) StringReader(java.io.StringReader) GraphQLError(io.smallrye.graphql.client.GraphQLError) OperationIDGenerator(io.smallrye.graphql.client.vertx.websocket.opid.OperationIDGenerator) Duration(java.time.Duration) Map(java.util.Map) Json(javax.json.Json) Cancellable(io.smallrye.mutiny.subscription.Cancellable) JsonParsingException(javax.json.stream.JsonParsingException) JsonObjectBuilder(javax.json.JsonObjectBuilder) InvalidResponseException(io.smallrye.graphql.client.InvalidResponseException) Cancellable(io.smallrye.mutiny.subscription.Cancellable) JsonObject(javax.json.JsonObject) InvalidResponseException(io.smallrye.graphql.client.InvalidResponseException) JsonParsingException(javax.json.stream.JsonParsingException)

Aggregations

Uni (io.smallrye.mutiny.Uni)44 Multi (io.smallrye.mutiny.Multi)21 Test (org.junit.jupiter.api.Test)18 List (java.util.List)17 Assertions.assertThat (org.assertj.core.api.Assertions.assertThat)17 Duration (java.time.Duration)16 AtomicBoolean (java.util.concurrent.atomic.AtomicBoolean)14 IOException (java.io.IOException)13 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)13 AtomicReference (java.util.concurrent.atomic.AtomicReference)13 Assertions.assertThrows (org.junit.jupiter.api.Assertions.assertThrows)13 AssertSubscriber (io.smallrye.mutiny.helpers.test.AssertSubscriber)12 Function (java.util.function.Function)12 Supplier (java.util.function.Supplier)12 Map (java.util.Map)11 Consumer (java.util.function.Consumer)10 CompositeException (io.smallrye.mutiny.CompositeException)9 ArrayList (java.util.ArrayList)9 ApplicationScoped (javax.enterprise.context.ApplicationScoped)8 CompletableFuture (java.util.concurrent.CompletableFuture)7