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);
}
}
}
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;
}
});
}
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;
}
});
}
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?
}
});
});
}
Aggregations