Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WebSockets Next: Dev UI fixes #41779

Merged
merged 2 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public void pages(List<WebSocketEndpointBuildItem> endpoints, List<GeneratedEndp
.title("Server Endpoints")
.icon("font-awesome-solid:plug")
.componentLink("qwc-wsn-endpoints.js")
.staticLabel(String.valueOf(endpoints.size())));
.staticLabel(String.valueOf(endpoints.stream().filter(WebSocketEndpointBuildItem::isServer).count())));

cardPages.produce(pageBuildItem);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package io.quarkus.websockets.next.test.devmode;

import static org.junit.jupiter.api.Assertions.assertEquals;

import jakarta.enterprise.event.Observes;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusDevModeTest;
import io.quarkus.websockets.next.BasicWebSocketConnector;
import io.restassured.RestAssured;
import io.vertx.ext.web.Router;

/**
* Just to make sure the Dev UI is not broken if no server endpoint is defined.
*/
public class NoServerEndpointDevModeTest {

@RegisterExtension
static final QuarkusDevModeTest testConfig = new QuarkusDevModeTest()
.withApplicationRoot(root -> root
.addClass(MyBean.class));

@Test
public void testConnectorIsInjected() {
assertEquals("1", RestAssured.get("mybeantest").then().statusCode(200).extract().body().asString());
}

@Singleton
public static class MyBean {

@Inject
BasicWebSocketConnector connector;

void addRoute(@Observes Router router) {
router.get("/mybeantest").handler(rc -> {
rc.end(connector != null ? "1" : "0");
});
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -116,10 +116,7 @@ public Uni<WebSocketClientConnection> connect() {
// TODO would it make sense to share clients?
WebSocketClient client = vertx.createWebSocketClient(populateClientOptions());

WebSocketConnectOptions connectOptions = new WebSocketConnectOptions()
.setSsl(baseUri.getScheme().equals("https"))
.setHost(baseUri.getHost())
.setPort(baseUri.getPort());
WebSocketConnectOptions connectOptions = newConnectOptions(baseUri);
StringBuilder requestUri = new StringBuilder();
String mergedPath = mergePath(baseUri.getPath(), replacePathParameters(path));
requestUri.append(mergedPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import io.vertx.core.Vertx;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.http.WebSocketClientOptions;
import io.vertx.core.http.WebSocketConnectOptions;
import io.vertx.core.net.SSLOptions;

abstract class WebSocketConnectorBase<THIS extends WebSocketConnectorBase<THIS>> {
Expand Down Expand Up @@ -191,4 +192,21 @@ protected WebSocketClientOptions populateClientOptions() {
}
return clientOptions;
}

protected WebSocketConnectOptions newConnectOptions(URI serverEndpointUri) {
WebSocketConnectOptions connectOptions = new WebSocketConnectOptions()
.setSsl(isHttps(serverEndpointUri))
.setHost(serverEndpointUri.getHost());
if (serverEndpointUri.getPort() != -1) {
connectOptions.setPort(serverEndpointUri.getPort());
} else if (isHttps(serverEndpointUri)) {
// If port is undefined and https is used then use 443 by default
connectOptions.setPort(443);
}
return connectOptions;
}

protected boolean isHttps(URI uri) {
return "https".equals(uri.getScheme());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,7 @@ public Uni<WebSocketClientConnection> connect() {
throw new WebSocketClientException(e);
}

WebSocketConnectOptions connectOptions = new WebSocketConnectOptions()
.setSsl(serverEndpointUri.getScheme().equals("https"))
.setHost(serverEndpointUri.getHost())
.setPort(serverEndpointUri.getPort());
WebSocketConnectOptions connectOptions = newConnectOptions(serverEndpointUri);
StringBuilder uri = new StringBuilder();
if (serverEndpointUri.getPath() != null) {
uri.append(serverEndpointUri.getRawPath());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import java.util.concurrent.ConcurrentMap;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.enterprise.inject.Instance;

import org.jboss.logging.Logger;

Expand Down Expand Up @@ -52,16 +53,18 @@ public class WebSocketNextJsonRPCService implements ConnectionListener {

private final WebSocketsServerRuntimeConfig.DevMode devModeConfig;

WebSocketNextJsonRPCService(ConnectionManager connectionManager, Vertx vertx, HttpConfiguration httpConfig,
WebSocketNextJsonRPCService(Instance<ConnectionManager> connectionManager, Vertx vertx, HttpConfiguration httpConfig,
WebSocketsServerRuntimeConfig config) {
this.connectionStatus = BroadcastProcessor.create();
this.connectionMessages = BroadcastProcessor.create();
this.connectionManager = connectionManager;
this.connectionManager = connectionManager.isResolvable() ? connectionManager.get() : null;
this.vertx = vertx;
this.httpConfig = httpConfig;
this.devModeConfig = config.devMode();
this.sockets = new ConcurrentHashMap<>();
connectionManager.addListener(this);
if (this.connectionManager != null) {
this.connectionManager.addListener(this);
}
}

public Multi<JsonObject> connectionStatus() {
Expand All @@ -74,14 +77,16 @@ public Multi<JsonObject> connectionMessages() {

public JsonObject getConnections(List<String> endpoints) {
JsonObject json = new JsonObject();
for (String endpoint : endpoints) {
List<WebSocketConnection> connections = new ArrayList<>(connectionManager.getConnections(endpoint));
connections.sort(Comparator.comparing(WebSocketConnection::creationTime));
JsonArray array = new JsonArray();
for (WebSocketConnection c : connections) {
array.add(toJsonObject(endpoint, c));
if (connectionManager != null) {
for (String endpoint : endpoints) {
List<WebSocketConnection> connections = new ArrayList<>(connectionManager.getConnections(endpoint));
connections.sort(Comparator.comparing(WebSocketConnection::creationTime));
JsonArray array = new JsonArray();
for (WebSocketConnection c : connections) {
array.add(toJsonObject(endpoint, c));
}
json.put(endpoint, array);
}
json.put(endpoint, array);
}
json.put("connectionMessagesLimit", devModeConfig.connectionMessagesLimit());
return json;
Expand All @@ -103,6 +108,9 @@ public JsonArray getMessages(String connectionKey) {
}

public Uni<JsonObject> openDevConnection(String path, String endpointPath) {
if (connectionManager == null) {
return failureUni();
}
if (isInvalidPath(path, endpointPath)) {
LOG.errorf("Invalid path %s; original endpoint path %s", path, endpointPath);
return failureUni();
Expand Down Expand Up @@ -179,6 +187,9 @@ private static String normalize(String path) {
}

public Uni<JsonObject> closeDevConnection(String connectionKey) {
if (connectionManager == null) {
return failureUni();
}
DevWebSocket socket = sockets.remove(connectionKey);
if (socket != null) {
Uni<Void> uni = Uni.createFrom().completionStage(() -> socket.socket.close().toCompletionStage());
Expand Down