From 6557800f97170e4f27eb1ad95b469bea6090cdce Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 14 Jul 2014 23:52:29 -0400 Subject: [PATCH 1/5] Polish WebSocket namespace --- .../config/HandlersBeanDefinitionParser.java | 141 +++--- .../MessageBrokerBeanDefinitionParser.java | 438 +++++++----------- .../config/WebSocketNamespaceUtils.java | 61 ++- .../HandlersBeanDefinitionParserTests.java | 230 +++++---- ...essageBrokerBeanDefinitionParserTests.java | 15 +- 5 files changed, 401 insertions(+), 484 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java index ca430f8cc70..4b973ee0a99 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/HandlersBeanDefinitionParser.java @@ -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 } 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 } 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 mappingElements = DomUtils.getChildElementsByTagName(element, "mapping"); ManagedMap urlMap = new ManagedMap(); 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 createMappings(Element mappingElement, ParserContext parserContext); + void addMapping(Element mappingElement, ManagedMap map, ParserContext context); + } - private HandlerMappingStrategy createHandlerMappingStrategy( - RuntimeBeanReference sockJsServiceRef, RuntimeBeanReference handshakeHandlerRef, - ManagedList 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 createMappings(Element mappingElement, ParserContext parserContext) { - ManagedMap urlMap = new ManagedMap(); - Object source = parserContext.extractSource(mappingElement); - - String path = mappingElement.getAttribute("path"); - List mappings = Arrays.asList(StringUtils.tokenizeToStringArray(path, ",")); - RuntimeBeanReference webSocketHandlerReference = new RuntimeBeanReference(mappingElement.getAttribute("handler")); + public void addMapping(Element element, ManagedMap urlMap, ParserContext context) { + String pathAttribute = element.getAttribute("path"); + List 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 createMappings(Element mappingElement, ParserContext parserContext) { - - ManagedMap urlMap = new ManagedMap(); - Object source = parserContext.extractSource(mappingElement); - - String pathValue = mappingElement.getAttribute("path"); - List mappings = Arrays.asList(StringUtils.tokenizeToStringArray(pathValue, ",")); - RuntimeBeanReference webSocketHandlerReference = new RuntimeBeanReference(mappingElement.getAttribute("handler")); + public void addMapping(Element element, ManagedMap urlMap, ParserContext context) { + String pathAttribute = element.getAttribute("path"); + List 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; } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index cb9456f1601..6027fc3c90a 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -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 urlMap = new ManagedMap(); 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 (no path mapping)"); - List paths = Arrays.asList(StringUtils.tokenizeToStringArray(pathAttribute, ",")); for(String path : paths) { path = path.trim(); Assert.state(StringUtils.hasText(path), "Invalid 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 scopeMap = Collections.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 nor 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 convertersDef = new ManagedList(); + ManagedList converters = new ManagedList(); 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)); } } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java index 51cbacbc4e2..bc7d3b804bd 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java @@ -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 parseBeanSubElements(Element parentElement, ParserContext parserContext) { - + public static ManagedList parseBeanSubElements(Element parentElement, ParserContext context) { ManagedList beans = new ManagedList(); 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; } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java index 0d46c9c48e9..163ddcab901 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java @@ -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 handlersMap = appContext.getBeansOfType(HandlerMapping.class); + + Map 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 handshakeInterceptorList = (List) - new DirectFieldAccessor(handler).getPropertyValue("interceptors"); - assertNotNull(handshakeInterceptorList); - assertThat(handshakeInterceptorList, Matchers.contains( - Matchers.instanceOf(FooTestInterceptor.class), Matchers.instanceOf(BarTestInterceptor.class))); + List 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) - 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 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 attributes) { + + return false; + } +} + +class TestChannelInterceptor extends ChannelInterceptorAdapter { +} class FooTestInterceptor implements HandshakeInterceptor { + @Override public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, - WebSocketHandler wsHandler, Map attributes) throws Exception { + WebSocketHandler wsHandler, Map 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; + } + } \ No newline at end of file diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java index d77b650bcff..8066de25440 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java @@ -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.>asList( - SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class); + subscriberTypes = Arrays.>asList(SimpleBrokerMessageHandler.class, UserDestinationMessageHandler.class); testChannel("brokerChannel", subscriberTypes, 0); try { this.appContext.getBean("brokerChannelExecutor", ThreadPoolTaskExecutor.class); From 61e77eeb61394e8e719e4e06216e55491743652e Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 15 Jul 2014 08:23:56 -0400 Subject: [PATCH 2/5] Fix white spaces --- .../socket/config/spring-websocket-4.0.xsd | 744 +++++++++--------- .../socket/config/spring-websocket-4.1.xsd | 744 +++++++++--------- ...-config-broker-converters-defaults-off.xml | 20 +- .../websocket-config-broker-converters.xml | 20 +- ...broker-customchannels-default-executor.xml | 46 +- ...websocket-config-broker-customchannels.xml | 54 +- .../config/websocket-config-broker-relay.xml | 28 +- .../config/websocket-config-broker-simple.xml | 32 +- .../websocket-config-handlers-attributes.xml | 32 +- ...cket-config-handlers-sockjs-attributes.xml | 40 +- .../websocket-config-handlers-sockjs.xml | 20 +- .../config/websocket-config-handlers.xml | 22 +- 12 files changed, 901 insertions(+), 901 deletions(-) diff --git a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd index c2997384ea2..1c355d1af21 100644 --- a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd +++ b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd @@ -17,133 +17,133 @@ --> + xmlns:xsd="http://www.w3.org/2001/XMLSchema" + xmlns:beans="http://www.springframework.org/schema/beans" + targetNamespace="http://www.springframework.org/schema/websocket" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> - + - - - + + - - - - + + + - - - - - + + + + - - - + + + - - - - + + + - - - + + + - - - + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + + - - - + + - - - - - + + + + - - - - - - - + + + + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - - + + + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - + + - - - - + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - + + - - - - + + + - - - + + + - - - - - - + + + + + + - - - + + - - - - + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + + - + - - - + + - - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - + + + + - - - - - + + + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + - - - - + + + + diff --git a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd index 43bce0b891a..71a1f76b24a 100644 --- a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd +++ b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd @@ -17,134 +17,134 @@ --> + targetNamespace="http://www.springframework.org/schema/websocket" + elementFormDefault="qualified" + attributeFormDefault="unqualified"> - - + + - - - + + - - - - + + + - - - - - + + + + - - - + + + - - - - + + + - - - + + + - - - + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + + - - - + + - - - - - + + + + - - - - - - - + + + + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - - + + + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - + + - - - - + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - + + - - - - + + + - - - + + + - - - - - - + + + + + + - - - + + - - - - + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - + + + - - - + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + + - + - - - + + - - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - + + - - - - - - + + + + + - - - - - + + + + - - - - - + + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - - - + + + + + + + + - - - - - - - - - - - + + + + + + + + + + - - - - - - - + + + + + + - - - - - + + + + - - - - - - - + + + + + + - - - - - - - + + + + + + - - - - - + + + + - - - - - + + + + - - - - - - + + + + + - - - - - + + + + - - + + - - - + + - - - - + + + + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml index 8cc18e54007..0da56b8e128 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters-defaults-off.xml @@ -1,19 +1,19 @@ - + - + - + - - - + + + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml index 86c0fbfba44..80a664ccc1b 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-converters.xml @@ -1,19 +1,19 @@ - + - + - + - - - + + + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml index 1e68eccc812..ef38534a840 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml @@ -1,30 +1,30 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml index 2b07d476eab..e8908da1a17 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels.xml @@ -1,34 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml index a7527ce43f8..eb3b9c4d6eb 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-relay.xml @@ -1,20 +1,20 @@ - - - - - - + + + + + + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml index aa2acc0fa58..d89a7f42230 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml @@ -1,33 +1,33 @@ - - - + + - - - + + + - - - - + + + + - + - + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml index bbde4d4dce8..9cc65a3426a 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-attributes.xml @@ -1,24 +1,24 @@ - - - - - - - - - + + + + + + + + + - - + + - - + + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml index f40e41f6708..8e7ab6cd45a 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml @@ -1,29 +1,29 @@ - - - - - - - - - + + + + + + + + + - + - + - + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml index c39d33fd361..689cddd19be 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml @@ -1,17 +1,17 @@ - - - - - + + + + + - - + + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml index 9de9921e4cc..138eb8e3c32 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers.xml @@ -1,19 +1,19 @@ - - - + + + - - - + + + - - + + From 85c175059a3cd51958103e37d948811fa16a47af Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 15 Jul 2014 09:46:53 -0400 Subject: [PATCH 3/5] Add missing handshake-interceptor namespace support Issue: SPR-11845 --- .../MessageBrokerBeanDefinitionParser.java | 3 +++ .../socket/config/WebSocketNamespaceUtils.java | 6 +++++- .../web/socket/config/spring-websocket-4.0.xsd | 1 + .../web/socket/config/spring-websocket-4.1.xsd | 1 + .../HandlersBeanDefinitionParserTests.java | 16 ++++++++++++---- .../MessageBrokerBeanDefinitionParserTests.java | 8 ++++++++ .../config/websocket-config-broker-simple.xml | 9 +++++++++ ...bsocket-config-handlers-sockjs-attributes.xml | 11 +++-------- .../config/websocket-config-handlers-sockjs.xml | 7 +++++++ 9 files changed, 49 insertions(+), 13 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java index 6027fc3c90a..4785d161091 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParser.java @@ -263,12 +263,15 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { } else { RuntimeBeanReference handshakeHandler = WebSocketNamespaceUtils.registerHandshakeHandler(element, context, source); + Element interceptorsElement = DomUtils.getChildElementByTagName(element, "handshake-interceptors"); + ManagedList interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, context); ConstructorArgumentValues cavs = new ConstructorArgumentValues(); cavs.addIndexedArgumentValue(0, subProtoHandler); if (handshakeHandler != null) { cavs.addIndexedArgumentValue(1, handshakeHandler); } beanDef = new RootBeanDefinition(WebSocketHttpRequestHandler.class, cavs, null); + beanDef.getPropertyValues().add("handshakeInterceptors", interceptors); } return new RuntimeBeanReference(registerBeanDef(beanDef, context, source)); } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java index bc7d3b804bd..bc1763cce1b 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/WebSocketNamespaceUtils.java @@ -96,7 +96,11 @@ class WebSocketNamespaceUtils { sockJsServiceDef.getConstructorArgumentValues().addIndexedArgumentValue(1, transportHandler); } - String attrValue = sockJsElement.getAttribute("name"); + Element interceptorsElement = DomUtils.getChildElementByTagName(element, "handshake-interceptors"); + ManagedList interceptors = WebSocketNamespaceUtils.parseBeanSubElements(interceptorsElement, context); + sockJsServiceDef.getPropertyValues().add("handshakeInterceptors", interceptors); + + String attrValue = sockJsElement.getAttribute("name"); if (!attrValue.isEmpty()) { sockJsServiceDef.getPropertyValues().add("name", attrValue); } diff --git a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd index 1c355d1af21..d69f5006a0f 100644 --- a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd +++ b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.0.xsd @@ -589,6 +589,7 @@ + diff --git a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd index 71a1f76b24a..447928b262c 100644 --- a/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd +++ b/spring-websocket/src/main/resources/org/springframework/web/socket/config/spring-websocket-4.1.xsd @@ -590,6 +590,7 @@ + diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java index 163ddcab901..0f4a02e345c 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/HandlersBeanDefinitionParserTests.java @@ -48,7 +48,9 @@ import org.springframework.web.socket.server.support.DefaultHandshakeHandler; import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler; import org.springframework.web.socket.sockjs.SockJsService; import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler; +import org.springframework.web.socket.sockjs.transport.TransportHandler; import org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService; +import org.springframework.web.socket.sockjs.transport.TransportType; import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService; import org.springframework.web.socket.sockjs.transport.handler.EventSourceTransportHandler; import org.springframework.web.socket.sockjs.transport.handler.HtmlFileTransportHandler; @@ -79,8 +81,8 @@ public class HandlersBeanDefinitionParserTests { this.appContext = new GenericWebApplicationContext(); } - @Test + @Test public void webSocketHandlers() { loadBeanDefinitions("websocket-config-handlers.xml"); @@ -132,7 +134,6 @@ public class HandlersBeanDefinitionParserTests { assertNotNull(handshakeHandler); assertTrue(handshakeHandler instanceof TestHandshakeHandler); List interceptors = handler.getHandshakeInterceptors(); - assertNotNull(interceptors); assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class))); handler = (WebSocketHttpRequestHandler) urlHandlerMapping.getUrlMap().get("/test"); @@ -142,7 +143,6 @@ public class HandlersBeanDefinitionParserTests { assertNotNull(handshakeHandler); assertTrue(handshakeHandler instanceof TestHandshakeHandler); interceptors = handler.getHandshakeInterceptors(); - assertNotNull(interceptors); assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class))); } @@ -171,7 +171,9 @@ public class HandlersBeanDefinitionParserTests { assertThat(sockJsService, instanceOf(DefaultSockJsService.class)); DefaultSockJsService defaultSockJsService = (DefaultSockJsService) sockJsService; assertThat(defaultSockJsService.getTaskScheduler(), instanceOf(ThreadPoolTaskScheduler.class)); - assertThat(defaultSockJsService.getTransportHandlers().values(), + + Map transportHandlers = defaultSockJsService.getTransportHandlers(); + assertThat(transportHandlers.values(), containsInAnyOrder( instanceOf(XhrPollingTransportHandler.class), instanceOf(XhrReceivingTransportHandler.class), @@ -181,6 +183,12 @@ public class HandlersBeanDefinitionParserTests { instanceOf(EventSourceTransportHandler.class), instanceOf(HtmlFileTransportHandler.class), instanceOf(WebSocketTransportHandler.class))); + + WebSocketTransportHandler handler = (WebSocketTransportHandler) transportHandlers.get(TransportType.WEBSOCKET); + assertEquals(TestHandshakeHandler.class, handler.getHandshakeHandler().getClass()); + + List interceptors = defaultSockJsService.getHandshakeInterceptors(); + assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class))); } @Test diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java index 8066de25440..3cd52748bb7 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/MessageBrokerBeanDefinitionParserTests.java @@ -75,16 +75,19 @@ import org.springframework.web.socket.sockjs.transport.handler.WebSocketTranspor * * @author Brian Clozel * @author Artem Bilan + * @author Rossen Stoyanchev */ public class MessageBrokerBeanDefinitionParserTests { private GenericWebApplicationContext appContext; + @Before public void setup() { this.appContext = new GenericWebApplicationContext(); } + @Test public void simpleBroker() { loadBeanDefinitions("websocket-config-broker-simple.xml"); @@ -103,6 +106,8 @@ public class MessageBrokerBeanDefinitionParserTests { HandshakeHandler handshakeHandler = wsHttpRequestHandler.getHandshakeHandler(); assertNotNull(handshakeHandler); assertTrue(handshakeHandler instanceof TestHandshakeHandler); + List interceptors = wsHttpRequestHandler.getHandshakeInterceptors(); + assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class))); WebSocketHandler wsHandler = unwrapWebSocketHandler(wsHttpRequestHandler.getWebSocketHandler()); assertNotNull(wsHandler); @@ -140,6 +145,9 @@ public class MessageBrokerBeanDefinitionParserTests { assertEquals(Runtime.getRuntime().availableProcessors(), scheduler.getScheduledThreadPoolExecutor().getCorePoolSize()); assertTrue(scheduler.getScheduledThreadPoolExecutor().getRemoveOnCancelPolicy()); + interceptors = defaultSockJsService.getHandshakeInterceptors(); + assertThat(interceptors, contains(instanceOf(FooTestInterceptor.class), instanceOf(BarTestInterceptor.class))); + UserSessionRegistry userSessionRegistry = this.appContext.getBean(UserSessionRegistry.class); assertNotNull(userSessionRegistry); diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml index d89a7f42230..4f700be0195 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-simple.xml @@ -13,10 +13,18 @@ + + + + + + + + @@ -29,5 +37,6 @@ + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml index 8e7ab6cd45a..4a2476c45c4 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs-attributes.xml @@ -17,13 +17,8 @@ - - - - - + + + diff --git a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml index 689cddd19be..92c167772b5 100644 --- a/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-handlers-sockjs.xml @@ -8,10 +8,17 @@ + + + + + + + From 6d6cc0ecec9bdba48e81e337e15a07c1325e238b Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 15 Jul 2014 13:06:39 -0400 Subject: [PATCH 4/5] Polish WebSocket Java config --- .../AbstractWebSocketHandlerRegistration.java | 29 +++---- .../WebSocketHandlerRegistration.java | 10 +-- .../WebMvcStompEndpointRegistryTests.java | 24 +++--- ...mpWebSocketEndpointRegistrationTests.java} | 42 +++++----- .../WebSocketHandlerRegistrationTests.java | 77 +++++++++---------- ...essageBrokerConfigurationSupportTests.java | 2 - 6 files changed, 79 insertions(+), 105 deletions(-) rename spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/{WebMvcStompEndpointRegistrationTests.java => WebMvcStompWebSocketEndpointRegistrationTests.java} (72%) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketHandlerRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketHandlerRegistration.java index 9d3b01353cc..ef84ed883b0 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketHandlerRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/AbstractWebSocketHandlerRegistration.java @@ -38,15 +38,15 @@ import org.springframework.web.socket.sockjs.transport.handler.WebSocketTranspor */ public abstract class AbstractWebSocketHandlerRegistration implements WebSocketHandlerRegistration { - private MultiValueMap handlerMap = new LinkedMultiValueMap(); + private final TaskScheduler sockJsTaskScheduler; - private HandshakeInterceptor[] interceptors; + private MultiValueMap handlerMap = new LinkedMultiValueMap(); private HandshakeHandler handshakeHandler; - private SockJsServiceRegistration sockJsServiceRegistration; + private HandshakeInterceptor[] interceptors; - private final TaskScheduler sockJsTaskScheduler; + private SockJsServiceRegistration sockJsServiceRegistration; public AbstractWebSocketHandlerRegistration(TaskScheduler defaultTaskScheduler) { @@ -68,8 +68,8 @@ public abstract class AbstractWebSocketHandlerRegistration implements WebSock return this; } - public HandshakeHandler getHandshakeHandler() { - return handshakeHandler; + protected HandshakeHandler getHandshakeHandler() { + return this.handshakeHandler; } @Override @@ -82,30 +82,21 @@ public abstract class AbstractWebSocketHandlerRegistration implements WebSock return this.interceptors; } - /** - * @param interceptors the interceptors to set - */ - public void setInterceptors(HandshakeInterceptor[] interceptors) { - this.interceptors = interceptors; - } - @Override public SockJsServiceRegistration withSockJS() { - this.sockJsServiceRegistration = new SockJsServiceRegistration(this.sockJsTaskScheduler); - this.sockJsServiceRegistration.setInterceptors(this.interceptors); - + if (this.interceptors != null) { + this.sockJsServiceRegistration.setInterceptors(this.interceptors); + } if (this.handshakeHandler != null) { WebSocketTransportHandler transportHandler = new WebSocketTransportHandler(this.handshakeHandler); this.sockJsServiceRegistration.setTransportHandlerOverrides(transportHandler); } - return this.sockJsServiceRegistration; } - public final M getMappings() { + protected final M getMappings() { M mappings = createMappings(); - if (this.sockJsServiceRegistration != null) { SockJsService sockJsService = this.sockJsServiceRegistration.getSockJsService(); for (WebSocketHandler wsHandler : this.handlerMap.keySet()) { diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java index 8debdceb99f..622b1e73bde 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistration.java @@ -34,16 +34,16 @@ public interface WebSocketHandlerRegistration { */ WebSocketHandlerRegistration addHandler(WebSocketHandler handler, String... paths); - /** - * Configure interceptors for the handshake request. - */ - WebSocketHandlerRegistration addInterceptors(HandshakeInterceptor... interceptors); - /** * Configure the HandshakeHandler to use. */ WebSocketHandlerRegistration setHandshakeHandler(HandshakeHandler handshakeHandler); + /** + * Configure interceptors for the handshake request. + */ + WebSocketHandlerRegistration addInterceptors(HandshakeInterceptor... interceptors); + /** * Enable SockJS fallback options. */ diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistryTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistryTests.java index a2d823a15b9..82be51df93f 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistryTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistryTests.java @@ -35,13 +35,14 @@ import org.springframework.web.util.UrlPathHelper; import static org.junit.Assert.*; /** - * Test fixture for {@link org.springframework.web.socket.config.annotation.WebMvcStompEndpointRegistry}. + * Test fixture for + * {@link org.springframework.web.socket.config.annotation.WebMvcStompEndpointRegistry}. * * @author Rossen Stoyanchev */ public class WebMvcStompEndpointRegistryTests { - private WebMvcStompEndpointRegistry registry; + private WebMvcStompEndpointRegistry endpointRegistry; private SubProtocolWebSocketHandler webSocketHandler; @@ -50,22 +51,18 @@ public class WebMvcStompEndpointRegistryTests { @Before public void setup() { - SubscribableChannel inChannel = Mockito.mock(SubscribableChannel.class); SubscribableChannel outChannel = Mockito.mock(SubscribableChannel.class); - this.webSocketHandler = new SubProtocolWebSocketHandler(inChannel, outChannel); this.userSessionRegistry = new DefaultUserSessionRegistry(); - - this.registry = new WebMvcStompEndpointRegistry(this.webSocketHandler, + this.endpointRegistry = new WebMvcStompEndpointRegistry(this.webSocketHandler, new WebSocketTransportRegistration(), this.userSessionRegistry, Mockito.mock(TaskScheduler.class)); } @Test public void stompProtocolHandler() { - - this.registry.addEndpoint("/stomp"); + this.endpointRegistry.addEndpoint("/stomp"); Map protocolHandlers = webSocketHandler.getProtocolHandlerMap(); assertEquals(3, protocolHandlers.size()); @@ -79,16 +76,15 @@ public class WebMvcStompEndpointRegistryTests { @Test public void handlerMapping() { - - SimpleUrlHandlerMapping hm = (SimpleUrlHandlerMapping) this.registry.getHandlerMapping(); + SimpleUrlHandlerMapping hm = (SimpleUrlHandlerMapping) this.endpointRegistry.getHandlerMapping(); assertEquals(0, hm.getUrlMap().size()); UrlPathHelper pathHelper = new UrlPathHelper(); - this.registry.setUrlPathHelper(pathHelper); - this.registry.addEndpoint("/stompOverWebSocket"); - this.registry.addEndpoint("/stompOverSockJS").withSockJS(); + this.endpointRegistry.setUrlPathHelper(pathHelper); + this.endpointRegistry.addEndpoint("/stompOverWebSocket"); + this.endpointRegistry.addEndpoint("/stompOverSockJS").withSockJS(); - hm = (SimpleUrlHandlerMapping) this.registry.getHandlerMapping(); + hm = (SimpleUrlHandlerMapping) this.endpointRegistry.getHandlerMapping(); assertEquals(2, hm.getUrlMap().size()); assertNotNull(hm.getUrlMap().get("/stompOverWebSocket")); assertNotNull(hm.getUrlMap().get("/stompOverSockJS/**")); diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java similarity index 72% rename from spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistrationTests.java rename to spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java index 6128d10de13..56a0b9823ba 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompEndpointRegistrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,9 +22,9 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; -import org.mockito.Mockito; -import org.springframework.messaging.support.ExecutorSubscribableChannel; +import org.springframework.messaging.MessageChannel; +import org.springframework.messaging.SubscribableChannel; import org.springframework.scheduling.TaskScheduler; import org.springframework.util.MultiValueMap; import org.springframework.web.HttpRequestHandler; @@ -32,37 +32,37 @@ import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler; import org.springframework.web.socket.server.support.DefaultHandshakeHandler; import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler; import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler; +import org.springframework.web.socket.sockjs.transport.TransportHandler; import org.springframework.web.socket.sockjs.transport.TransportType; import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsService; import org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler; import static org.junit.Assert.*; +import static org.mockito.Mockito.mock; /** - * Test fixture for {@link org.springframework.web.socket.config.annotation.WebMvcStompWebSocketEndpointRegistration}. + * Test fixture for + * {@link org.springframework.web.socket.config.annotation.WebMvcStompWebSocketEndpointRegistration}. * * @author Rossen Stoyanchev */ -public class WebMvcStompEndpointRegistrationTests { +public class WebMvcStompWebSocketEndpointRegistrationTests { - private SubProtocolWebSocketHandler wsHandler; + private SubProtocolWebSocketHandler handler; private TaskScheduler scheduler; @Before public void setup() { - this.wsHandler = new SubProtocolWebSocketHandler( - new ExecutorSubscribableChannel(), new ExecutorSubscribableChannel()); - this.scheduler = Mockito.mock(TaskScheduler.class); + this.handler = new SubProtocolWebSocketHandler(mock(MessageChannel.class), mock(SubscribableChannel.class)); + this.scheduler = mock(TaskScheduler.class); } @Test public void minimalRegistration() { - - - WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration( - new String[] {"/foo"}, this.wsHandler, this.scheduler); + WebMvcStompWebSocketEndpointRegistration registration = + new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler); MultiValueMap mappings = registration.getMappings(); assertEquals(1, mappings.size()); @@ -74,12 +74,10 @@ public class WebMvcStompEndpointRegistrationTests { @Test public void customHandshakeHandler() { + WebMvcStompWebSocketEndpointRegistration registration = + new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler); DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler(); - - WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration( - new String[] {"/foo"}, this.wsHandler, this.scheduler); - registration.setHandshakeHandler(handshakeHandler); MultiValueMap mappings = registration.getMappings(); @@ -95,12 +93,10 @@ public class WebMvcStompEndpointRegistrationTests { @Test public void customHandshakeHandlerPassedToSockJsService() { + WebMvcStompWebSocketEndpointRegistration registration = + new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler); DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler(); - - WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration( - new String[] {"/foo"}, this.wsHandler, this.scheduler); - registration.setHandshakeHandler(handshakeHandler); registration.withSockJS(); @@ -116,8 +112,8 @@ public class WebMvcStompEndpointRegistrationTests { DefaultSockJsService sockJsService = (DefaultSockJsService) requestHandler.getSockJsService(); assertNotNull(sockJsService); - WebSocketTransportHandler transportHandler = - (WebSocketTransportHandler) sockJsService.getTransportHandlers().get(TransportType.WEBSOCKET); + Map handlers = sockJsService.getTransportHandlers(); + WebSocketTransportHandler transportHandler = (WebSocketTransportHandler) handlers.get(TransportType.WEBSOCKET); assertSame(handshakeHandler, transportHandler.getHandshakeHandler()); } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistrationTests.java index 4d96a531f65..64d1be83ffb 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketHandlerRegistrationTests.java @@ -38,7 +38,8 @@ import org.springframework.web.socket.sockjs.transport.handler.WebSocketTranspor import static org.junit.Assert.*; /** - * Test fixture for {@link org.springframework.web.socket.config.annotation.AbstractWebSocketHandlerRegistration}. + * Test fixture for + * {@link org.springframework.web.socket.config.annotation.AbstractWebSocketHandlerRegistration}. * * @author Rossen Stoyanchev */ @@ -57,99 +58,93 @@ public class WebSocketHandlerRegistrationTests { @Test public void minimal() { - - WebSocketHandler wsHandler = new TextWebSocketHandler(); - this.registration.addHandler(wsHandler, "/foo", "/bar"); + WebSocketHandler handler = new TextWebSocketHandler(); + this.registration.addHandler(handler, "/foo", "/bar"); List mappings = this.registration.getMappings(); assertEquals(2, mappings.size()); Mapping m1 = mappings.get(0); - assertEquals(wsHandler, m1.webSocketHandler); + assertEquals(handler, m1.webSocketHandler); assertEquals("/foo", m1.path); Mapping m2 = mappings.get(1); - assertEquals(wsHandler, m2.webSocketHandler); + assertEquals(handler, m2.webSocketHandler); assertEquals("/bar", m2.path); } @Test public void interceptors() { - - WebSocketHandler wsHandler = new TextWebSocketHandler(); + WebSocketHandler handler = new TextWebSocketHandler(); HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor(); - this.registration.addHandler(wsHandler, "/foo").addInterceptors(interceptor); + this.registration.addHandler(handler, "/foo").addInterceptors(interceptor); List mappings = this.registration.getMappings(); assertEquals(1, mappings.size()); - Mapping m1 = mappings.get(0); - assertEquals(wsHandler, m1.webSocketHandler); - assertEquals("/foo", m1.path); - assertArrayEquals(new HandshakeInterceptor[] { interceptor }, m1.interceptors); + Mapping mapping = mappings.get(0); + assertEquals(handler, mapping.webSocketHandler); + assertEquals("/foo", mapping.path); + assertArrayEquals(new HandshakeInterceptor[] {interceptor}, mapping.interceptors); } @Test public void interceptorsPassedToSockJsRegistration() { - - WebSocketHandler wsHandler = new TextWebSocketHandler(); + WebSocketHandler handler = new TextWebSocketHandler(); HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor(); - this.registration.addHandler(wsHandler, "/foo").addInterceptors(interceptor).withSockJS(); + this.registration.addHandler(handler, "/foo").addInterceptors(interceptor).withSockJS(); List mappings = this.registration.getMappings(); assertEquals(1, mappings.size()); - Mapping m1 = mappings.get(0); - assertEquals(wsHandler, m1.webSocketHandler); - assertEquals("/foo/**", m1.path); - assertNotNull(m1.sockJsService); - assertEquals(Arrays.asList(interceptor), m1.sockJsService.getHandshakeInterceptors()); + Mapping mapping = mappings.get(0); + assertEquals(handler, mapping.webSocketHandler); + assertEquals("/foo/**", mapping.path); + assertNotNull(mapping.sockJsService); + assertEquals(Arrays.asList(interceptor), mapping.sockJsService.getHandshakeInterceptors()); } @Test public void handshakeHandler() { - - WebSocketHandler wsHandler = new TextWebSocketHandler(); + WebSocketHandler handler = new TextWebSocketHandler(); HandshakeHandler handshakeHandler = new DefaultHandshakeHandler(); - this.registration.addHandler(wsHandler, "/foo").setHandshakeHandler(handshakeHandler); + this.registration.addHandler(handler, "/foo").setHandshakeHandler(handshakeHandler); List mappings = this.registration.getMappings(); assertEquals(1, mappings.size()); - Mapping m1 = mappings.get(0); - assertEquals(wsHandler, m1.webSocketHandler); - assertEquals("/foo", m1.path); - assertSame(handshakeHandler, m1.handshakeHandler); + Mapping mapping = mappings.get(0); + assertEquals(handler, mapping.webSocketHandler); + assertEquals("/foo", mapping.path); + assertSame(handshakeHandler, mapping.handshakeHandler); } @Test public void handshakeHandlerPassedToSockJsRegistration() { - - WebSocketHandler wsHandler = new TextWebSocketHandler(); + WebSocketHandler handler = new TextWebSocketHandler(); HandshakeHandler handshakeHandler = new DefaultHandshakeHandler(); - this.registration.addHandler(wsHandler, "/foo").setHandshakeHandler(handshakeHandler).withSockJS(); + this.registration.addHandler(handler, "/foo").setHandshakeHandler(handshakeHandler).withSockJS(); List mappings = this.registration.getMappings(); assertEquals(1, mappings.size()); - Mapping m1 = mappings.get(0); - assertEquals(wsHandler, m1.webSocketHandler); - assertEquals("/foo/**", m1.path); - assertNotNull(m1.sockJsService); + Mapping mapping = mappings.get(0); + assertEquals(handler, mapping.webSocketHandler); + assertEquals("/foo/**", mapping.path); + assertNotNull(mapping.sockJsService); WebSocketTransportHandler transportHandler = - (WebSocketTransportHandler) m1.sockJsService.getTransportHandlers().get(TransportType.WEBSOCKET); + (WebSocketTransportHandler) mapping.sockJsService.getTransportHandlers().get(TransportType.WEBSOCKET); assertSame(handshakeHandler, transportHandler.getHandshakeHandler()); } private static class TestWebSocketHandlerRegistration extends AbstractWebSocketHandlerRegistration> { - public TestWebSocketHandlerRegistration(TaskScheduler sockJsTaskScheduler) { super(sockJsTaskScheduler); } @@ -167,15 +162,13 @@ public class WebSocketHandlerRegistrationTests { } @Override - protected void addWebSocketHandlerMapping(List mappings, - WebSocketHandler wsHandler, HandshakeHandler handshakeHandler, - HandshakeInterceptor[] interceptors, String path) { + protected void addWebSocketHandlerMapping(List mappings, WebSocketHandler handler, + HandshakeHandler handshakeHandler, HandshakeInterceptor[] interceptors, String path) { - mappings.add(new Mapping(wsHandler, path, handshakeHandler, interceptors)); + mappings.add(new Mapping(handler, path, handshakeHandler, interceptors)); } } - private static class Mapping { private final WebSocketHandler webSocketHandler; diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketMessageBrokerConfigurationSupportTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketMessageBrokerConfigurationSupportTests.java index 0cb1e5f3e27..5bc9f732d24 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketMessageBrokerConfigurationSupportTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebSocketMessageBrokerConfigurationSupportTests.java @@ -74,7 +74,6 @@ public class WebSocketMessageBrokerConfigurationSupportTests { @Test public void handlerMapping() { - SimpleUrlHandlerMapping hm = (SimpleUrlHandlerMapping) this.config.getBean(HandlerMapping.class); assertEquals(1, hm.getOrder()); @@ -85,7 +84,6 @@ public class WebSocketMessageBrokerConfigurationSupportTests { @Test public void clientInboundChannelSendMessage() throws Exception { - TestChannel channel = this.config.getBean("clientInboundChannel", TestChannel.class); SubProtocolWebSocketHandler webSocketHandler = this.config.getBean(SubProtocolWebSocketHandler.class); From 4dd5c274a022518e66dc499e4e02f97cddc38152 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 15 Jul 2014 13:28:50 -0400 Subject: [PATCH 5/5] Add missing HandshakeInterceptor for STOMP endpoints Issue: SPR-11845 --- .../StompWebSocketEndpointRegistration.java | 6 +++ ...MvcStompWebSocketEndpointRegistration.java | 37 ++++++++++++++----- ...ompWebSocketEndpointRegistrationTests.java | 16 +++++++- 3 files changed, 48 insertions(+), 11 deletions(-) diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java index 14b5402352b..4229e6efb36 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/StompWebSocketEndpointRegistration.java @@ -17,6 +17,7 @@ package org.springframework.web.socket.config.annotation; import org.springframework.web.socket.server.HandshakeHandler; +import org.springframework.web.socket.server.HandshakeInterceptor; /** * A contract for configuring a STOMP over WebSocket endpoint. @@ -36,4 +37,9 @@ public interface StompWebSocketEndpointRegistration { */ StompWebSocketEndpointRegistration setHandshakeHandler(HandshakeHandler handshakeHandler); + /** + * Configure the HandshakeInterceptor's to use. + */ + StompWebSocketEndpointRegistration addInterceptors(HandshakeInterceptor... interceptors); + } \ No newline at end of file diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistration.java b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistration.java index 8b0bc31a429..a9e24920a43 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistration.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistration.java @@ -23,11 +23,14 @@ import org.springframework.util.MultiValueMap; import org.springframework.web.HttpRequestHandler; import org.springframework.web.socket.WebSocketHandler; 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.SockJsService; import org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler; +import java.util.Arrays; + /** * An abstract base class class for configuring STOMP over WebSocket/SockJS endpoints. * @@ -44,6 +47,8 @@ public class WebMvcStompWebSocketEndpointRegistration implements StompWebSocketE private HandshakeHandler handshakeHandler; + private HandshakeInterceptor[] interceptors; + private StompSockJsServiceRegistration registration; @@ -58,9 +63,6 @@ public class WebMvcStompWebSocketEndpointRegistration implements StompWebSocketE this.sockJsTaskScheduler = sockJsTaskScheduler; } - /** - * Provide a custom or pre-configured {@link HandshakeHandler}. - */ @Override public StompWebSocketEndpointRegistration setHandshakeHandler(HandshakeHandler handshakeHandler) { Assert.notNull(handshakeHandler, "'handshakeHandler' must not be null"); @@ -68,12 +70,22 @@ public class WebMvcStompWebSocketEndpointRegistration implements StompWebSocketE return this; } - /** - * Enable SockJS fallback options. - */ + @Override + public StompWebSocketEndpointRegistration addInterceptors(HandshakeInterceptor... interceptors) { + this.interceptors = interceptors; + return this; + } + + protected HandshakeInterceptor[] getInterceptors() { + return this.interceptors; + } + @Override public SockJsServiceRegistration withSockJS() { this.registration = new StompSockJsServiceRegistration(this.sockJsTaskScheduler); + if (this.interceptors != null) { + this.registration.setInterceptors(this.interceptors); + } if (this.handshakeHandler != null) { WebSocketTransportHandler transportHandler = new WebSocketTransportHandler(this.handshakeHandler); this.registration.setTransportHandlerOverrides(transportHandler); @@ -93,9 +105,16 @@ public class WebMvcStompWebSocketEndpointRegistration implements StompWebSocketE } else { for (String path : this.paths) { - WebSocketHttpRequestHandler handler = (this.handshakeHandler != null) ? - new WebSocketHttpRequestHandler(this.webSocketHandler, this.handshakeHandler) : - new WebSocketHttpRequestHandler(this.webSocketHandler); + WebSocketHttpRequestHandler handler; + if (this.handshakeHandler != null) { + handler = new WebSocketHttpRequestHandler(this.webSocketHandler, this.handshakeHandler); + } + else { + handler = new WebSocketHttpRequestHandler(this.webSocketHandler); + } + if (this.interceptors != null) { + handler.setHandshakeInterceptors(Arrays.asList(this.interceptors)); + } mappings.add(handler, path); } } diff --git a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java index 56a0b9823ba..7cf381b6bb7 100644 --- a/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java +++ b/spring-websocket/src/test/java/org/springframework/web/socket/config/annotation/WebMvcStompWebSocketEndpointRegistrationTests.java @@ -29,7 +29,9 @@ import org.springframework.scheduling.TaskScheduler; import org.springframework.util.MultiValueMap; import org.springframework.web.HttpRequestHandler; import org.springframework.web.socket.messaging.SubProtocolWebSocketHandler; +import org.springframework.web.socket.server.HandshakeInterceptor; import org.springframework.web.socket.server.support.DefaultHandshakeHandler; +import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; import org.springframework.web.socket.server.support.WebSocketHttpRequestHandler; import org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler; import org.springframework.web.socket.sockjs.transport.TransportHandler; @@ -38,6 +40,8 @@ import org.springframework.web.socket.sockjs.transport.handler.DefaultSockJsServ import org.springframework.web.socket.sockjs.transport.handler.WebSocketTransportHandler; import static org.junit.Assert.*; +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; import static org.mockito.Mockito.mock; /** @@ -73,12 +77,15 @@ public class WebMvcStompWebSocketEndpointRegistrationTests { } @Test - public void customHandshakeHandler() { + public void handshakeHandlerAndInterceptors() { WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler); DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler(); + HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor(); + registration.setHandshakeHandler(handshakeHandler); + registration.addInterceptors(interceptor); MultiValueMap mappings = registration.getMappings(); assertEquals(1, mappings.size()); @@ -89,15 +96,19 @@ public class WebMvcStompWebSocketEndpointRegistrationTests { WebSocketHttpRequestHandler requestHandler = (WebSocketHttpRequestHandler) entry.getKey(); assertNotNull(requestHandler.getWebSocketHandler()); assertSame(handshakeHandler, requestHandler.getHandshakeHandler()); + assertEquals(Arrays.asList(interceptor), requestHandler.getHandshakeInterceptors()); } @Test - public void customHandshakeHandlerPassedToSockJsService() { + public void handshakeHandlerAndInterceptorsWithSockJsService() { WebMvcStompWebSocketEndpointRegistration registration = new WebMvcStompWebSocketEndpointRegistration(new String[] {"/foo"}, this.handler, this.scheduler); DefaultHandshakeHandler handshakeHandler = new DefaultHandshakeHandler(); + HttpSessionHandshakeInterceptor interceptor = new HttpSessionHandshakeInterceptor(); + registration.setHandshakeHandler(handshakeHandler); + registration.addInterceptors(interceptor); registration.withSockJS(); MultiValueMap mappings = registration.getMappings(); @@ -115,6 +126,7 @@ public class WebMvcStompWebSocketEndpointRegistrationTests { Map handlers = sockJsService.getTransportHandlers(); WebSocketTransportHandler transportHandler = (WebSocketTransportHandler) handlers.get(TransportType.WEBSOCKET); assertSame(handshakeHandler, transportHandler.getHandshakeHandler()); + assertEquals(Arrays.asList(interceptor), sockJsService.getHandshakeInterceptors()); } }