Polish WebSocket namespace
This commit is contained in:
parent
2665d56209
commit
6557800f97
|
|
@ -38,13 +38,13 @@ import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler
|
|||
import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;
|
||||
|
||||
/**
|
||||
* A {@link BeanDefinitionParser} that provides the configuration for the
|
||||
* {@code <websocket:handlers/>} namespace element. It registers a Spring MVC
|
||||
* {@link org.springframework.web.servlet.handler.SimpleUrlHandlerMapping}
|
||||
* to map HTTP WebSocket handshake requests to
|
||||
* {@link org.springframework.web.socket.WebSocketHandler}s.
|
||||
* Parses the configuration for the {@code <websocket:handlers/>} namespace
|
||||
* element. Registers a Spring MVC {@code SimpleUrlHandlerMapping} to map HTTP
|
||||
* WebSocket handshake (or SockJS) requests to
|
||||
* {@link org.springframework.web.socket.WebSocketHandler WebSocketHandler}s.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
class HandlersBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
|
@ -55,11 +55,10 @@ class HandlersBeanDefinitionParser implements BeanDefinitionParser {
|
|||
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserCxt) {
|
||||
|
||||
Object source = parserCxt.extractSource(element);
|
||||
public BeanDefinition parse(Element element, ParserContext context) {
|
||||
Object source = context.extractSource(element);
|
||||
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
|
||||
parserCxt.pushContainingComponent(compDefinition);
|
||||
context.pushContainingComponent(compDefinition);
|
||||
|
||||
String orderAttribute = element.getAttribute("order");
|
||||
int order = orderAttribute.isEmpty() ? DEFAULT_MAPPING_ORDER : Integer.valueOf(orderAttribute);
|
||||
|
|
@ -68,128 +67,106 @@ class HandlersBeanDefinitionParser implements BeanDefinitionParser {
|
|||
handlerMappingDef.setSource(source);
|
||||
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
handlerMappingDef.getPropertyValues().add("order", order);
|
||||
String handlerMappingName = parserCxt.getReaderContext().registerWithGeneratedName(handlerMappingDef);
|
||||
String handlerMappingName = context.getReaderContext().registerWithGeneratedName(handlerMappingDef);
|
||||
|
||||
RuntimeBeanReference handshakeHandler = WebSocketNamespaceUtils.registerHandshakeHandler(element, parserCxt, source);
|
||||
Element interceptorsElement = DomUtils.getChildElementByTagName(element, "handshake-interceptors");
|
||||
ManagedList<?> interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, parserCxt);
|
||||
RuntimeBeanReference sockJsServiceRef =
|
||||
WebSocketNamespaceUtils.registerSockJsService(element, SOCK_JS_SCHEDULER_NAME, parserCxt, source);
|
||||
RuntimeBeanReference sockJsService = WebSocketNamespaceUtils.registerSockJsService(
|
||||
element, SOCK_JS_SCHEDULER_NAME, context, source);
|
||||
|
||||
HandlerMappingStrategy strategy = createHandlerMappingStrategy(sockJsServiceRef, handshakeHandler, interceptors);
|
||||
HandlerMappingStrategy strategy;
|
||||
if (sockJsService != null) {
|
||||
strategy = new SockJsHandlerMappingStrategy(sockJsService);
|
||||
}
|
||||
else {
|
||||
RuntimeBeanReference handshakeHandler = WebSocketNamespaceUtils.registerHandshakeHandler(element, context, source);
|
||||
Element interceptorsElement = DomUtils.getChildElementByTagName(element, "handshake-interceptors");
|
||||
ManagedList<?> interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, context);
|
||||
strategy = new WebSocketHandlerMappingStrategy(handshakeHandler, interceptors);
|
||||
}
|
||||
|
||||
List<Element> mappingElements = DomUtils.getChildElementsByTagName(element, "mapping");
|
||||
ManagedMap<String, Object> urlMap = new ManagedMap<String, Object>();
|
||||
urlMap.setSource(source);
|
||||
|
||||
for(Element mappingElement : mappingElements) {
|
||||
urlMap.putAll(strategy.createMappings(mappingElement, parserCxt));
|
||||
for(Element mappingElement : DomUtils.getChildElementsByTagName(element, "mapping")) {
|
||||
strategy.addMapping(mappingElement, urlMap, context);
|
||||
}
|
||||
handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
|
||||
|
||||
parserCxt.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingName));
|
||||
parserCxt.popAndRegisterContainingComponent();
|
||||
context.registerComponent(new BeanComponentDefinition(handlerMappingDef, handlerMappingName));
|
||||
context.popAndRegisterContainingComponent();
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private interface HandlerMappingStrategy {
|
||||
|
||||
public ManagedMap<String, Object> createMappings(Element mappingElement, ParserContext parserContext);
|
||||
void addMapping(Element mappingElement, ManagedMap<String, Object> map, ParserContext context);
|
||||
|
||||
}
|
||||
|
||||
private HandlerMappingStrategy createHandlerMappingStrategy(
|
||||
RuntimeBeanReference sockJsServiceRef, RuntimeBeanReference handshakeHandlerRef,
|
||||
ManagedList<? extends Object> interceptorsList) {
|
||||
private static class WebSocketHandlerMappingStrategy implements HandlerMappingStrategy {
|
||||
|
||||
if(sockJsServiceRef != null) {
|
||||
SockJSHandlerMappingStrategy strategy = new SockJSHandlerMappingStrategy();
|
||||
strategy.setSockJsServiceRef(sockJsServiceRef);
|
||||
return strategy;
|
||||
private final RuntimeBeanReference handshakeHandlerReference;
|
||||
|
||||
private final ManagedList<?> interceptorsList;
|
||||
|
||||
|
||||
private WebSocketHandlerMappingStrategy(RuntimeBeanReference handshakeHandler, ManagedList<?> interceptors) {
|
||||
this.handshakeHandlerReference = handshakeHandler;
|
||||
this.interceptorsList = interceptors;
|
||||
}
|
||||
else {
|
||||
WebSocketHandlerMappingStrategy strategy = new WebSocketHandlerMappingStrategy();
|
||||
strategy.setHandshakeHandlerReference(handshakeHandlerRef);
|
||||
strategy.setInterceptorsList(interceptorsList);
|
||||
return strategy;
|
||||
}
|
||||
}
|
||||
|
||||
private class WebSocketHandlerMappingStrategy implements HandlerMappingStrategy {
|
||||
|
||||
private RuntimeBeanReference handshakeHandlerReference;
|
||||
|
||||
private ManagedList<?> interceptorsList;
|
||||
|
||||
public void setHandshakeHandlerReference(RuntimeBeanReference handshakeHandlerReference) {
|
||||
this.handshakeHandlerReference = handshakeHandlerReference;
|
||||
}
|
||||
|
||||
public void setInterceptorsList(ManagedList<?> interceptorsList) { this.interceptorsList = interceptorsList; }
|
||||
|
||||
@Override
|
||||
public ManagedMap<String, Object> createMappings(Element mappingElement, ParserContext parserContext) {
|
||||
ManagedMap<String, Object> urlMap = new ManagedMap<String, Object>();
|
||||
Object source = parserContext.extractSource(mappingElement);
|
||||
|
||||
String path = mappingElement.getAttribute("path");
|
||||
List<String> mappings = Arrays.asList(StringUtils.tokenizeToStringArray(path, ","));
|
||||
RuntimeBeanReference webSocketHandlerReference = new RuntimeBeanReference(mappingElement.getAttribute("handler"));
|
||||
public void addMapping(Element element, ManagedMap<String, Object> urlMap, ParserContext context) {
|
||||
String pathAttribute = element.getAttribute("path");
|
||||
List<String> mappings = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ","));
|
||||
RuntimeBeanReference handlerReference = new RuntimeBeanReference(element.getAttribute("handler"));
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, webSocketHandlerReference);
|
||||
cavs.addIndexedArgumentValue(0, handlerReference);
|
||||
if(this.handshakeHandlerReference != null) {
|
||||
cavs.addIndexedArgumentValue(1, this.handshakeHandlerReference);
|
||||
}
|
||||
RootBeanDefinition requestHandlerDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cavs, null);
|
||||
requestHandlerDef.setSource(source);
|
||||
requestHandlerDef.setSource(context.extractSource(element));
|
||||
requestHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
requestHandlerDef.getPropertyValues().add("handshakeInterceptors", this.interceptorsList);
|
||||
String requestHandlerName = parserContext.getReaderContext().registerWithGeneratedName(requestHandlerDef);
|
||||
String requestHandlerName = context.getReaderContext().registerWithGeneratedName(requestHandlerDef);
|
||||
RuntimeBeanReference requestHandlerRef = new RuntimeBeanReference(requestHandlerName);
|
||||
|
||||
for(String mapping : mappings) {
|
||||
for (String mapping : mappings) {
|
||||
urlMap.put(mapping, requestHandlerRef);
|
||||
}
|
||||
|
||||
return urlMap;
|
||||
}
|
||||
}
|
||||
|
||||
private class SockJSHandlerMappingStrategy implements HandlerMappingStrategy {
|
||||
private static class SockJsHandlerMappingStrategy implements HandlerMappingStrategy {
|
||||
|
||||
private RuntimeBeanReference sockJsServiceRef;
|
||||
private final RuntimeBeanReference sockJsService;
|
||||
|
||||
public void setSockJsServiceRef(RuntimeBeanReference sockJsServiceRef) {
|
||||
this.sockJsServiceRef = sockJsServiceRef;
|
||||
|
||||
private SockJsHandlerMappingStrategy(RuntimeBeanReference sockJsService) {
|
||||
this.sockJsService = sockJsService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManagedMap<String, Object> createMappings(Element mappingElement, ParserContext parserContext) {
|
||||
|
||||
ManagedMap<String, Object> urlMap = new ManagedMap<String, Object>();
|
||||
Object source = parserContext.extractSource(mappingElement);
|
||||
|
||||
String pathValue = mappingElement.getAttribute("path");
|
||||
List<String> mappings = Arrays.asList(StringUtils.tokenizeToStringArray(pathValue, ","));
|
||||
RuntimeBeanReference webSocketHandlerReference = new RuntimeBeanReference(mappingElement.getAttribute("handler"));
|
||||
public void addMapping(Element element, ManagedMap<String, Object> urlMap, ParserContext context) {
|
||||
String pathAttribute = element.getAttribute("path");
|
||||
List<String> mappings = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ","));
|
||||
RuntimeBeanReference handlerReference = new RuntimeBeanReference(element.getAttribute("handler"));
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, this.sockJsServiceRef, "SockJsService");
|
||||
cavs.addIndexedArgumentValue(1, webSocketHandlerReference, "WebSocketHandler");
|
||||
cavs.addIndexedArgumentValue(0, this.sockJsService, "SockJsService");
|
||||
cavs.addIndexedArgumentValue(1, handlerReference, "WebSocketHandler");
|
||||
|
||||
RootBeanDefinition requestHandlerDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cavs, null);
|
||||
requestHandlerDef.setSource(source);
|
||||
requestHandlerDef.setSource(context.extractSource(element));
|
||||
requestHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
String requestHandlerName = parserContext.getReaderContext().registerWithGeneratedName(requestHandlerDef);
|
||||
String requestHandlerName = context.getReaderContext().registerWithGeneratedName(requestHandlerDef);
|
||||
RuntimeBeanReference requestHandlerRef = new RuntimeBeanReference(requestHandlerName);
|
||||
|
||||
for(String path : mappings) {
|
||||
String pathPattern = path.endsWith("/") ? path + "**" : path + "/**";
|
||||
for (String mapping : mappings) {
|
||||
String pathPattern = (mapping.endsWith("/") ? mapping + "**" : mapping + "/**");
|
||||
urlMap.put(pathPattern, requestHandlerRef);
|
||||
}
|
||||
|
||||
return urlMap;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,6 @@ import org.springframework.messaging.simp.user.UserDestinationMessageHandler;
|
|||
import org.springframework.messaging.simp.stomp.StompBrokerRelayMessageHandler;
|
||||
import org.springframework.messaging.support.ExecutorSubscribableChannel;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
import org.springframework.util.AntPathMatcher;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.MimeTypeUtils;
|
||||
|
|
@ -92,7 +91,7 @@ import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;
|
|||
*/
|
||||
class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
||||
|
||||
protected static final String SOCKJS_SCHEDULER_BEAN_NAME = "messageBrokerSockJsScheduler";
|
||||
private static final String SOCKJS_SCHEDULER_BEAN_NAME = "messageBrokerSockJsScheduler";
|
||||
|
||||
private static final int DEFAULT_MAPPING_ORDER = 1;
|
||||
|
||||
|
|
@ -101,142 +100,111 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
|||
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserCxt) {
|
||||
|
||||
Object source = parserCxt.extractSource(element);
|
||||
public BeanDefinition parse(Element element, ParserContext context) {
|
||||
Object source = context.extractSource(element);
|
||||
CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(), source);
|
||||
parserCxt.pushContainingComponent(compDefinition);
|
||||
context.pushContainingComponent(compDefinition);
|
||||
|
||||
String orderAttribute = element.getAttribute("order");
|
||||
int order = orderAttribute.isEmpty() ? DEFAULT_MAPPING_ORDER : Integer.valueOf(orderAttribute);
|
||||
|
||||
ManagedMap<String, Object> urlMap = new ManagedMap<String, Object>();
|
||||
urlMap.setSource(source);
|
||||
|
||||
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||
handlerMappingDef.getPropertyValues().add("order", order);
|
||||
handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
|
||||
registerBeanDef(handlerMappingDef, context, source);
|
||||
|
||||
String beanName = "clientInboundChannel";
|
||||
Element channelElem = DomUtils.getChildElementByTagName(element, "client-inbound-channel");
|
||||
RuntimeBeanReference clientInChannel = getMessageChannel(beanName, channelElem, parserCxt, source);
|
||||
RuntimeBeanReference inChannel = getMessageChannel("clientInboundChannel", channelElem, context, source);
|
||||
|
||||
beanName = "clientOutboundChannel";
|
||||
channelElem = DomUtils.getChildElementByTagName(element, "client-outbound-channel");
|
||||
RuntimeBeanReference clientOutChannel = getMessageChannel(beanName, channelElem, parserCxt, source);
|
||||
RuntimeBeanReference outChannel = getMessageChannel("clientOutboundChannel", channelElem, context, source);
|
||||
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(DefaultUserSessionRegistry.class);
|
||||
beanName = registerBeanDef(beanDef, parserCxt, source);
|
||||
RuntimeBeanReference userSessionRegistry = new RuntimeBeanReference(beanName);
|
||||
RootBeanDefinition registryBeanDef = new RootBeanDefinition(DefaultUserSessionRegistry.class);
|
||||
String registryBeanName = registerBeanDef(registryBeanDef, context, source);
|
||||
RuntimeBeanReference sessionRegistry = new RuntimeBeanReference(registryBeanName);
|
||||
|
||||
RuntimeBeanReference subProtocolHandlerDef = registerSubProtocolWebSocketHandler(
|
||||
element, clientInChannel, clientOutChannel, userSessionRegistry, parserCxt, source);
|
||||
RuntimeBeanReference subProtoHandler = registerSubProtoHandler(element, inChannel, outChannel,
|
||||
sessionRegistry, context, source);
|
||||
|
||||
for(Element stompEndpointElem : DomUtils.getChildElementsByTagName(element, "stomp-endpoint")) {
|
||||
|
||||
RuntimeBeanReference httpRequestHandler = registerHttpRequestHandler(
|
||||
stompEndpointElem, subProtocolHandlerDef, parserCxt, source);
|
||||
|
||||
String pathAttribute = stompEndpointElem.getAttribute("path");
|
||||
for (Element endpointElem : DomUtils.getChildElementsByTagName(element, "stomp-endpoint")) {
|
||||
RuntimeBeanReference requestHandler = registerRequestHandler(endpointElem, subProtoHandler, context, source);
|
||||
String pathAttribute = endpointElem.getAttribute("path");
|
||||
Assert.state(StringUtils.hasText(pathAttribute), "Invalid <stomp-endpoint> (no path mapping)");
|
||||
|
||||
List<String> paths = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ","));
|
||||
for(String path : paths) {
|
||||
path = path.trim();
|
||||
Assert.state(StringUtils.hasText(path), "Invalid <stomp-endpoint> path attribute: " + pathAttribute);
|
||||
if (DomUtils.getChildElementByTagName(stompEndpointElem, "sockjs") != null) {
|
||||
if (DomUtils.getChildElementByTagName(endpointElem, "sockjs") != null) {
|
||||
path = path.endsWith("/") ? path + "**" : path + "/**";
|
||||
}
|
||||
urlMap.put(path, httpRequestHandler);
|
||||
urlMap.put(path, requestHandler);
|
||||
}
|
||||
}
|
||||
|
||||
registerBeanDef(handlerMappingDef, parserCxt, source);
|
||||
|
||||
beanName = "brokerChannel";
|
||||
channelElem = DomUtils.getChildElementByTagName(element, "broker-channel");
|
||||
RuntimeBeanReference brokerChannel = getMessageChannel(beanName, channelElem, parserCxt, source);
|
||||
RootBeanDefinition brokerDef = registerMessageBroker(element, clientInChannel,
|
||||
clientOutChannel, brokerChannel, parserCxt, source);
|
||||
RuntimeBeanReference brokerChannel = getMessageChannel("brokerChannel", channelElem, context, source);
|
||||
RootBeanDefinition broker = registerMessageBroker(element, inChannel, outChannel, brokerChannel, context, source);
|
||||
|
||||
RuntimeBeanReference messageConverter = registerBrokerMessageConverter(element, parserCxt, source);
|
||||
RuntimeBeanReference converter = registerMessageConverter(element, context, source);
|
||||
RuntimeBeanReference template = registerMessagingTemplate(element, brokerChannel, converter, context, source);
|
||||
registerAnnotationMethodMessageHandler(element, inChannel, outChannel,converter, template, context, source);
|
||||
|
||||
RuntimeBeanReference messagingTemplate = registerBrokerMessagingTemplate(element, brokerChannel,
|
||||
messageConverter, parserCxt, source);
|
||||
|
||||
registerAnnotationMethodMessageHandler(element, clientInChannel, clientOutChannel,
|
||||
messageConverter, messagingTemplate, parserCxt, source);
|
||||
|
||||
RuntimeBeanReference userDestinationResolver = registerUserDestinationResolver(element,
|
||||
userSessionRegistry, parserCxt, source);
|
||||
|
||||
registerUserDestinationMessageHandler(clientInChannel, clientOutChannel, brokerChannel,
|
||||
userDestinationResolver, parserCxt, source);
|
||||
RuntimeBeanReference resolver = registerUserDestinationResolver(element, sessionRegistry, context, source);
|
||||
registerUserDestinationMessageHandler(inChannel, brokerChannel, resolver, context, source);
|
||||
|
||||
Map<String, Object> scopeMap = Collections.<String, Object>singletonMap("websocket", new SimpSessionScope());
|
||||
RootBeanDefinition scopeConfigurerDef = new RootBeanDefinition(CustomScopeConfigurer.class);
|
||||
scopeConfigurerDef.getPropertyValues().add("scopes", scopeMap);
|
||||
registerBeanDefByName("webSocketScopeConfigurer", scopeConfigurerDef, parserCxt, source);
|
||||
RootBeanDefinition scopeConfigurer = new RootBeanDefinition(CustomScopeConfigurer.class);
|
||||
scopeConfigurer.getPropertyValues().add("scopes", scopeMap);
|
||||
registerBeanDefByName("webSocketScopeConfigurer", scopeConfigurer, context, source);
|
||||
|
||||
registerWebSocketMessageBrokerStats(subProtocolHandlerDef, brokerDef, clientInChannel,
|
||||
clientOutChannel, parserCxt, source);
|
||||
|
||||
parserCxt.popAndRegisterContainingComponent();
|
||||
registerWebSocketMessageBrokerStats(subProtoHandler, broker, inChannel, outChannel, context, source);
|
||||
|
||||
context.popAndRegisterContainingComponent();
|
||||
return null;
|
||||
}
|
||||
|
||||
private RuntimeBeanReference getMessageChannel(String channelName, Element channelElement,
|
||||
ParserContext parserCxt, Object source) {
|
||||
|
||||
RootBeanDefinition executorDef = null;
|
||||
if (channelElement == null) {
|
||||
executorDef = getDefaultExecutorBeanDefinition(channelName);
|
||||
private RuntimeBeanReference getMessageChannel(String name, Element element, ParserContext context, Object source) {
|
||||
RootBeanDefinition executor = null;
|
||||
if (element == null) {
|
||||
executor = getDefaultExecutorBeanDefinition(name);
|
||||
}
|
||||
else {
|
||||
Element executor = DomUtils.getChildElementByTagName(channelElement, "executor");
|
||||
if (executor == null) {
|
||||
executorDef = getDefaultExecutorBeanDefinition(channelName);
|
||||
Element executorElem = DomUtils.getChildElementByTagName(element, "executor");
|
||||
if (executorElem == null) {
|
||||
executor = getDefaultExecutorBeanDefinition(name);
|
||||
}
|
||||
else {
|
||||
executorDef = new RootBeanDefinition(ThreadPoolTaskExecutor.class);
|
||||
String attrValue = executor.getAttribute("core-pool-size");
|
||||
if (!StringUtils.isEmpty(attrValue)) {
|
||||
executorDef.getPropertyValues().add("corePoolSize", attrValue);
|
||||
executor = new RootBeanDefinition(ThreadPoolTaskExecutor.class);
|
||||
if (executorElem.hasAttribute("core-pool-size")) {
|
||||
executor.getPropertyValues().add("corePoolSize", executorElem.getAttribute("core-pool-size"));
|
||||
}
|
||||
attrValue = executor.getAttribute("max-pool-size");
|
||||
if (!StringUtils.isEmpty(attrValue)) {
|
||||
executorDef.getPropertyValues().add("maxPoolSize", attrValue);
|
||||
if (executorElem.hasAttribute("max-pool-size")) {
|
||||
executor.getPropertyValues().add("maxPoolSize", executorElem.getAttribute("max-pool-size"));
|
||||
}
|
||||
attrValue = executor.getAttribute("keep-alive-seconds");
|
||||
if (!StringUtils.isEmpty(attrValue)) {
|
||||
executorDef.getPropertyValues().add("keepAliveSeconds", attrValue);
|
||||
if (executorElem.hasAttribute("keep-alive-seconds")) {
|
||||
executor.getPropertyValues().add("keepAliveSeconds", executorElem.getAttribute("keep-alive-seconds"));
|
||||
}
|
||||
attrValue = executor.getAttribute("queue-capacity");
|
||||
if (!StringUtils.isEmpty(attrValue)) {
|
||||
executorDef.getPropertyValues().add("queueCapacity", attrValue);
|
||||
if (executorElem.hasAttribute("queue-capacity")) {
|
||||
executor.getPropertyValues().add("queueCapacity", executorElem.getAttribute("queue-capacity"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ConstructorArgumentValues argValues = new ConstructorArgumentValues();
|
||||
if (executorDef != null) {
|
||||
executorDef.getPropertyValues().add("threadNamePrefix", channelName + "-");
|
||||
String executorName = channelName + "Executor";
|
||||
registerBeanDefByName(executorName, executorDef, parserCxt, source);
|
||||
if (executor != null) {
|
||||
executor.getPropertyValues().add("threadNamePrefix", name + "-");
|
||||
String executorName = name + "Executor";
|
||||
registerBeanDefByName(executorName, executor, context, source);
|
||||
argValues.addIndexedArgumentValue(0, new RuntimeBeanReference(executorName));
|
||||
}
|
||||
|
||||
RootBeanDefinition channelDef = new RootBeanDefinition(ExecutorSubscribableChannel.class, argValues, null);
|
||||
|
||||
if (channelElement != null) {
|
||||
Element interceptorsElement = DomUtils.getChildElementByTagName(channelElement, "interceptors");
|
||||
ManagedList<?> interceptorList = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, parserCxt);
|
||||
channelDef.getPropertyValues().add("interceptors", interceptorList);
|
||||
if (element != null) {
|
||||
Element interceptorsElement = DomUtils.getChildElementByTagName(element, "interceptors");
|
||||
ManagedList<?> interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, context);
|
||||
channelDef.getPropertyValues().add("interceptors", interceptors);
|
||||
}
|
||||
|
||||
registerBeanDefByName(channelName, channelDef, parserCxt, source);
|
||||
return new RuntimeBeanReference(channelName);
|
||||
registerBeanDefByName(name, channelDef, context, source);
|
||||
return new RuntimeBeanReference(name);
|
||||
}
|
||||
|
||||
private RootBeanDefinition getDefaultExecutorBeanDefinition(String channelName) {
|
||||
|
|
@ -250,81 +218,71 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
|||
return executorDef;
|
||||
}
|
||||
|
||||
private RuntimeBeanReference registerSubProtocolWebSocketHandler(Element element,
|
||||
RuntimeBeanReference clientInChannel, RuntimeBeanReference clientOutChannel,
|
||||
RuntimeBeanReference userSessionRegistry, ParserContext parserCxt, Object source) {
|
||||
private RuntimeBeanReference registerSubProtoHandler(Element element, RuntimeBeanReference inChannel,
|
||||
RuntimeBeanReference outChannel, RuntimeBeanReference registry, ParserContext context, Object source) {
|
||||
|
||||
RootBeanDefinition stompHandlerDef = new RootBeanDefinition(StompSubProtocolHandler.class);
|
||||
stompHandlerDef.getPropertyValues().add("userSessionRegistry", userSessionRegistry);
|
||||
registerBeanDef(stompHandlerDef, parserCxt, source);
|
||||
stompHandlerDef.getPropertyValues().add("userSessionRegistry", registry);
|
||||
registerBeanDef(stompHandlerDef, context, source);
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, clientInChannel);
|
||||
cavs.addIndexedArgumentValue(1, clientOutChannel);
|
||||
cavs.addIndexedArgumentValue(0, inChannel);
|
||||
cavs.addIndexedArgumentValue(1, outChannel);
|
||||
|
||||
RootBeanDefinition subProtocolWshDef = new RootBeanDefinition(SubProtocolWebSocketHandler.class, cavs, null);
|
||||
subProtocolWshDef.getPropertyValues().addPropertyValue("protocolHandlers", stompHandlerDef);
|
||||
String subProtocolWshName = registerBeanDef(subProtocolWshDef, parserCxt, source);
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(SubProtocolWebSocketHandler.class, cavs, null);
|
||||
beanDef.getPropertyValues().addPropertyValue("protocolHandlers", stompHandlerDef);
|
||||
|
||||
Element transportElem = DomUtils.getChildElementByTagName(element, "transport");
|
||||
if (transportElem != null) {
|
||||
String messageSize = transportElem.getAttribute("message-size");
|
||||
if (messageSize != null) {
|
||||
stompHandlerDef.getPropertyValues().add("messageSizeLimit", messageSize);
|
||||
if (transportElem.hasAttribute("message-size")) {
|
||||
stompHandlerDef.getPropertyValues().add("messageSizeLimit", transportElem.getAttribute("message-size"));
|
||||
}
|
||||
String sendTimeLimit = transportElem.getAttribute("send-timeout");
|
||||
if (sendTimeLimit != null) {
|
||||
subProtocolWshDef.getPropertyValues().add("sendTimeLimit", sendTimeLimit);
|
||||
if (transportElem.hasAttribute("send-timeout")) {
|
||||
beanDef.getPropertyValues().add("sendTimeLimit", transportElem.getAttribute("send-timeout"));
|
||||
}
|
||||
String sendBufferSizeLimit = transportElem.getAttribute("send-buffer-size");
|
||||
if (sendBufferSizeLimit != null) {
|
||||
subProtocolWshDef.getPropertyValues().add("sendBufferSizeLimit", sendBufferSizeLimit);
|
||||
if (transportElem.hasAttribute("send-buffer-size")) {
|
||||
beanDef.getPropertyValues().add("sendBufferSizeLimit", transportElem.getAttribute("send-buffer-size"));
|
||||
}
|
||||
}
|
||||
|
||||
return new RuntimeBeanReference(subProtocolWshName);
|
||||
return new RuntimeBeanReference(registerBeanDef(beanDef, context, source));
|
||||
}
|
||||
|
||||
private RuntimeBeanReference registerHttpRequestHandler(Element stompEndpointElement,
|
||||
RuntimeBeanReference subProtocolWebSocketHandler, ParserContext parserCxt, Object source) {
|
||||
private RuntimeBeanReference registerRequestHandler(Element element, RuntimeBeanReference subProtoHandler,
|
||||
ParserContext context, Object source) {
|
||||
|
||||
RootBeanDefinition httpRequestHandlerDef;
|
||||
RootBeanDefinition beanDef;
|
||||
|
||||
RuntimeBeanReference sockJsService = WebSocketNamespaceUtils.registerSockJsService(
|
||||
stompEndpointElement, SOCKJS_SCHEDULER_BEAN_NAME, parserCxt, source);
|
||||
element, SOCKJS_SCHEDULER_BEAN_NAME, context, source);
|
||||
|
||||
if (sockJsService != null) {
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, sockJsService);
|
||||
cavs.addIndexedArgumentValue(1, subProtocolWebSocketHandler);
|
||||
httpRequestHandlerDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cavs, null);
|
||||
cavs.addIndexedArgumentValue(1, subProtoHandler);
|
||||
beanDef = new RootBeanDefinition(SockJsHttpRequestHandler.class, cavs, null);
|
||||
}
|
||||
else {
|
||||
RuntimeBeanReference handshakeHandler =
|
||||
WebSocketNamespaceUtils.registerHandshakeHandler(stompEndpointElement, parserCxt, source);
|
||||
RuntimeBeanReference handshakeHandler = WebSocketNamespaceUtils.registerHandshakeHandler(element, context, source);
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, subProtocolWebSocketHandler);
|
||||
if(handshakeHandler != null) {
|
||||
cavs.addIndexedArgumentValue(0, subProtoHandler);
|
||||
if (handshakeHandler != null) {
|
||||
cavs.addIndexedArgumentValue(1, handshakeHandler);
|
||||
}
|
||||
httpRequestHandlerDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cavs, null);
|
||||
beanDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cavs, null);
|
||||
}
|
||||
|
||||
String httpRequestHandlerBeanName = registerBeanDef(httpRequestHandlerDef, parserCxt, source);
|
||||
return new RuntimeBeanReference(httpRequestHandlerBeanName);
|
||||
return new RuntimeBeanReference(registerBeanDef(beanDef, context, source));
|
||||
}
|
||||
|
||||
private RootBeanDefinition registerMessageBroker(Element messageBrokerElement, RuntimeBeanReference clientInChannelDef,
|
||||
RuntimeBeanReference clientOutChannelDef, RuntimeBeanReference brokerChannelDef,
|
||||
ParserContext parserCxt, Object source) {
|
||||
private RootBeanDefinition registerMessageBroker(Element messageBrokerElement, RuntimeBeanReference inChannel,
|
||||
RuntimeBeanReference outChannel, RuntimeBeanReference brokerChannel, ParserContext context, Object source) {
|
||||
|
||||
Element simpleBrokerElem = DomUtils.getChildElementByTagName(messageBrokerElement, "simple-broker");
|
||||
Element brokerRelayElem = DomUtils.getChildElementByTagName(messageBrokerElement, "stomp-broker-relay");
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, clientInChannelDef);
|
||||
cavs.addIndexedArgumentValue(1, clientOutChannelDef);
|
||||
cavs.addIndexedArgumentValue(2, brokerChannelDef);
|
||||
cavs.addIndexedArgumentValue(0, inChannel);
|
||||
cavs.addIndexedArgumentValue(1, outChannel);
|
||||
cavs.addIndexedArgumentValue(2, brokerChannel);
|
||||
|
||||
RootBeanDefinition brokerDef;
|
||||
if (simpleBrokerElem != null) {
|
||||
|
|
@ -332,213 +290,177 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser {
|
|||
cavs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ",")));
|
||||
brokerDef = new RootBeanDefinition(SimpleBrokerMessageHandler.class, cavs, null);
|
||||
if (messageBrokerElement.hasAttribute("path-matcher")) {
|
||||
brokerDef.getPropertyValues().add("pathMatcher",
|
||||
new RuntimeBeanReference(messageBrokerElement.getAttribute("path-matcher")));
|
||||
String pathMatcherRef = messageBrokerElement.getAttribute("path-matcher");
|
||||
brokerDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef));
|
||||
}
|
||||
}
|
||||
else if (brokerRelayElem != null) {
|
||||
String prefix = brokerRelayElem.getAttribute("prefix");
|
||||
cavs.addIndexedArgumentValue(3, Arrays.asList(StringUtils.tokenizeToStringArray(prefix, ",")));
|
||||
|
||||
MutablePropertyValues mpvs = new MutablePropertyValues();
|
||||
String relayHost = brokerRelayElem.getAttribute("relay-host");
|
||||
if(!relayHost.isEmpty()) {
|
||||
mpvs.add("relayHost",relayHost);
|
||||
MutablePropertyValues values = new MutablePropertyValues();
|
||||
if (brokerRelayElem.hasAttribute("relay-host")) {
|
||||
values.add("relayHost", brokerRelayElem.getAttribute("relay-host"));
|
||||
}
|
||||
String relayPort = brokerRelayElem.getAttribute("relay-port");
|
||||
if(!relayPort.isEmpty()) {
|
||||
mpvs.add("relayPort", Integer.valueOf(relayPort));
|
||||
if (brokerRelayElem.hasAttribute("relay-port")) {
|
||||
values.add("relayPort", brokerRelayElem.getAttribute("relay-port"));
|
||||
}
|
||||
String attrValue = brokerRelayElem.getAttribute("client-login");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("clientLogin",attrValue);
|
||||
if (brokerRelayElem.hasAttribute("client-login")) {
|
||||
values.add("clientLogin", brokerRelayElem.getAttribute("client-login"));
|
||||
}
|
||||
attrValue = brokerRelayElem.getAttribute("client-passcode");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("clientPasscode", attrValue);
|
||||
if (brokerRelayElem.hasAttribute("client-passcode")) {
|
||||
values.add("clientPasscode", brokerRelayElem.getAttribute("client-passcode"));
|
||||
}
|
||||
attrValue = brokerRelayElem.getAttribute("system-login");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("systemLogin",attrValue);
|
||||
if (brokerRelayElem.hasAttribute("system-login")) {
|
||||
values.add("systemLogin", brokerRelayElem.getAttribute("system-login"));
|
||||
}
|
||||
attrValue = brokerRelayElem.getAttribute("system-passcode");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("systemPasscode", attrValue);
|
||||
if (brokerRelayElem.hasAttribute("system-passcode")) {
|
||||
values.add("systemPasscode", brokerRelayElem.getAttribute("system-passcode"));
|
||||
}
|
||||
attrValue = brokerRelayElem.getAttribute("heartbeat-send-interval");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("systemHeartbeatSendInterval", Long.parseLong(attrValue));
|
||||
if (brokerRelayElem.hasAttribute("heartbeat-send-interval")) {
|
||||
values.add("systemHeartbeatSendInterval", brokerRelayElem.getAttribute("heartbeat-send-interval"));
|
||||
}
|
||||
attrValue = brokerRelayElem.getAttribute("heartbeat-receive-interval");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("systemHeartbeatReceiveInterval", Long.parseLong(attrValue));
|
||||
if (brokerRelayElem.hasAttribute("heartbeat-receive-interval")) {
|
||||
values.add("systemHeartbeatReceiveInterval", brokerRelayElem.getAttribute("heartbeat-receive-interval"));
|
||||
}
|
||||
attrValue = brokerRelayElem.getAttribute("virtual-host");
|
||||
if(!attrValue.isEmpty()) {
|
||||
mpvs.add("virtualHost", attrValue);
|
||||
if (brokerRelayElem.hasAttribute("virtual-host")) {
|
||||
values.add("virtualHost", brokerRelayElem.getAttribute("virtual-host"));
|
||||
}
|
||||
Class<?> handlerType = StompBrokerRelayMessageHandler.class;
|
||||
brokerDef = new RootBeanDefinition(handlerType, cavs, mpvs);
|
||||
brokerDef = new RootBeanDefinition(handlerType, cavs, values);
|
||||
}
|
||||
else {
|
||||
// Should not happen
|
||||
throw new IllegalStateException("Neither <simple-broker> nor <stomp-broker-relay> elements found.");
|
||||
}
|
||||
registerBeanDef(brokerDef, parserCxt, source);
|
||||
registerBeanDef(brokerDef, context, source);
|
||||
return brokerDef;
|
||||
}
|
||||
|
||||
private RuntimeBeanReference registerBrokerMessageConverter(Element element,
|
||||
ParserContext parserCxt, Object source) {
|
||||
|
||||
private RuntimeBeanReference registerMessageConverter(Element element, ParserContext context, Object source) {
|
||||
Element convertersElement = DomUtils.getChildElementByTagName(element, "message-converters");
|
||||
ManagedList<? super Object> convertersDef = new ManagedList<Object>();
|
||||
ManagedList<? super Object> converters = new ManagedList<Object>();
|
||||
if (convertersElement != null) {
|
||||
convertersDef.setSource(source);
|
||||
converters.setSource(source);
|
||||
for (Element beanElement : DomUtils.getChildElementsByTagName(convertersElement, "bean", "ref")) {
|
||||
Object object = parserCxt.getDelegate().parsePropertySubElement(beanElement, null);
|
||||
convertersDef.add(object);
|
||||
Object object = context.getDelegate().parsePropertySubElement(beanElement, null);
|
||||
converters.add(object);
|
||||
}
|
||||
}
|
||||
|
||||
if (convertersElement == null || Boolean.valueOf(convertersElement.getAttribute("register-defaults"))) {
|
||||
convertersDef.setSource(source);
|
||||
convertersDef.add(new RootBeanDefinition(StringMessageConverter.class));
|
||||
convertersDef.add(new RootBeanDefinition(ByteArrayMessageConverter.class));
|
||||
converters.setSource(source);
|
||||
converters.add(new RootBeanDefinition(StringMessageConverter.class));
|
||||
converters.add(new RootBeanDefinition(ByteArrayMessageConverter.class));
|
||||
if (jackson2Present) {
|
||||
RootBeanDefinition jacksonConverterDef = new RootBeanDefinition(MappingJackson2MessageConverter.class);
|
||||
RootBeanDefinition resolverDef = new RootBeanDefinition(DefaultContentTypeResolver.class);
|
||||
resolverDef.getPropertyValues().add("defaultMimeType", MimeTypeUtils.APPLICATION_JSON);
|
||||
jacksonConverterDef.getPropertyValues().add("contentTypeResolver", resolverDef);
|
||||
convertersDef.add(jacksonConverterDef);
|
||||
converters.add(jacksonConverterDef);
|
||||
}
|
||||
}
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, convertersDef);
|
||||
|
||||
cavs.addIndexedArgumentValue(0, converters);
|
||||
RootBeanDefinition messageConverterDef = new RootBeanDefinition(CompositeMessageConverter.class, cavs, null);
|
||||
return new RuntimeBeanReference(registerBeanDef(messageConverterDef, parserCxt, source));
|
||||
return new RuntimeBeanReference(registerBeanDef(messageConverterDef, context, source));
|
||||
}
|
||||
|
||||
private RuntimeBeanReference registerBrokerMessagingTemplate(
|
||||
Element element, RuntimeBeanReference brokerChannelDef, RuntimeBeanReference messageConverterRef,
|
||||
ParserContext parserCxt, Object source) {
|
||||
private RuntimeBeanReference registerMessagingTemplate(Element element, RuntimeBeanReference brokerChannel,
|
||||
RuntimeBeanReference messageConverter, ParserContext context, Object source) {
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, brokerChannelDef);
|
||||
RootBeanDefinition messagingTemplateDef = new RootBeanDefinition(SimpMessagingTemplate.class,cavs, null);
|
||||
|
||||
String userDestinationPrefixAttribute = element.getAttribute("user-destination-prefix");
|
||||
if(!userDestinationPrefixAttribute.isEmpty()) {
|
||||
messagingTemplateDef.getPropertyValues().add("userDestinationPrefix", userDestinationPrefixAttribute);
|
||||
cavs.addIndexedArgumentValue(0, brokerChannel);
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(SimpMessagingTemplate.class,cavs, null);
|
||||
if(element.hasAttribute("user-destination-prefix")) {
|
||||
beanDef.getPropertyValues().add("userDestinationPrefix", element.getAttribute("user-destination-prefix"));
|
||||
}
|
||||
messagingTemplateDef.getPropertyValues().add("messageConverter", messageConverterRef);
|
||||
|
||||
return new RuntimeBeanReference(registerBeanDef(messagingTemplateDef,parserCxt, source));
|
||||
beanDef.getPropertyValues().add("messageConverter", messageConverter);
|
||||
return new RuntimeBeanReference(registerBeanDef(beanDef,context, source));
|
||||
}
|
||||
|
||||
private void registerAnnotationMethodMessageHandler(Element messageBrokerElement,
|
||||
RuntimeBeanReference clientInChannelDef, RuntimeBeanReference clientOutChannelDef,
|
||||
RuntimeBeanReference brokerMessageConverterRef, RuntimeBeanReference brokerMessagingTemplateRef,
|
||||
ParserContext parserCxt, Object source) {
|
||||
|
||||
String appDestPrefix = messageBrokerElement.getAttribute("application-destination-prefix");
|
||||
RuntimeBeanReference inChannel, RuntimeBeanReference outChannel,
|
||||
RuntimeBeanReference converter, RuntimeBeanReference messagingTemplate,
|
||||
ParserContext context, Object source) {
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, clientInChannelDef);
|
||||
cavs.addIndexedArgumentValue(1, clientOutChannelDef);
|
||||
cavs.addIndexedArgumentValue(2, brokerMessagingTemplateRef);
|
||||
cavs.addIndexedArgumentValue(0, inChannel);
|
||||
cavs.addIndexedArgumentValue(1, outChannel);
|
||||
cavs.addIndexedArgumentValue(2, messagingTemplate);
|
||||
|
||||
MutablePropertyValues mpvs = new MutablePropertyValues();
|
||||
mpvs.add("destinationPrefixes",Arrays.asList(StringUtils.tokenizeToStringArray(appDestPrefix, ",")));
|
||||
mpvs.add("messageConverter", brokerMessageConverterRef);
|
||||
MutablePropertyValues values = new MutablePropertyValues();
|
||||
String prefixAttribute = messageBrokerElement.getAttribute("application-destination-prefix");
|
||||
values.add("destinationPrefixes", Arrays.asList(StringUtils.tokenizeToStringArray(prefixAttribute, ",")));
|
||||
values.add("messageConverter", converter);
|
||||
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(SimpAnnotationMethodMessageHandler.class, cavs, mpvs);
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(SimpAnnotationMethodMessageHandler.class, cavs, values);
|
||||
if (messageBrokerElement.hasAttribute("path-matcher")) {
|
||||
beanDef.getPropertyValues().add("pathMatcher",
|
||||
new RuntimeBeanReference(messageBrokerElement.getAttribute("path-matcher")));
|
||||
String pathMatcherRef = messageBrokerElement.getAttribute("path-matcher");
|
||||
beanDef.getPropertyValues().add("pathMatcher", new RuntimeBeanReference(pathMatcherRef));
|
||||
}
|
||||
|
||||
registerBeanDef(beanDef, parserCxt, source);
|
||||
registerBeanDef(beanDef, context, source);
|
||||
}
|
||||
|
||||
private RuntimeBeanReference registerUserDestinationResolver(Element messageBrokerElement,
|
||||
RuntimeBeanReference userSessionRegistry, ParserContext parserCxt, Object source) {
|
||||
private RuntimeBeanReference registerUserDestinationResolver(Element brokerElem,
|
||||
RuntimeBeanReference userSessionRegistry, ParserContext context, Object source) {
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, userSessionRegistry);
|
||||
RootBeanDefinition userDestinationResolverDef =
|
||||
new RootBeanDefinition(DefaultUserDestinationResolver.class, cavs, null);
|
||||
String prefix = messageBrokerElement.getAttribute("user-destination-prefix");
|
||||
if (!prefix.isEmpty()) {
|
||||
userDestinationResolverDef.getPropertyValues().add("userDestinationPrefix", prefix);
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(DefaultUserDestinationResolver.class, cavs, null);
|
||||
if (brokerElem.hasAttribute("user-destination-prefix")) {
|
||||
beanDef.getPropertyValues().add("userDestinationPrefix", brokerElem.getAttribute("user-destination-prefix"));
|
||||
}
|
||||
String userDestinationResolverName = registerBeanDef(userDestinationResolverDef, parserCxt, source);
|
||||
return new RuntimeBeanReference(userDestinationResolverName);
|
||||
return new RuntimeBeanReference(registerBeanDef(beanDef, context, source));
|
||||
}
|
||||
|
||||
private RuntimeBeanReference registerUserDestinationMessageHandler(RuntimeBeanReference clientInChannelDef,
|
||||
RuntimeBeanReference clientOutChannelDef, RuntimeBeanReference brokerChannelDef,
|
||||
RuntimeBeanReference userDestinationResolverRef, ParserContext parserCxt, Object source) {
|
||||
private RuntimeBeanReference registerUserDestinationMessageHandler(RuntimeBeanReference inChannel,
|
||||
RuntimeBeanReference brokerChannel, RuntimeBeanReference userDestinationResolver,
|
||||
ParserContext context, Object source) {
|
||||
|
||||
ConstructorArgumentValues cavs = new ConstructorArgumentValues();
|
||||
cavs.addIndexedArgumentValue(0, clientInChannelDef);
|
||||
cavs.addIndexedArgumentValue(1, brokerChannelDef);
|
||||
cavs.addIndexedArgumentValue(2, userDestinationResolverRef);
|
||||
|
||||
RootBeanDefinition userDestinationMessageHandlerDef =
|
||||
new RootBeanDefinition(UserDestinationMessageHandler.class, cavs, null);
|
||||
|
||||
String userDestinationMessageHandleName = registerBeanDef(userDestinationMessageHandlerDef, parserCxt, source);
|
||||
return new RuntimeBeanReference(userDestinationMessageHandleName);
|
||||
cavs.addIndexedArgumentValue(0, inChannel);
|
||||
cavs.addIndexedArgumentValue(1, brokerChannel);
|
||||
cavs.addIndexedArgumentValue(2, userDestinationResolver);
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(UserDestinationMessageHandler.class, cavs, null);
|
||||
return new RuntimeBeanReference(registerBeanDef(beanDef, context, source));
|
||||
}
|
||||
|
||||
private void registerWebSocketMessageBrokerStats(RuntimeBeanReference subProtocolHandlerDef,
|
||||
RootBeanDefinition brokerDef, RuntimeBeanReference clientInChannel,
|
||||
RuntimeBeanReference clientOutChannel, ParserContext parserCxt, Object source) {
|
||||
private void registerWebSocketMessageBrokerStats(RuntimeBeanReference subProtoHandler,
|
||||
RootBeanDefinition broker, RuntimeBeanReference inChannel, RuntimeBeanReference outChannel,
|
||||
ParserContext context, Object source) {
|
||||
|
||||
RootBeanDefinition statsDef = new RootBeanDefinition(WebSocketMessageBrokerStats.class);
|
||||
statsDef.getPropertyValues().add("subProtocolWebSocketHandler", subProtocolHandlerDef);
|
||||
RootBeanDefinition beanDef = new RootBeanDefinition(WebSocketMessageBrokerStats.class);
|
||||
beanDef.getPropertyValues().add("subProtocolWebSocketHandler", subProtoHandler);
|
||||
|
||||
if (StompBrokerRelayMessageHandler.class.equals(brokerDef.getBeanClass())) {
|
||||
statsDef.getPropertyValues().add("stompBrokerRelay", brokerDef);
|
||||
if (StompBrokerRelayMessageHandler.class.equals(broker.getBeanClass())) {
|
||||
beanDef.getPropertyValues().add("stompBrokerRelay", broker);
|
||||
}
|
||||
|
||||
String beanName = clientInChannel.getBeanName() + "Executor";
|
||||
if (parserCxt.getRegistry().containsBeanDefinition(beanName)) {
|
||||
BeanDefinition beanDef = parserCxt.getRegistry().getBeanDefinition(beanName);
|
||||
statsDef.getPropertyValues().add("inboundChannelExecutor", beanDef);
|
||||
String name = inChannel.getBeanName() + "Executor";
|
||||
if (context.getRegistry().containsBeanDefinition(name)) {
|
||||
beanDef.getPropertyValues().add("inboundChannelExecutor", context.getRegistry().getBeanDefinition(name));
|
||||
}
|
||||
|
||||
beanName = clientOutChannel.getBeanName() + "Executor";
|
||||
if (parserCxt.getRegistry().containsBeanDefinition(beanName)) {
|
||||
BeanDefinition beanDef = parserCxt.getRegistry().getBeanDefinition(beanName);
|
||||
statsDef.getPropertyValues().add("outboundChannelExecutor", beanDef);
|
||||
name = outChannel.getBeanName() + "Executor";
|
||||
if (context.getRegistry().containsBeanDefinition(name)) {
|
||||
beanDef.getPropertyValues().add("outboundChannelExecutor", context.getRegistry().getBeanDefinition(name));
|
||||
}
|
||||
|
||||
beanName = SOCKJS_SCHEDULER_BEAN_NAME;
|
||||
if (parserCxt.getRegistry().containsBeanDefinition(beanName)) {
|
||||
BeanDefinition beanDef = parserCxt.getRegistry().getBeanDefinition(beanName);
|
||||
statsDef.getPropertyValues().add("sockJsTaskScheduler", beanDef);
|
||||
name = SOCKJS_SCHEDULER_BEAN_NAME;
|
||||
if (context.getRegistry().containsBeanDefinition(name)) {
|
||||
beanDef.getPropertyValues().add("sockJsTaskScheduler", context.getRegistry().getBeanDefinition(name));
|
||||
}
|
||||
registerBeanDefByName("webSocketMessageBrokerStats", statsDef, parserCxt, source);
|
||||
registerBeanDefByName("webSocketMessageBrokerStats", beanDef, context, source);
|
||||
}
|
||||
|
||||
|
||||
private static String registerBeanDef(RootBeanDefinition beanDef, ParserContext parserCxt, Object source) {
|
||||
String beanName = parserCxt.getReaderContext().generateBeanName(beanDef);
|
||||
registerBeanDefByName(beanName, beanDef, parserCxt, source);
|
||||
return beanName;
|
||||
private static String registerBeanDef(RootBeanDefinition beanDef, ParserContext context, Object source) {
|
||||
String name = context.getReaderContext().generateBeanName(beanDef);
|
||||
registerBeanDefByName(name, beanDef, context, source);
|
||||
return name;
|
||||
}
|
||||
|
||||
private static void registerBeanDefByName(String beanName, RootBeanDefinition beanDef,
|
||||
ParserContext parserCxt, Object source) {
|
||||
|
||||
private static void registerBeanDefByName(String name, RootBeanDefinition beanDef, ParserContext context, Object source) {
|
||||
beanDef.setSource(source);
|
||||
beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
parserCxt.getRegistry().registerBeanDefinition(beanName, beanDef);
|
||||
parserCxt.registerComponent(new BeanComponentDefinition(beanDef, beanName));
|
||||
context.getRegistry().registerBeanDefinition(name, beanDef);
|
||||
context.registerComponent(new BeanComponentDefinition(beanDef, name));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,8 +31,6 @@ import org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsSe
|
|||
import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService;
|
||||
import org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler;
|
||||
|
||||
import java.util.concurrent.ScheduledThreadPoolExecutor;
|
||||
|
||||
/**
|
||||
* Provides utility methods for parsing common WebSocket XML namespace elements.
|
||||
*
|
||||
|
|
@ -43,7 +41,7 @@ import java.util.concurrent.ScheduledThreadPoolExecutor;
|
|||
class WebSocketNamespaceUtils {
|
||||
|
||||
|
||||
public static RuntimeBeanReference registerHandshakeHandler(Element element, ParserContext parserContext, Object source) {
|
||||
public static RuntimeBeanReference registerHandshakeHandler(Element element, ParserContext context, Object source) {
|
||||
RuntimeBeanReference handlerRef;
|
||||
Element handlerElem = DomUtils.getChildElementByTagName(element, "handshake-handler");
|
||||
if (handlerElem != null) {
|
||||
|
|
@ -53,19 +51,19 @@ class WebSocketNamespaceUtils {
|
|||
RootBeanDefinition defaultHandlerDef = new RootBeanDefinition(DefaultHandshakeHandler.class);
|
||||
defaultHandlerDef.setSource(source);
|
||||
defaultHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
String handlerName = parserContext.getReaderContext().registerWithGeneratedName(defaultHandlerDef);
|
||||
String handlerName = context.getReaderContext().registerWithGeneratedName(defaultHandlerDef);
|
||||
handlerRef = new RuntimeBeanReference(handlerName);
|
||||
}
|
||||
return handlerRef;
|
||||
}
|
||||
|
||||
public static RuntimeBeanReference registerSockJsService(Element element, String sockJsSchedulerName,
|
||||
ParserContext parserContext, Object source) {
|
||||
ParserContext context, Object source) {
|
||||
|
||||
Element sockJsElement = DomUtils.getChildElementByTagName(element, "sockjs");
|
||||
|
||||
if (sockJsElement != null) {
|
||||
Element handshakeHandlerElement = DomUtils.getChildElementByTagName(element, "handshake-handler");
|
||||
Element handshakeHandler = DomUtils.getChildElementByTagName(element, "handshake-handler");
|
||||
|
||||
RootBeanDefinition sockJsServiceDef = new RootBeanDefinition(DefaultSockJsService.class);
|
||||
sockJsServiceDef.setSource(source);
|
||||
|
|
@ -76,28 +74,29 @@ class WebSocketNamespaceUtils {
|
|||
scheduler = new RuntimeBeanReference(customTaskSchedulerName);
|
||||
}
|
||||
else {
|
||||
scheduler = registerSockJsTaskScheduler(sockJsSchedulerName, parserContext, source);
|
||||
scheduler = registerSockJsScheduler(sockJsSchedulerName, context, source);
|
||||
}
|
||||
sockJsServiceDef.getConstructorArgumentValues().addIndexedArgumentValue(0, scheduler);
|
||||
|
||||
Element transportHandlersElement = DomUtils.getChildElementByTagName(sockJsElement, "transport-handlers");
|
||||
if (transportHandlersElement != null) {
|
||||
String registerDefaultsAttribute = transportHandlersElement.getAttribute("register-defaults");
|
||||
if (registerDefaultsAttribute.equals("false")) {
|
||||
String registerDefaults = transportHandlersElement.getAttribute("register-defaults");
|
||||
if (registerDefaults.equals("false")) {
|
||||
sockJsServiceDef.setBeanClass(TransportHandlingSockJsService.class);
|
||||
}
|
||||
ManagedList<?> transportHandlersList = parseBeanSubElements(transportHandlersElement, parserContext);
|
||||
sockJsServiceDef.getConstructorArgumentValues().addIndexedArgumentValue(1, transportHandlersList);
|
||||
} else if(handshakeHandlerElement != null){
|
||||
RuntimeBeanReference handshakeHandlerRef = new RuntimeBeanReference(handshakeHandlerElement.getAttribute("ref"));
|
||||
ManagedList<?> transportHandlers = parseBeanSubElements(transportHandlersElement, context);
|
||||
sockJsServiceDef.getConstructorArgumentValues().addIndexedArgumentValue(1, transportHandlers);
|
||||
}
|
||||
else if (handshakeHandler != null) {
|
||||
RuntimeBeanReference handshakeHandlerRef = new RuntimeBeanReference(handshakeHandler.getAttribute("ref"));
|
||||
|
||||
RootBeanDefinition wsTransportHandler = new RootBeanDefinition(WebSocketTransportHandler.class);
|
||||
wsTransportHandler.setSource(source);
|
||||
wsTransportHandler.getConstructorArgumentValues().addIndexedArgumentValue(0, handshakeHandlerRef);
|
||||
sockJsServiceDef.getConstructorArgumentValues().addIndexedArgumentValue(1, wsTransportHandler);
|
||||
RootBeanDefinition transportHandler = new RootBeanDefinition(WebSocketTransportHandler.class);
|
||||
transportHandler.setSource(source);
|
||||
transportHandler.getConstructorArgumentValues().addIndexedArgumentValue(0, handshakeHandlerRef);
|
||||
sockJsServiceDef.getConstructorArgumentValues().addIndexedArgumentValue(1, transportHandler);
|
||||
}
|
||||
|
||||
String attrValue = sockJsElement.getAttribute("name");
|
||||
String attrValue = sockJsElement.getAttribute("name");
|
||||
if (!attrValue.isEmpty()) {
|
||||
sockJsServiceDef.getPropertyValues().add("name", attrValue);
|
||||
}
|
||||
|
|
@ -125,43 +124,35 @@ class WebSocketNamespaceUtils {
|
|||
if (!attrValue.isEmpty()) {
|
||||
sockJsServiceDef.getPropertyValues().add("heartbeatTime", Long.valueOf(attrValue));
|
||||
}
|
||||
|
||||
sockJsServiceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
String sockJsServiceName = parserContext.getReaderContext().registerWithGeneratedName(sockJsServiceDef);
|
||||
String sockJsServiceName = context.getReaderContext().registerWithGeneratedName(sockJsServiceDef);
|
||||
return new RuntimeBeanReference(sockJsServiceName);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static RuntimeBeanReference registerSockJsTaskScheduler(String schedulerName,
|
||||
ParserContext parserContext, Object source) {
|
||||
|
||||
if (!parserContext.getRegistry().containsBeanDefinition(schedulerName)) {
|
||||
private static RuntimeBeanReference registerSockJsScheduler(String schedulerName, ParserContext context, Object source) {
|
||||
if (!context.getRegistry().containsBeanDefinition(schedulerName)) {
|
||||
RootBeanDefinition taskSchedulerDef = new RootBeanDefinition(ThreadPoolTaskScheduler.class);
|
||||
taskSchedulerDef.setSource(source);
|
||||
taskSchedulerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||
taskSchedulerDef.getPropertyValues().add("poolSize", Runtime.getRuntime().availableProcessors());
|
||||
taskSchedulerDef.getPropertyValues().add("threadNamePrefix", schedulerName + "-");
|
||||
taskSchedulerDef.getPropertyValues().add("removeOnCancelPolicy", true);
|
||||
parserContext.getRegistry().registerBeanDefinition(schedulerName, taskSchedulerDef);
|
||||
parserContext.registerComponent(new BeanComponentDefinition(taskSchedulerDef, schedulerName));
|
||||
context.getRegistry().registerBeanDefinition(schedulerName, taskSchedulerDef);
|
||||
context.registerComponent(new BeanComponentDefinition(taskSchedulerDef, schedulerName));
|
||||
}
|
||||
|
||||
return new RuntimeBeanReference(schedulerName);
|
||||
}
|
||||
|
||||
public static ManagedList<? super Object> parseBeanSubElements(Element parentElement, ParserContext parserContext) {
|
||||
|
||||
public static ManagedList<? super Object> parseBeanSubElements(Element parentElement, ParserContext context) {
|
||||
ManagedList<? super Object> beans = new ManagedList<Object>();
|
||||
if (parentElement != null) {
|
||||
beans.setSource(parserContext.extractSource(parentElement));
|
||||
for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, new String[] { "bean", "ref" })) {
|
||||
Object object = parserContext.getDelegate().parsePropertySubElement(beanElement, null);
|
||||
beans.add(object);
|
||||
beans.setSource(context.extractSource(parentElement));
|
||||
for (Element beanElement : DomUtils.getChildElementsByTagName(parentElement, new String[] {"bean", "ref"})) {
|
||||
beans.add(context.getDelegate().parsePropertySubElement(beanElement, null));
|
||||
}
|
||||
}
|
||||
|
||||
return beans;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -41,7 +41,7 @@ import org.springframework.web.socket.CloseStatus;
|
|||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.server.HandshakeFailureException;
|
||||
import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
|
||||
import org.springframework.web.socket.server.HandshakeHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
import org.springframework.web.socket.server.support.DefaultHandshakeHandler;
|
||||
|
|
@ -59,6 +59,7 @@ import org.springframework.web.socket.sockjs.transport.handler.XhrPollingTranspo
|
|||
import org.springframework.web.socket.sockjs.transport.handler.XhrReceivingTransportHandler;
|
||||
import org.springframework.web.socket.sockjs.transport.handler.XhrStreamingTransportHandler;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
|
|
@ -66,46 +67,46 @@ import static org.junit.Assert.*;
|
|||
* See test configuration files websocket-config-handlers-*.xml.
|
||||
*
|
||||
* @author Brian Clozel
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class HandlersBeanDefinitionParserTests {
|
||||
|
||||
private GenericWebApplicationContext appContext;
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
appContext = new GenericWebApplicationContext();
|
||||
this.appContext = new GenericWebApplicationContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
public void webSocketHandlers() {
|
||||
loadBeanDefinitions("websocket-config-handlers.xml");
|
||||
Map<String, HandlerMapping> handlersMap = appContext.getBeansOfType(HandlerMapping.class);
|
||||
|
||||
Map<String, HandlerMapping> handlersMap = this.appContext.getBeansOfType(HandlerMapping.class);
|
||||
assertNotNull(handlersMap);
|
||||
assertThat(handlersMap.values(), Matchers.hasSize(2));
|
||||
assertThat(handlersMap.values(), hasSize(2));
|
||||
|
||||
for(HandlerMapping handlerMapping : handlersMap.values()) {
|
||||
assertTrue(handlerMapping instanceof SimpleUrlHandlerMapping);
|
||||
SimpleUrlHandlerMapping urlHandlerMapping = (SimpleUrlHandlerMapping) handlerMapping;
|
||||
for (HandlerMapping hm : handlersMap.values()) {
|
||||
assertTrue(hm instanceof SimpleUrlHandlerMapping);
|
||||
SimpleUrlHandlerMapping shm = (SimpleUrlHandlerMapping) hm;
|
||||
|
||||
if(urlHandlerMapping.getUrlMap().keySet().contains("/foo")) {
|
||||
assertThat(urlHandlerMapping.getUrlMap().keySet(),Matchers.contains("/foo","/bar"));
|
||||
WebSocketHttpRequestHandler handler = (WebSocketHttpRequestHandler)
|
||||
urlHandlerMapping.getUrlMap().get("/foo");
|
||||
if (shm.getUrlMap().keySet().contains("/foo")) {
|
||||
assertThat(shm.getUrlMap().keySet(), contains("/foo", "/bar"));
|
||||
WebSocketHttpRequestHandler handler = (WebSocketHttpRequestHandler) shm.getUrlMap().get("/foo");
|
||||
assertNotNull(handler);
|
||||
checkDelegateHandlerType(handler.getWebSocketHandler(), FooWebSocketHandler.class);
|
||||
HandshakeHandler handshakeHandler = (HandshakeHandler)
|
||||
new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
|
||||
unwrapAndCheckDecoratedHandlerType(handler.getWebSocketHandler(), FooWebSocketHandler.class);
|
||||
HandshakeHandler handshakeHandler = handler.getHandshakeHandler();
|
||||
assertNotNull(handshakeHandler);
|
||||
assertTrue(handshakeHandler instanceof DefaultHandshakeHandler);
|
||||
}
|
||||
else {
|
||||
assertThat(urlHandlerMapping.getUrlMap().keySet(),Matchers.contains("/test"));
|
||||
WebSocketHttpRequestHandler handler = (WebSocketHttpRequestHandler)
|
||||
urlHandlerMapping.getUrlMap().get("/test");
|
||||
assertThat(shm.getUrlMap().keySet(), contains("/test"));
|
||||
WebSocketHttpRequestHandler handler = (WebSocketHttpRequestHandler) shm.getUrlMap().get("/test");
|
||||
assertNotNull(handler);
|
||||
checkDelegateHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
HandshakeHandler handshakeHandler = (HandshakeHandler)
|
||||
new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
|
||||
unwrapAndCheckDecoratedHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
HandshakeHandler handshakeHandler = handler.getHandshakeHandler();
|
||||
assertNotNull(handshakeHandler);
|
||||
assertTrue(handshakeHandler instanceof DefaultHandshakeHandler);
|
||||
}
|
||||
|
|
@ -114,9 +115,10 @@ public class HandlersBeanDefinitionParserTests {
|
|||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void websocketHandlersAttributes() {
|
||||
public void webSocketHandlersAttributes() {
|
||||
loadBeanDefinitions("websocket-config-handlers-attributes.xml");
|
||||
HandlerMapping handlerMapping = appContext.getBean(HandlerMapping.class);
|
||||
|
||||
HandlerMapping handlerMapping = this.appContext.getBean(HandlerMapping.class);
|
||||
assertNotNull(handlerMapping);
|
||||
assertTrue(handlerMapping instanceof SimpleUrlHandlerMapping);
|
||||
|
||||
|
|
@ -125,142 +127,155 @@ public class HandlersBeanDefinitionParserTests {
|
|||
|
||||
WebSocketHttpRequestHandler handler = (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/foo");
|
||||
assertNotNull(handler);
|
||||
checkDelegateHandlerType(handler.getWebSocketHandler(), FooWebSocketHandler.class);
|
||||
HandshakeHandler handshakeHandler = (HandshakeHandler)
|
||||
new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
|
||||
unwrapAndCheckDecoratedHandlerType(handler.getWebSocketHandler(), FooWebSocketHandler.class);
|
||||
HandshakeHandler handshakeHandler = handler.getHandshakeHandler();
|
||||
assertNotNull(handshakeHandler);
|
||||
assertTrue(handshakeHandler instanceof TestHandshakeHandler);
|
||||
List<HandshakeInterceptor> handshakeInterceptorList = (List<HandshakeInterceptor>)
|
||||
new DirectFieldAccessor(handler).getPropertyValue("interceptors");
|
||||
assertNotNull(handshakeInterceptorList);
|
||||
assertThat(handshakeInterceptorList, Matchers.contains(
|
||||
Matchers.instanceOf(FooTestInterceptor.class), Matchers.instanceOf(BarTestInterceptor.class)));
|
||||
List<HandshakeInterceptor> interceptors = handler.getHandshakeInterceptors();
|
||||
assertNotNull(interceptors);
|
||||
assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class)));
|
||||
|
||||
handler = (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/test");
|
||||
assertNotNull(handler);
|
||||
checkDelegateHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
handshakeHandler = (HandshakeHandler) new DirectFieldAccessor(handler).getPropertyValue("handshakeHandler");
|
||||
unwrapAndCheckDecoratedHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
handshakeHandler = handler.getHandshakeHandler();
|
||||
assertNotNull(handshakeHandler);
|
||||
assertTrue(handshakeHandler instanceof TestHandshakeHandler);
|
||||
handshakeInterceptorList = (List<HandshakeInterceptor>)
|
||||
new DirectFieldAccessor(handler).getPropertyValue("interceptors");
|
||||
assertNotNull(handshakeInterceptorList);
|
||||
assertThat(handshakeInterceptorList, Matchers.contains(
|
||||
Matchers.instanceOf(FooTestInterceptor.class), Matchers.instanceOf(BarTestInterceptor.class)));
|
||||
interceptors = handler.getHandshakeInterceptors();
|
||||
assertNotNull(interceptors);
|
||||
assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class)));
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sockJsSupport() {
|
||||
public void sockJs() {
|
||||
loadBeanDefinitions("websocket-config-handlers-sockjs.xml");
|
||||
SimpleUrlHandlerMapping handlerMapping = appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = this.appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||
assertNotNull(handlerMapping);
|
||||
|
||||
SockJsHttpRequestHandler testHandler = (SockJsHttpRequestHandler) handlerMapping.getUrlMap().get("/test/**");
|
||||
assertNotNull(testHandler);
|
||||
checkDelegateHandlerType(testHandler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
unwrapAndCheckDecoratedHandlerType(testHandler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
SockJsService testSockJsService = testHandler.getSockJsService();
|
||||
|
||||
SockJsHttpRequestHandler fooHandler = (SockJsHttpRequestHandler) handlerMapping.getUrlMap().get("/foo/**");
|
||||
assertNotNull(fooHandler);
|
||||
checkDelegateHandlerType(fooHandler.getWebSocketHandler(), FooWebSocketHandler.class);
|
||||
|
||||
unwrapAndCheckDecoratedHandlerType(fooHandler.getWebSocketHandler(), FooWebSocketHandler.class);
|
||||
SockJsService sockJsService = fooHandler.getSockJsService();
|
||||
assertNotNull(sockJsService);
|
||||
assertEquals(testSockJsService, sockJsService);
|
||||
|
||||
assertThat(sockJsService, Matchers.instanceOf(DefaultSockJsService.class));
|
||||
assertSame(testSockJsService, sockJsService);
|
||||
|
||||
assertThat(sockJsService, instanceOf(DefaultSockJsService.class));
|
||||
DefaultSockJsService defaultSockJsService = (DefaultSockJsService) sockJsService;
|
||||
assertThat(defaultSockJsService.getTaskScheduler(), Matchers.instanceOf(ThreadPoolTaskScheduler.class));
|
||||
assertThat(defaultSockJsService.getTransportHandlers().values(), Matchers.containsInAnyOrder(
|
||||
Matchers.instanceOf(XhrPollingTransportHandler.class),
|
||||
Matchers.instanceOf(XhrReceivingTransportHandler.class),
|
||||
Matchers.instanceOf(JsonpPollingTransportHandler.class),
|
||||
Matchers.instanceOf(JsonpReceivingTransportHandler.class),
|
||||
Matchers.instanceOf(XhrStreamingTransportHandler.class),
|
||||
Matchers.instanceOf(EventSourceTransportHandler.class),
|
||||
Matchers.instanceOf(HtmlFileTransportHandler.class),
|
||||
Matchers.instanceOf(WebSocketTransportHandler.class)));
|
||||
|
||||
assertThat(defaultSockJsService.getTaskScheduler(), instanceOf(ThreadPoolTaskScheduler.class));
|
||||
assertThat(defaultSockJsService.getTransportHandlers().values(),
|
||||
containsInAnyOrder(
|
||||
instanceOf(XhrPollingTransportHandler.class),
|
||||
instanceOf(XhrReceivingTransportHandler.class),
|
||||
instanceOf(JsonpPollingTransportHandler.class),
|
||||
instanceOf(JsonpReceivingTransportHandler.class),
|
||||
instanceOf(XhrStreamingTransportHandler.class),
|
||||
instanceOf(EventSourceTransportHandler.class),
|
||||
instanceOf(HtmlFileTransportHandler.class),
|
||||
instanceOf(WebSocketTransportHandler.class)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void sockJsAttributesSupport() {
|
||||
public void sockJsAttributes() {
|
||||
loadBeanDefinitions("websocket-config-handlers-sockjs-attributes.xml");
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||
assertNotNull(handlerMapping);
|
||||
|
||||
SockJsHttpRequestHandler handler = (SockJsHttpRequestHandler) handlerMapping.getUrlMap().get("/test/**");
|
||||
assertNotNull(handler);
|
||||
checkDelegateHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
unwrapAndCheckDecoratedHandlerType(handler.getWebSocketHandler(), TestWebSocketHandler.class);
|
||||
|
||||
SockJsService sockJsService = handler.getSockJsService();
|
||||
assertNotNull(sockJsService);
|
||||
assertThat(sockJsService, Matchers.instanceOf(TransportHandlingSockJsService.class));
|
||||
TransportHandlingSockJsService defaultSockJsService = (TransportHandlingSockJsService) sockJsService;
|
||||
assertThat(defaultSockJsService.getTaskScheduler(), Matchers.instanceOf(TestTaskScheduler.class));
|
||||
assertThat(defaultSockJsService.getTransportHandlers().values(), Matchers.containsInAnyOrder(
|
||||
Matchers.instanceOf(XhrPollingTransportHandler.class),
|
||||
Matchers.instanceOf(XhrStreamingTransportHandler.class)));
|
||||
assertThat(sockJsService, instanceOf(TransportHandlingSockJsService.class));
|
||||
TransportHandlingSockJsService transportService = (TransportHandlingSockJsService) sockJsService;
|
||||
assertThat(transportService.getTaskScheduler(), instanceOf(TestTaskScheduler.class));
|
||||
assertThat(transportService.getTransportHandlers().values(),
|
||||
containsInAnyOrder(
|
||||
instanceOf(XhrPollingTransportHandler.class),
|
||||
instanceOf(XhrStreamingTransportHandler.class)));
|
||||
|
||||
assertEquals("testSockJsService", defaultSockJsService.getName());
|
||||
assertFalse(defaultSockJsService.isWebSocketEnabled());
|
||||
assertFalse(defaultSockJsService.isSessionCookieNeeded());
|
||||
assertEquals(2048, defaultSockJsService.getStreamBytesLimit());
|
||||
assertEquals(256, defaultSockJsService.getDisconnectDelay());
|
||||
assertEquals(1024, defaultSockJsService.getHttpMessageCacheSize());
|
||||
assertEquals(20, defaultSockJsService.getHeartbeatTime());
|
||||
assertEquals("testSockJsService", transportService.getName());
|
||||
assertFalse(transportService.isWebSocketEnabled());
|
||||
assertFalse(transportService.isSessionCookieNeeded());
|
||||
assertEquals(2048, transportService.getStreamBytesLimit());
|
||||
assertEquals(256, transportService.getDisconnectDelay());
|
||||
assertEquals(1024, transportService.getHttpMessageCacheSize());
|
||||
assertEquals(20, transportService.getHeartbeatTime());
|
||||
}
|
||||
|
||||
private void loadBeanDefinitions(String fileName) {
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
|
||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this.appContext);
|
||||
ClassPathResource resource = new ClassPathResource(fileName, HandlersBeanDefinitionParserTests.class);
|
||||
reader.loadBeanDefinitions(resource);
|
||||
appContext.refresh();
|
||||
this.appContext.refresh();
|
||||
}
|
||||
|
||||
private void checkDelegateHandlerType(WebSocketHandler handler, Class<?> handlerClass) {
|
||||
do {
|
||||
handler = (WebSocketHandler) new DirectFieldAccessor(handler).getPropertyValue("delegate");
|
||||
private static void unwrapAndCheckDecoratedHandlerType(WebSocketHandler handler, Class<?> handlerClass) {
|
||||
if (handler instanceof WebSocketHandlerDecorator) {
|
||||
handler = ((WebSocketHandlerDecorator) handler).getLastHandler();
|
||||
}
|
||||
while (new DirectFieldAccessor(handler).isReadableProperty("delegate"));
|
||||
assertTrue(handlerClass.isInstance(handler));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
class TestWebSocketHandler implements WebSocketHandler {
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) throws Exception {}
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {}
|
||||
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {}
|
||||
public void handleTransportError(WebSocketSession session, Throwable exception) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {}
|
||||
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsPartialMessages() { return false; }
|
||||
}
|
||||
|
||||
class FooWebSocketHandler extends TestWebSocketHandler { }
|
||||
|
||||
class TestHandshakeHandler implements HandshakeHandler {
|
||||
@Override
|
||||
public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler, Map<String, Object> attributes) throws HandshakeFailureException {
|
||||
public boolean supportsPartialMessages() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class TestChannelInterceptor extends ChannelInterceptorAdapter { }
|
||||
class FooWebSocketHandler extends TestWebSocketHandler {
|
||||
}
|
||||
|
||||
class TestHandshakeHandler implements HandshakeHandler {
|
||||
|
||||
@Override
|
||||
public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler, Map<String, Object> attributes) {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class TestChannelInterceptor extends ChannelInterceptorAdapter {
|
||||
}
|
||||
|
||||
class FooTestInterceptor implements HandshakeInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
||||
WebSocketHandler wsHandler, Map<String, Object> attributes) {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -270,25 +285,40 @@ class FooTestInterceptor implements HandshakeInterceptor {
|
|||
}
|
||||
}
|
||||
|
||||
class BarTestInterceptor extends FooTestInterceptor {}
|
||||
class BarTestInterceptor extends FooTestInterceptor {
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
class TestTaskScheduler implements TaskScheduler {
|
||||
@Override
|
||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) { return null; }
|
||||
|
||||
@Override
|
||||
public ScheduledFuture schedule(Runnable task, Date startTime) { return null; }
|
||||
public ScheduledFuture schedule(Runnable task, Trigger trigger) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) { return null; }
|
||||
public ScheduledFuture schedule(Runnable task, Date startTime) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) { return null; }
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, Date startTime, long period) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) { return null; }
|
||||
public ScheduledFuture scheduleAtFixedRate(Runnable task, long period) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) { return null; }
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, Date startTime, long delay) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScheduledFuture scheduleWithFixedDelay(Runnable task, long delay) {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,6 +16,8 @@
|
|||
|
||||
package org.springframework.web.socket.config;
|
||||
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.instanceOf;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -60,6 +62,7 @@ import org.springframework.web.socket.handler.WebSocketHandlerDecorator;
|
|||
import org.springframework.web.socket.messaging.StompSubProtocolHandler;
|
||||
import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler;
|
||||
import org.springframework.web.socket.server.HandshakeHandler;
|
||||
import org.springframework.web.socket.server.HandshakeInterceptor;
|
||||
import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler;
|
||||
import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler;
|
||||
import org.springframework.web.socket.sockjs.transport.TransportType;
|
||||
|
|
@ -87,9 +90,7 @@ public class MessageBrokerBeanDefinitionParserTests {
|
|||
loadBeanDefinitions("websocket-config-broker-simple.xml");
|
||||
|
||||
HandlerMapping hm = this.appContext.getBean(HandlerMapping.class);
|
||||
assertNotNull(hm);
|
||||
assertThat(hm, Matchers.instanceOf(SimpleUrlHandlerMapping.class));
|
||||
|
||||
SimpleUrlHandlerMapping suhm = (SimpleUrlHandlerMapping) hm;
|
||||
assertThat(suhm.getUrlMap().keySet(), Matchers.hasSize(4));
|
||||
assertThat(suhm.getUrlMap().values(), Matchers.hasSize(4));
|
||||
|
|
@ -99,9 +100,7 @@ public class MessageBrokerBeanDefinitionParserTests {
|
|||
assertThat(httpRequestHandler, Matchers.instanceOf(WebSocketHttpRequestHandler.class));
|
||||
|
||||
WebSocketHttpRequestHandler wsHttpRequestHandler = (WebSocketHttpRequestHandler) httpRequestHandler;
|
||||
|
||||
HandshakeHandler handshakeHandler = (HandshakeHandler)
|
||||
new DirectFieldAccessor(wsHttpRequestHandler).getPropertyValue("handshakeHandler");
|
||||
HandshakeHandler handshakeHandler = wsHttpRequestHandler.getHandshakeHandler();
|
||||
assertNotNull(handshakeHandler);
|
||||
assertTrue(handshakeHandler instanceof TestHandshakeHandler);
|
||||
|
||||
|
|
@ -114,8 +113,7 @@ public class MessageBrokerBeanDefinitionParserTests {
|
|||
assertEquals(25 * 1000, subProtocolWsHandler.getSendTimeLimit());
|
||||
assertEquals(1024 * 1024, subProtocolWsHandler.getSendBufferSizeLimit());
|
||||
|
||||
StompSubProtocolHandler stompHandler =
|
||||
(StompSubProtocolHandler) subProtocolWsHandler.getProtocolHandlerMap().get("v12.stomp");
|
||||
StompSubProtocolHandler stompHandler = (StompSubProtocolHandler) subProtocolWsHandler.getProtocolHandlerMap().get("v12.stomp");
|
||||
assertNotNull(stompHandler);
|
||||
assertEquals(128 * 1024, stompHandler.getMessageSizeLimit());
|
||||
|
||||
|
|
@ -170,8 +168,7 @@ public class MessageBrokerBeanDefinitionParserTests {
|
|||
testChannel("clientOutboundChannel", subscriberTypes, 0);
|
||||
testExecutor("clientOutboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60);
|
||||
|
||||
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(
|
||||
SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
|
||||
subscriberTypes = Arrays.<Class<? extends MessageHandler>>asList(SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class);
|
||||
testChannel("brokerChannel", subscriberTypes, 0);
|
||||
try {
|
||||
this.appContext.getBean("brokerChannelExecutor", ThreadPoolTaskExecutor.class);
|
||||
|
|
|
|||
Loading…
Reference in New Issue