Skip to content

Commit

Permalink
SCI's can't add websocket endpoints
Browse files Browse the repository at this point in the history
Fixes #19781
  • Loading branch information
stuartwdouglas committed Sep 6, 2021
1 parent 9eb3e8b commit fc511ef
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -523,7 +523,11 @@ public void run() {
}

public void addServletContextAttribute(RuntimeValue<DeploymentInfo> deployment, String key, Object value1) {
deployment.getValue().addServletContextAttribute(key, value1);
if (value1 instanceof RuntimeValue) {
deployment.getValue().addServletContextAttribute(key, ((RuntimeValue<?>) value1).getValue());
} else {
deployment.getValue().addServletContextAttribute(key, value1);
}
}

public void addServletExtension(RuntimeValue<DeploymentInfo> deployment, ServletExtension extension) {
Expand Down
4 changes: 4 additions & 0 deletions extensions/websockets/client/deployment/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
<groupId>io.quarkus</groupId>
<artifactId>quarkus-websockets-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-undertow-spi</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-internal</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import javax.websocket.ContainerProvider;
import javax.websocket.Endpoint;
import javax.websocket.server.ServerApplicationConfig;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;

import org.jboss.jandex.AnnotationInstance;
Expand All @@ -34,10 +35,11 @@
import io.quarkus.deployment.builditem.ServiceStartBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem;
import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem;
import io.quarkus.netty.deployment.EventLoopSupplierBuildItem;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.undertow.deployment.ServletContextAttributeBuildItem;
import io.quarkus.undertow.websockets.client.runtime.WebsocketCoreRecorder;
import io.undertow.websockets.DefaultContainerConfigurator;
import io.undertow.websockets.ServerWebSocketContainer;
import io.undertow.websockets.UndertowContainerProvider;
import io.undertow.websockets.WebSocketDeploymentInfo;

Expand Down Expand Up @@ -70,16 +72,16 @@ void scanForAnnotatedEndpoints(CombinedIndexBuildItem indexBuildItem,
}

@BuildStep
@Record(ExecutionTime.RUNTIME_INIT)
@Record(ExecutionTime.STATIC_INIT)
public ServerWebSocketContainerBuildItem deploy(final CombinedIndexBuildItem indexBuildItem,
WebsocketCoreRecorder recorder,
BuildProducer<ReflectiveClassBuildItem> reflection,
EventLoopSupplierBuildItem eventLoopSupplierBuildItem,
List<AnnotatedWebsocketEndpointBuildItem> annotatedEndpoints,
BeanContainerBuildItem beanContainerBuildItem,
WebsocketConfig websocketConfig,
BuildProducer<WebSocketDeploymentInfoBuildItem> infoBuildItemBuildProducer,
Optional<ServerWebSocketContainerFactoryBuildItem> factoryBuildItem) throws Exception {
Optional<ServerWebSocketContainerFactoryBuildItem> factoryBuildItem,
BuildProducer<ServletContextAttributeBuildItem> servletContextAttributeBuildItemBuildProducer) throws Exception {

final Set<String> endpoints = new HashSet<>();
final Set<String> config = new HashSet<>();
Expand Down Expand Up @@ -121,10 +123,14 @@ public ServerWebSocketContainerBuildItem deploy(final CombinedIndexBuildItem ind
websocketConfig.maxFrameSize,
websocketConfig.dispatchToWorker);
infoBuildItemBuildProducer.produce(new WebSocketDeploymentInfoBuildItem(deploymentInfo));
RuntimeValue<ServerWebSocketContainer> serverContainer = recorder.createServerContainer(
beanContainerBuildItem.getValue(),
deploymentInfo,
factoryBuildItem.map(ServerWebSocketContainerFactoryBuildItem::getFactory).orElse(null));
servletContextAttributeBuildItemBuildProducer
.produce(new ServletContextAttributeBuildItem(ServerContainer.class.getName(), serverContainer));
return new ServerWebSocketContainerBuildItem(
recorder.createServerContainer(beanContainerBuildItem.getValue(), eventLoopSupplierBuildItem.getMainSupplier(),
deploymentInfo,
factoryBuildItem.map(ServerWebSocketContainerFactoryBuildItem::getFactory).orElse(null)));
serverContainer);
}

public static void registerCodersForReflection(BuildProducer<ReflectiveClassBuildItem> reflection,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@
import io.quarkus.arc.runtime.BeanContainer;
import io.quarkus.runtime.RuntimeValue;
import io.quarkus.runtime.annotations.Recorder;
import io.quarkus.vertx.core.runtime.VertxCoreRecorder;
import io.undertow.websockets.ServerWebSocketContainer;
import io.undertow.websockets.UndertowContainerProvider;
import io.undertow.websockets.WebSocketDeploymentInfo;
import io.undertow.websockets.util.ContextSetupHandler;
import io.undertow.websockets.util.ObjectFactory;
import io.undertow.websockets.util.ObjectHandle;
import io.undertow.websockets.util.ObjectIntrospecter;
import io.vertx.core.impl.VertxInternal;

@Recorder
public class WebsocketCoreRecorder {
Expand Down Expand Up @@ -105,7 +107,6 @@ public RuntimeValue<WebSocketDeploymentInfo> createDeploymentInfo(Set<String> an
}

public RuntimeValue<ServerWebSocketContainer> createServerContainer(BeanContainer beanContainer,
Supplier<EventLoopGroup> eventLoopGroupSupplier,
RuntimeValue<WebSocketDeploymentInfo> infoVal, ServerWebSocketContainerFactory serverContainerFactory)
throws DeploymentException {
WebSocketDeploymentInfo info = infoVal.getValue();
Expand Down Expand Up @@ -136,7 +137,12 @@ public void release() {
}
};
}
}, Thread.currentThread().getContextClassLoader(), eventLoopGroupSupplier,
}, Thread.currentThread().getContextClassLoader(), new Supplier<EventLoopGroup>() {
@Override
public EventLoopGroup get() {
return ((VertxInternal) VertxCoreRecorder.getVertx().get()).getEventLoopGroup();
}
},
Collections.singletonList(new ContextSetupHandler() {
@Override
public <T, C> Action<T, C> create(Action<T, C> action) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package io.quarkus.it.websocket;

import javax.enterprise.inject.spi.DeploymentException;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import javax.websocket.Endpoint;
import javax.websocket.EndpointConfig;
import javax.websocket.Session;
import javax.websocket.server.ServerContainer;
import javax.websocket.server.ServerEndpointConfig;

@WebListener
public class AddWebSocketHandler implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
}

@Override
public void contextInitialized(ServletContextEvent sce) {
try {
((ServerContainer) sce.getServletContext().getAttribute(ServerContainer.class.getName()))
.addEndpoint(ServerEndpointConfig.Builder.create(WebsockEndpoint.class, "/added-dynamic").build());

} catch (DeploymentException | javax.websocket.DeploymentException e) {
throw new RuntimeException(e);
}
}

public static class WebsockEndpoint extends Endpoint {

@Override
public void onOpen(Session session, EndpointConfig config) {
session.getAsyncRemote().sendText("DYNAMIC");
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class WebsocketTestCase {

@TestHTTPResource("wsopen")
URI openURI;
@TestHTTPResource("added-dynamic")
URI added;

@Test
public void websocketTest() throws Exception {
Expand All @@ -57,6 +59,29 @@ public void onMessage(String s) {
}
}

@Test
public void addedWebSocketTest() throws Exception {

LinkedBlockingDeque<String> message = new LinkedBlockingDeque<>();
Session session = ContainerProvider.getWebSocketContainer().connectToServer(new Endpoint() {
@Override
public void onOpen(Session session, EndpointConfig endpointConfig) {
session.addMessageHandler(new MessageHandler.Whole<String>() {
@Override
public void onMessage(String s) {
message.add(s);
}
});
}
}, ClientEndpointConfig.Builder.create().build(), added);

try {
Assertions.assertEquals("DYNAMIC", message.poll(20, TimeUnit.SECONDS));
} finally {
session.close();
}
}

@Test
public void websocketServerEncodingAndDecodingTest() throws Exception {
LinkedBlockingDeque<String> message = new LinkedBlockingDeque<>();
Expand Down

0 comments on commit fc511ef

Please sign in to comment.