Skip to content

Commit

Permalink
Merge pull request #33942 from tsegismont/vertx_graphql_ws
Browse files Browse the repository at this point in the history
  • Loading branch information
cescoffier authored Jun 10, 2023
2 parents 80f16a5 + 0a01334 commit 55fb3b2
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.graphql.impl.GraphQLBatch;
// import io.vertx.ext.web.handler.graphql.impl.GraphQLInputDeserializer;
import io.vertx.ext.web.handler.graphql.impl.GraphQLQuery;

class VertxGraphqlProcessor {
Expand All @@ -34,14 +33,18 @@ FeatureBuildItem feature() {
}

@BuildStep
WebsocketSubProtocolsBuildItem websocketSubProtocols() {
WebsocketSubProtocolsBuildItem graphQLWSProtocol() {
return new WebsocketSubProtocolsBuildItem("graphql-transport-ws");
}

@BuildStep
WebsocketSubProtocolsBuildItem appoloWSProtocol() {
return new WebsocketSubProtocolsBuildItem("graphql-ws");
}

@BuildStep
List<ReflectiveClassBuildItem> registerForReflection() {
return Arrays.asList(
//new ReflectiveClassBuildItem(true, true, GraphQLInputDeserializer.class.getName()),
ReflectiveClassBuildItem.builder(GraphQLBatch.class.getName()).methods().fields().build(),
ReflectiveClassBuildItem.builder(GraphQLQuery.class.getName()).methods().fields().build());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@
import graphql.schema.idl.TypeDefinitionRegistry;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.handler.graphql.ApolloWSHandler;
import io.vertx.ext.web.handler.graphql.GraphQLHandler;
import io.vertx.ext.web.handler.graphql.ws.GraphQLWSHandler;

@ApplicationScoped
public class VertxGraphqlResource {
Expand All @@ -50,8 +50,9 @@ public void setupRouter(@Observes Router router) {
GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();

router.post().handler(BodyHandler.create());
router.route("/graphql").handler(ApolloWSHandler.create(graphQL));
router.route("/graphql").handler(GraphQLHandler.create(graphQL));
router.route("/graphql")
.handler(GraphQLWSHandler.create(graphQL))
.handler(GraphQLHandler.create(graphQL));
}

}
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package io.quarkus.vertx.graphql.it;

import static io.restassured.RestAssured.given;
import static io.vertx.ext.web.handler.graphql.ws.MessageType.COMPLETE;
import static io.vertx.ext.web.handler.graphql.ws.MessageType.CONNECTION_ACK;
import static io.vertx.ext.web.handler.graphql.ws.MessageType.CONNECTION_INIT;
import static io.vertx.ext.web.handler.graphql.ws.MessageType.NEXT;
import static java.lang.String.format;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
Expand All @@ -24,7 +28,7 @@
import io.vertx.core.http.WebSocket;
import io.vertx.core.http.WebSocketConnectOptions;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.handler.graphql.ApolloWSMessageType;
import io.vertx.ext.web.handler.graphql.ws.MessageType;

@QuarkusTest
class VertxGraphqlTest {
Expand Down Expand Up @@ -57,9 +61,9 @@ public void testGraphQlQuery() {
public void testWebSocketSubProtocol() throws Exception {
HttpClient httpClient = vertx.createHttpClient();
WebSocketConnectOptions options = new WebSocketConnectOptions().setPort(getPortFromConfig())
.addSubProtocol("graphql-ws").setURI("/graphql");
JsonObject init = new JsonObject().put("type", ApolloWSMessageType.CONNECTION_INIT.getText());
String graphql = "{\"id\" : \"2\", \"type\" : \"start\", \"payload\" : { \"query\" : \"{ hello }\" } }";
.addSubProtocol("graphql-transport-ws").setURI("/graphql");
JsonObject init = new JsonObject().put("type", CONNECTION_INIT.getText());
String graphql = "{\"id\" : \"2\", \"type\" : \"subscribe\", \"payload\" : { \"query\" : \"{ hello }\" } }";
CompletableFuture<JsonObject> wsFuture = new CompletableFuture<>();
wsFuture.whenComplete((r, t) -> httpClient.close());

Expand All @@ -73,25 +77,31 @@ public void testWebSocketSubProtocol() throws Exception {
*/

httpClient.webSocket(options, ws -> {
AtomicReference<String> lastReceivedType = new AtomicReference<>();
AtomicReference<MessageType> lastReceivedType = new AtomicReference<>();
AtomicReference<JsonObject> result = new AtomicReference<>();
if (ws.succeeded()) {
WebSocket webSocket = ws.result();
webSocket.handler(message -> {
if (lastReceivedType.compareAndSet(null, ApolloWSMessageType.CONNECTION_ACK.getText())) {
// Go ack, wait for the next message (ka)
} else if (lastReceivedType.compareAndSet("connection_ack",
ApolloWSMessageType.CONNECTION_KEEP_ALIVE.getText())) {
webSocket.write(Buffer.buffer(graphql));
} else {
JsonObject json = message.toJsonObject();
String type = json.getString("type");
if (ApolloWSMessageType.DATA.getText().equals(type)) {
wsFuture.complete(message.toJsonObject());
} else {
wsFuture.completeExceptionally(new RuntimeException(
format("Unexpected message type: %s\nMessage: %s", type, message.toString())));
JsonObject json = message.toJsonObject();
MessageType messageType = MessageType.from(json.getString("type"));
if (messageType == CONNECTION_ACK) {
if (lastReceivedType.compareAndSet(null, CONNECTION_ACK)) {
webSocket.write(Buffer.buffer(graphql));
return;
}
} else if (messageType == NEXT) {
if (lastReceivedType.compareAndSet(CONNECTION_ACK, NEXT)) {
result.set(json);
return;
}
} else if (messageType == COMPLETE) {
if (lastReceivedType.compareAndSet(NEXT, COMPLETE)) {
wsFuture.complete(result.get());
return;
}
}
wsFuture.completeExceptionally(new RuntimeException(
format("Unexpected message type: %s\nMessage: %s", messageType.getText(), message)));
});
webSocket.write(init.toBuffer());
} else {
Expand All @@ -102,7 +112,7 @@ public void testWebSocketSubProtocol() throws Exception {
JsonObject json = wsFuture.get(1, TimeUnit.MINUTES);
assertNotNull(json);
assertEquals("2", json.getString("id"));
assertEquals("data", json.getString("type"));
assertEquals(NEXT.getText(), json.getString("type"));
assertEquals("world", json.getJsonObject("payload").getJsonObject("data").getString("hello"));
}

Expand Down

0 comments on commit 55fb3b2

Please sign in to comment.