INT-2285 Implement max-subscribers on Channels
Add a subscriber limit on both unicast and publish-subscribe
channels. This permits detection of inadvertent channel wiring
during context initialization.
Also add a mechanism to globally set these defaults.
Two properties are added to ChannelInitializer. If the
'channelInitializer' bean is declared before a channel, and
these properties are set, it will globally override the
default (Integer.MAX_VALUE) for these properties.
For example:
<bean id="channelInitializer" class="org.springframework.integration.config.xml.ChannelInitializer">
<property name="autoCreate" value="true" />
<property name="defaultMaxUnicastSubscribers" value="1" />
<property name="defaultMaxMulticastSubscribers" value="2" />
</bean>
will make the default max-subscribers 1 and 2 for <channel/> and
<publish-subscribe/> channels respectively.
Also applies to module channels (jms, amqp, redis).
This commit is contained in:
committed by
Gunnar Hillert
parent
a90a7e8e0b
commit
2ecb14de2a
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<int:channel id="defaultChannel" />
|
||||
|
||||
<int:channel id="defaultChannel2">
|
||||
<int:dispatcher />
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="explicitChannel">
|
||||
<int:dispatcher max-subscribers="123" />
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="executorChannel">
|
||||
<int:dispatcher task-executor="taskExecutor" />
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="explicitExecutorChannel">
|
||||
<int:dispatcher task-executor="taskExecutor" max-subscribers="234" />
|
||||
</int:channel>
|
||||
|
||||
<task:executor id="taskExecutor"/>
|
||||
|
||||
<int:publish-subscribe-channel id="pubSubDefaultChannel" />
|
||||
|
||||
<int:publish-subscribe-channel id="pubSubExplicitChannel" max-subscribers="2 "/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class DispatcherMaxSubscribersDefaultConfigurationTests extends DispatcherMaxSubscribersTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
doTestUnicast(Integer.MAX_VALUE, Integer.MAX_VALUE, 123, Integer.MAX_VALUE, 234);
|
||||
doTestMulticast(Integer.MAX_VALUE, 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<!-- Explicit channel initializer, but no specification of the default max subscribers properties -->
|
||||
|
||||
<bean id="channelInitializer" class="org.springframework.integration.config.xml.ChannelInitializer">
|
||||
<property name="autoCreate" value="true" />
|
||||
</bean>
|
||||
|
||||
<import resource="DispatcherMaxSubscribersDefaultConfigurationTests-context.xml" />
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class DispatcherMaxSubscribersDontOverrideDefaultTests extends DispatcherMaxSubscribersTests {
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
doTestUnicast(Integer.MAX_VALUE, Integer.MAX_VALUE, 123, Integer.MAX_VALUE, 234);
|
||||
doTestMulticast(Integer.MAX_VALUE, 2);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.2.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
|
||||
|
||||
<bean id="channelInitializer" class="org.springframework.integration.config.xml.ChannelInitializer">
|
||||
<property name="autoCreate" value="true" />
|
||||
<property name="defaultMaxUnicastSubscribers" value="456" />
|
||||
<property name="defaultMaxBroadcastSubscribers" value="789" />
|
||||
</bean>
|
||||
|
||||
<import resource="DispatcherMaxSubscribersDefaultConfigurationTests-context.xml" />
|
||||
|
||||
<int:channel id="oneSub">
|
||||
<int:dispatcher max-subscribers="1" />
|
||||
</int:channel>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.Message;
|
||||
import org.springframework.integration.MessagingException;
|
||||
import org.springframework.integration.core.MessageHandler;
|
||||
import org.springframework.integration.core.SubscribableChannel;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class DispatcherMaxSubscribersOverrideDefaultTests extends DispatcherMaxSubscribersTests {
|
||||
|
||||
@Autowired
|
||||
private SubscribableChannel oneSub;
|
||||
|
||||
@Test
|
||||
public void test() {
|
||||
this.doTestUnicast(456, 456, 123, 456, 234);
|
||||
doTestMulticast(789, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExceed() {
|
||||
oneSub.subscribe(new MessageHandler() {
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
}
|
||||
});
|
||||
try {
|
||||
oneSub.subscribe(new MessageHandler() {
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
}
|
||||
});
|
||||
fail("Expected Exception");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
assertEquals("Maximum subscribers exceeded", e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2012 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.integration.config.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.MessageChannel;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
|
||||
/**
|
||||
* @author Gary Russell
|
||||
* @since 2.2
|
||||
*
|
||||
*/
|
||||
public abstract class DispatcherMaxSubscribersTests {
|
||||
|
||||
@Autowired
|
||||
private MessageChannel defaultChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel defaultChannel2;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel explicitChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel executorChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel explicitExecutorChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel pubSubDefaultChannel;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel pubSubExplicitChannel;
|
||||
|
||||
public DispatcherMaxSubscribersTests() {
|
||||
super();
|
||||
}
|
||||
|
||||
protected void doTestUnicast(int val1, int val2, int val3, int val4, int val5) {
|
||||
Integer defaultMax = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(defaultChannel, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val1, defaultMax.intValue());
|
||||
Integer defaultMax2 = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(defaultChannel2, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val2, defaultMax2.intValue());
|
||||
Integer explicitMax = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(explicitChannel, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val3, explicitMax.intValue());
|
||||
Integer execMax = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(executorChannel, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val4, execMax.intValue());
|
||||
Integer explicitExecMax = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(explicitExecutorChannel, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val5, explicitExecMax.intValue());
|
||||
}
|
||||
|
||||
protected void doTestMulticast(int val1, int val2) {
|
||||
Integer defaultMax = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(pubSubDefaultChannel, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val1, defaultMax.intValue());
|
||||
Integer explicitMax = TestUtils.getPropertyValue(
|
||||
TestUtils.getPropertyValue(pubSubExplicitChannel, "dispatcher"), "maxSubscribers", Integer.class);
|
||||
assertEquals(val2, explicitMax.intValue());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user