use of io.undertow.websockets.jsr.DefaultContainerConfigurator in project openremote by openremote.
the class DefaultWebsocketComponent method deploy.
@Override
protected void deploy() throws Exception {
WebSocketDeploymentInfo webSocketDeploymentInfo = new WebSocketDeploymentInfo();
getConsumers().entrySet().forEach(consumerEntry -> {
String endpointPath = MessageBrokerSetupService.WEBSOCKET_PATH + "/" + consumerEntry.getKey();
LOG.info("Deploying websocket endpoint: " + endpointPath);
webSocketDeploymentInfo.addEndpoint(ServerEndpointConfig.Builder.create(WebsocketAdapter.class, endpointPath).configurator(new DefaultContainerConfigurator() {
@SuppressWarnings("unchecked")
@Override
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
return (T) new WebsocketAdapter(consumerEntry.getValue());
}
@SuppressWarnings("unchecked")
@Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
Principal principal = request.getUserPrincipal();
if (principal == null) {
throw new WebApplicationException("Request is not authenticated, can't access user principal", FORBIDDEN);
}
AuthContext authContext;
if (principal instanceof KeycloakPrincipal) {
KeycloakPrincipal keycloakPrincipal = (KeycloakPrincipal) principal;
authContext = new AccessTokenAuthContext(keycloakPrincipal.getKeycloakSecurityContext().getRealm(), keycloakPrincipal.getKeycloakSecurityContext().getToken());
} else if (principal instanceof BasicAuthContext) {
authContext = (BasicAuthContext) principal;
} else {
throw new WebApplicationException("Unsupported user principal type: " + principal, INTERNAL_SERVER_ERROR);
}
config.getUserProperties().put(WebsocketConstants.HANDSHAKE_AUTH, authContext);
super.modifyHandshake(config, request, response);
}
}).build());
});
// We use the I/O thread to handle received websocket frames, as we expect to quickly hand them over to
// an internal asynchronous message queue for processing, so we don't need a separate worker thread
// pool for websocket frame processing
webSocketDeploymentInfo.setDispatchToWorkerThread(false);
// Make the shit Undertow/Websocket JSR client bootstrap happy - this is the pool that would be used
// when Undertow acts as a WebSocket client, which we don't do... and I'm not even sure it can do that...
webSocketDeploymentInfo.setWorker(Xnio.getInstance().createWorker(OptionMap.builder().set(Options.WORKER_TASK_MAX_THREADS, 1).set(Options.WORKER_NAME, "WebsocketInternalClient").set(Options.THREAD_DAEMON, true).getMap()));
boolean directBuffers = Boolean.getBoolean("io.undertow.websockets.direct-buffers");
webSocketDeploymentInfo.setBuffers(new DefaultByteBufferPool(directBuffers, 1024, 100, 12));
deploymentInfo = new DeploymentInfo().setDeploymentName("WebSocket Deployment").setContextPath(MessageBrokerSetupService.WEBSOCKET_PATH).addServletContextAttribute(WebSocketDeploymentInfo.ATTRIBUTE_NAME, webSocketDeploymentInfo).setClassLoader(WebsocketComponent.class.getClassLoader());
WebResourceCollection resourceCollection = new WebResourceCollection();
resourceCollection.addUrlPattern("/*");
// Require authentication, but authorize specific roles later in Camel
SecurityConstraint constraint = new SecurityConstraint();
constraint.setEmptyRoleSemantic(SecurityInfo.EmptyRoleSemantic.AUTHENTICATE);
constraint.addWebResourceCollection(resourceCollection);
deploymentInfo.addSecurityConstraints(constraint);
HttpHandler handler = webService.addServletDeployment(identityService, deploymentInfo, true);
webService.getPrefixRoutes().put(MessageBrokerSetupService.WEBSOCKET_PATH, handler);
}
Aggregations