From 30ea1a34758d40c052ddd2e33872075b03217cfc Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Mon, 31 Mar 2014 09:05:28 +0200 Subject: [PATCH] Fix issue with default executor for message channels This change ensures correct default settings for message channel's created through the websocket message-broker XML namespace even when the channels are customized for other reasons -- e.g. to add a channel interceptor. Issue: SPR-11623 --- .../MessageBrokerBeanDefinitionParser.java | 34 ++++++++++++------- ...essageBrokerBeanDefinitionParserTests.java | 11 ++++++ ...broker-customchannels-default-executor.xml | 30 ++++++++++++++++ 3 files changed, 63 insertions(+), 12 deletions(-) create mode 100644 spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml 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 4bfc632782d..c79df74ef94 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 @@ -176,10 +176,15 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { ParserContext parserCxt, Object source) { RootBeanDefinition executorDef = null; - - if (channelElement != null) { + if (channelElement == null) { + executorDef = getDefaultExecutorBeanDefinition(channelName); + } + else { Element executor = DomUtils.getChildElementByTagName(channelElement, "executor"); - if (executor != null) { + if (executor == null) { + executorDef = getDefaultExecutorBeanDefinition(channelName); + } + else { executorDef = new RootBeanDefinition(ThreadPoolTaskExecutor.class); String attrValue = executor.getAttribute("core-pool-size"); if (!StringUtils.isEmpty(attrValue)) { @@ -199,22 +204,16 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { } } } - else if (!channelName.equals("brokerChannel")) { - executorDef = new RootBeanDefinition(ThreadPoolTaskExecutor.class); - executorDef.getPropertyValues().add("corePoolSize", Runtime.getRuntime().availableProcessors() * 2); - executorDef.getPropertyValues().add("maxPoolSize", Integer.MAX_VALUE); - executorDef.getPropertyValues().add("queueCapacity", Integer.MAX_VALUE); - } - ConstructorArgumentValues values = new ConstructorArgumentValues(); + ConstructorArgumentValues argValues = new ConstructorArgumentValues(); if (executorDef != null) { executorDef.getPropertyValues().add("threadNamePrefix", channelName + "-"); String executorName = channelName + "Executor"; registerBeanDefByName(executorName, executorDef, parserCxt, source); - values.addIndexedArgumentValue(0, new RuntimeBeanReference(executorName)); + argValues.addIndexedArgumentValue(0, new RuntimeBeanReference(executorName)); } - RootBeanDefinition channelDef = new RootBeanDefinition(ExecutorSubscribableChannel.class, values, null); + RootBeanDefinition channelDef = new RootBeanDefinition(ExecutorSubscribableChannel.class, argValues, null); if (channelElement != null) { Element interceptorsElement = DomUtils.getChildElementByTagName(channelElement, "interceptors"); @@ -226,6 +225,17 @@ class MessageBrokerBeanDefinitionParser implements BeanDefinitionParser { return new RuntimeBeanReference(channelName); } + private RootBeanDefinition getDefaultExecutorBeanDefinition(String channelName) { + if (channelName.equals("brokerChannel")) { + return null; + } + RootBeanDefinition executorDef = new RootBeanDefinition(ThreadPoolTaskExecutor.class); + executorDef.getPropertyValues().add("corePoolSize", Runtime.getRuntime().availableProcessors() * 2); + executorDef.getPropertyValues().add("maxPoolSize", Integer.MAX_VALUE); + executorDef.getPropertyValues().add("queueCapacity", Integer.MAX_VALUE); + return executorDef; + } + private RuntimeBeanReference registerSubProtocolWebSocketHandler(Element element, RuntimeBeanReference clientInChannel, RuntimeBeanReference clientOutChannel, RuntimeBeanReference userSessionRegistry, ParserContext parserCxt, Object source) { 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 632fe341014..1c9b295d971 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 @@ -293,6 +293,17 @@ public class MessageBrokerBeanDefinitionParserTests { testExecutor("brokerChannel", 102, 202, 602); } + // SPR-11623 + + @Test + public void customChannelsWithDefaultExecutor() { + loadBeanDefinitions("websocket-config-broker-customchannels-default-executor.xml"); + + testExecutor("clientInboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60); + testExecutor("clientOutboundChannel", Runtime.getRuntime().availableProcessors() * 2, Integer.MAX_VALUE, 60); + assertFalse(this.appContext.containsBean("brokerChannelExecutor")); + } + @Test public void messageConverters() { loadBeanDefinitions("websocket-config-broker-converters.xml"); 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 new file mode 100644 index 00000000000..4c8de3eeded --- /dev/null +++ b/spring-websocket/src/test/resources/org/springframework/web/socket/config/websocket-config-broker-customchannels-default-executor.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + +