renamed modules org.springframework.integration.* -> spring-integration-*
@Ignore'd SimpleTcpNetOutboundGatewayTests#testOutboundClose() to avoid failure; this failure is correlated to the module name change, but hard to understand how it would be caused by it
This commit is contained in:
@@ -0,0 +1,231 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.channel.MessageChannelTemplate;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class AggregatingMessageGroupProcessorHeaderTests {
|
||||
|
||||
private final QueueChannel outputChannel = new QueueChannel(1);
|
||||
|
||||
private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
|
||||
|
||||
private final DefaultAggregatingMessageGroupProcessor defaultProcessor = new DefaultAggregatingMessageGroupProcessor();
|
||||
|
||||
private final MethodInvokingMessageGroupProcessor methodInvokingProcessor =
|
||||
new MethodInvokingMessageGroupProcessor(new TestAggregatorBean(), "aggregate");
|
||||
|
||||
@Test
|
||||
public void singleMessageUsingDefaultProcessor() {
|
||||
this.singleMessage(defaultProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleMessageUsingMethodInvokingProcessor() {
|
||||
this.singleMessage(methodInvokingProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoMessagesWithoutConflictsUsingDefaultProcessor() {
|
||||
this.twoMessagesWithoutConflicts(defaultProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoMessagesWithoutConflictsUsingMethodInvokingProcessor() {
|
||||
this.twoMessagesWithoutConflicts(methodInvokingProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoMessagesWithConflictsUsingDefaultProcessor() {
|
||||
this.twoMessagesWithConflicts(defaultProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoMessagesWithConflictsUsingMethodInvokingProcessor() {
|
||||
this.twoMessagesWithConflicts(methodInvokingProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingValuesDoNotConflictUsingDefaultProcessor() {
|
||||
this.missingValuesDoNotConflict(defaultProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingValuesDoNotConflictUsingMethodInvokingProcessor() {
|
||||
this.missingValuesDoNotConflict(methodInvokingProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleValuesConflictUsingDefaultProcessor() {
|
||||
this.multipleValuesConflict(defaultProcessor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleValuesConflictUsingMethodInvokingProcessor() {
|
||||
this.multipleValuesConflict(methodInvokingProcessor);
|
||||
}
|
||||
|
||||
|
||||
private void singleMessage(MessageGroupProcessor processor) {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
headers.put("k1", "value1");
|
||||
headers.put("k2", new Integer(2));
|
||||
Message<?> message = correlatedMessage(1, 1, 1, headers);
|
||||
List<Message<?>> messages = Collections.<Message<?>>singletonList(message);
|
||||
MessageGroup group = new SimpleMessageGroup(messages, 1);
|
||||
processor.processAndSend(group, channelTemplate, outputChannel);
|
||||
Message<?> result = outputChannel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("value1", result.getHeaders().get("k1"));
|
||||
assertEquals(2, result.getHeaders().get("k2"));
|
||||
}
|
||||
|
||||
private void twoMessagesWithoutConflicts(MessageGroupProcessor processor) {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
headers.put("k1", "value1");
|
||||
headers.put("k2", new Integer(2));
|
||||
Message<?> message1 = correlatedMessage(1, 2, 1, headers);
|
||||
Message<?> message2 = correlatedMessage(1, 2, 2, headers);
|
||||
List<Message<?>> messages = Arrays.<Message<?>>asList(message1, message2);
|
||||
MessageGroup group = new SimpleMessageGroup(messages, 1);
|
||||
processor.processAndSend(group, channelTemplate, outputChannel);
|
||||
Message<?> result = outputChannel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("value1", result.getHeaders().get("k1"));
|
||||
assertEquals(2, result.getHeaders().get("k2"));
|
||||
}
|
||||
|
||||
private void twoMessagesWithConflicts(MessageGroupProcessor processor) {
|
||||
Map<String, Object> headers1 = new HashMap<String, Object>();
|
||||
headers1.put("k1", "foo");
|
||||
headers1.put("k2", new Integer(123));
|
||||
Message<?> message1 = correlatedMessage(1, 2, 1, headers1);
|
||||
Map<String, Object> headers2 = new HashMap<String, Object>();
|
||||
headers2.put("k1", "bar");
|
||||
headers2.put("k2", new Integer(123));
|
||||
Message<?> message2 = correlatedMessage(1, 2, 2, headers2);
|
||||
List<Message<?>> messages = Arrays.<Message<?>>asList(message1, message2);
|
||||
MessageGroup group = new SimpleMessageGroup(messages, 1);
|
||||
processor.processAndSend(group, channelTemplate, outputChannel);
|
||||
Message<?> result = outputChannel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertNull(result.getHeaders().get("k1"));
|
||||
assertEquals(123, result.getHeaders().get("k2"));
|
||||
}
|
||||
|
||||
private void missingValuesDoNotConflict(MessageGroupProcessor processor) {
|
||||
Map<String, Object> headers1 = new HashMap<String, Object>();
|
||||
headers1.put("only1", "value1");
|
||||
headers1.put("commonTo1And2", "foo");
|
||||
headers1.put("commonToAll", new Integer(123));
|
||||
headers1.put("conflictBetween1And2", "valueFor1");
|
||||
Message<?> message1 = correlatedMessage(1, 3, 1, headers1);
|
||||
Map<String, Object> headers2 = new HashMap<String, Object>();
|
||||
headers2.put("only2", "value2");
|
||||
headers2.put("commonTo1And2", "foo");
|
||||
headers2.put("commonTo2And3", "bar");
|
||||
headers2.put("conflictBetween1And2", "valueFor2");
|
||||
headers2.put("conflictBetween2And3", "valueFor2");
|
||||
headers2.put("commonToAll", new Integer(123));
|
||||
Message<?> message2 = correlatedMessage(1, 3, 2, headers2);
|
||||
Map<String, Object> headers3 = new HashMap<String, Object>();
|
||||
headers3.put("only3", "value3");
|
||||
headers3.put("commonTo2And3", "bar");
|
||||
headers3.put("commonToAll", new Integer(123));
|
||||
headers3.put("conflictBetween2And3", "valueFor3");
|
||||
Message<?> message3 = correlatedMessage(1, 3, 3, headers3);
|
||||
List<Message<?>> messages = Arrays.<Message<?>>asList(message1, message2, message3);
|
||||
MessageGroup group = new SimpleMessageGroup(messages, 1);
|
||||
processor.processAndSend(group, channelTemplate, outputChannel);
|
||||
Message<?> result = outputChannel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("value1", result.getHeaders().get("only1"));
|
||||
assertEquals("value2", result.getHeaders().get("only2"));
|
||||
assertEquals("value3", result.getHeaders().get("only3"));
|
||||
assertEquals("foo", result.getHeaders().get("commonTo1And2"));
|
||||
assertEquals("bar", result.getHeaders().get("commonTo2And3"));
|
||||
assertEquals(123, result.getHeaders().get("commonToAll"));
|
||||
assertNull(result.getHeaders().get("conflictBetween1And2"));
|
||||
assertNull(result.getHeaders().get("conflictBetween2And3"));
|
||||
}
|
||||
|
||||
private void multipleValuesConflict(MessageGroupProcessor processor) {
|
||||
Map<String, Object> headers1 = new HashMap<String, Object>();
|
||||
headers1.put("common", "valueForAll");
|
||||
headers1.put("conflict", "valueFor1");
|
||||
Message<?> message1 = correlatedMessage(1, 3, 1, headers1);
|
||||
Map<String, Object> headers2 = new HashMap<String, Object>();
|
||||
headers2.put("common", "valueForAll");
|
||||
headers2.put("conflict", "valueFor2");
|
||||
Message<?> message2 = correlatedMessage(1, 3, 2, headers2);
|
||||
Map<String, Object> headers3 = new HashMap<String, Object>();
|
||||
headers3.put("conflict", "valueFor3");
|
||||
headers3.put("common", "valueForAll");
|
||||
Message<?> message3 = correlatedMessage(1, 3, 3, headers3);
|
||||
List<Message<?>> messages = Arrays.<Message<?>>asList(message1, message2, message3);
|
||||
MessageGroup group = new SimpleMessageGroup(messages, 1);
|
||||
processor.processAndSend(group, channelTemplate, outputChannel);
|
||||
Message<?> result = outputChannel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("valueForAll", result.getHeaders().get("common"));
|
||||
assertNull(result.getHeaders().get("conflict"));
|
||||
}
|
||||
|
||||
private static Message<?> correlatedMessage(Object correlationId, Integer sequenceSize,
|
||||
Integer sequenceNumber, Map<String, Object> headers) {
|
||||
return MessageBuilder.withPayload("test")
|
||||
.setCorrelationId(correlationId)
|
||||
.setSequenceNumber(sequenceNumber)
|
||||
.setSequenceSize(sequenceSize)
|
||||
.copyHeadersIfAbsent(headers)
|
||||
.build();
|
||||
}
|
||||
|
||||
|
||||
private static class TestAggregatorBean {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public Object aggregate(List<String> payloads) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (String s : payloads) {
|
||||
sb.append(s);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input"/>
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<splitter id="splitter" input-channel="input" output-channel="aggregatorChannel"/>
|
||||
|
||||
<aggregator id="aggregator" input-channel="aggregatorChannel"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class AggregatorReplyChannelTests {
|
||||
|
||||
@Autowired
|
||||
private volatile MessageChannel input;
|
||||
|
||||
@Autowired
|
||||
private volatile PollableChannel output;
|
||||
|
||||
private final List<String> list = new ArrayList<String>();
|
||||
|
||||
|
||||
@Before
|
||||
public void setupList() {
|
||||
list.add("foo");
|
||||
list.add("bar");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void replyChannelHeader() {
|
||||
this.verifyReply(MessageBuilder.withPayload(list).setReplyChannel(output).build());
|
||||
}
|
||||
|
||||
@Test // INT-1095
|
||||
public void replyChannelNameHeader() {
|
||||
this.verifyReply(MessageBuilder.withPayload(list).setReplyChannelName("output").build());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void verifyReply(Message<?> message) {
|
||||
assertNull(output.receive(0));
|
||||
input.send(message);
|
||||
Message<?> result = output.receive(0);
|
||||
assertNotNull(result);
|
||||
assertTrue(result.getPayload() instanceof List);
|
||||
List<?> resultList = (List<?>) result.getPayload();
|
||||
assertEquals(2, resultList.size());
|
||||
assertTrue(resultList.contains("foo"));
|
||||
assertTrue(resultList.contains("bar"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aggregator;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.channel.MessageChannelTemplate;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.core.MessageHeaders;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public class AggregatorTests {
|
||||
|
||||
private CorrelatingMessageHandler aggregator;
|
||||
private SimpleMessageStore store = new SimpleMessageStore(50);
|
||||
|
||||
@Before
|
||||
public void configureAggregator() {
|
||||
this.aggregator = new CorrelatingMessageHandler(new MultiplyingProcessor(), store);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompleteGroupWithinTimeout() throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
this.aggregator.handleMessage(message1);
|
||||
this.aggregator.handleMessage(message2);
|
||||
this.aggregator.handleMessage(message3);
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(2000);
|
||||
assertNotNull(reply);
|
||||
assertEquals(reply.getPayload(), 105);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldNotSendPartialResultOnTimeoutByDefault() throws InterruptedException {
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message = createMessage(3, "ABC", 2, 1, replyChannel, null);
|
||||
this.aggregator.handleMessage(message);
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNull("No message should have been sent normally", reply);
|
||||
Message<?> discardedMessage = discardChannel.receive(1000);
|
||||
assertNotNull("A message should have been discarded", discardedMessage);
|
||||
assertEquals(message, discardedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldSendPartialResultOnTimeoutTrue() throws InterruptedException {
|
||||
this.aggregator.setSendPartialResultOnExpiry(true);
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
this.aggregator.handleMessage(message1);
|
||||
this.aggregator.handleMessage(message2);
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
assertNotNull("A reply message should have been received", reply);
|
||||
assertEquals(15, reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleGroupsSimultaneously() throws InterruptedException {
|
||||
QueueChannel replyChannel1 = new QueueChannel();
|
||||
QueueChannel replyChannel2 = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel1, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel1, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel1, null);
|
||||
Message<?> message4 = createMessage(11, "XYZ", 3, 1, replyChannel2, null);
|
||||
Message<?> message5 = createMessage(13, "XYZ", 3, 2, replyChannel2, null);
|
||||
Message<?> message6 = createMessage(17, "XYZ", 3, 3, replyChannel2, null);
|
||||
aggregator.handleMessage(message1);
|
||||
aggregator.handleMessage(message5);
|
||||
aggregator.handleMessage(message3);
|
||||
aggregator.handleMessage(message6);
|
||||
aggregator.handleMessage(message4);
|
||||
aggregator.handleMessage(message2);
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply1 = (Message<Integer>) replyChannel1.receive(500);
|
||||
assertNotNull(reply1);
|
||||
assertThat(reply1.getPayload(), is(105));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply2 = (Message<Integer>) replyChannel2.receive(500);
|
||||
assertNotNull(reply2);
|
||||
assertThat(reply2.getPayload(), is(2431));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// dropped backwards compatibility for setting capacity limit (it's always Integer.MAX_VALUE)
|
||||
public void testTrackedCorrelationIdsCapacityAtLimit() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
// this.aggregator.setTrackedCorrelationIdCapacity(3);
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 2, 1, 1, replyChannel, null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 3, 1, 1, replyChannel, null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
// next message with same correllation ID is discarded
|
||||
this.aggregator.handleMessage(createMessage(2, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(2, discardChannel.receive(100).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// dropped backwards compatibility for setting capacity limit (it's always Integer.MAX_VALUE)
|
||||
public void testTrackedCorrelationIdsCapacityPassesLimit() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
// this.aggregator.setTrackedCorrelationIdCapacity(3);
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(2, 2, 1, 1, replyChannel, null));
|
||||
assertEquals(2, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 3, 1, 1, replyChannel, null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 4, 1, 1, replyChannel, null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(5, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(5, replyChannel.receive(100).getPayload());
|
||||
assertNull(discardChannel.receive(0));
|
||||
}
|
||||
|
||||
@Test(expected = MessageHandlingException.class)
|
||||
public void testExceptionThrownIfNoCorrelationId() throws InterruptedException {
|
||||
Message<?> message = createMessage(3, null, 2, 1, new QueueChannel(), null);
|
||||
this.aggregator.handleMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdditionalMessageAfterCompletion() throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
Message<?> message4 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(4);
|
||||
this.aggregator.handleMessage(message1);
|
||||
this.aggregator.handleMessage(message2);
|
||||
this.aggregator.handleMessage(message3);
|
||||
this.aggregator.handleMessage(message4);
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
// small wait to make sure the fourth message is received
|
||||
Thread.sleep(10);
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
assertNotNull("A message should be aggregated", reply);
|
||||
assertThat(((Integer) reply.getPayload()), is(105));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectDuplicatedSequenceNumbers() throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
Message<?> message4 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(4);
|
||||
this.aggregator.handleMessage(message1);
|
||||
this.aggregator.handleMessage(message3);
|
||||
// duplicated sequence number, either message3 or message4 should be rejected
|
||||
this.aggregator.handleMessage(message4);
|
||||
this.aggregator.handleMessage(message2);
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
assertNotNull("A message should be aggregated", reply);
|
||||
assertThat(((Integer) reply.getPayload()), is(105));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullReturningAggregator() throws InterruptedException {
|
||||
this.aggregator = new CorrelatingMessageHandler(new NullReturningMessageProcessor(), new SimpleMessageStore(50));
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
this.aggregator.handleMessage(message1);
|
||||
this.aggregator.handleMessage(message2);
|
||||
this.aggregator.handleMessage(message3);
|
||||
Message<?> reply = replyChannel.receive(500);
|
||||
assertNull(reply);
|
||||
}
|
||||
|
||||
private static Message<?> createMessage(Object payload, Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel replyChannel, String predefinedId) {
|
||||
MessageBuilder<Object> builder = MessageBuilder.withPayload(payload).setCorrelationId(correlationId)
|
||||
.setSequenceSize(sequenceSize).setSequenceNumber(sequenceNumber).setReplyChannel(replyChannel);
|
||||
if (predefinedId != null) {
|
||||
builder.setHeader(MessageHeaders.ID, predefinedId);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private class MultiplyingProcessor implements MessageGroupProcessor {
|
||||
public void processAndSend(MessageGroup group, MessageChannelTemplate channelTemplate,
|
||||
MessageChannel outputChannel) {
|
||||
Integer product = 1;
|
||||
for (Message<?> message : group.getUnmarked()) {
|
||||
product *= (Integer) message.getPayload();
|
||||
}
|
||||
channelTemplate.send(MessageBuilder.withPayload(product).build(), outputChannel);
|
||||
}
|
||||
}
|
||||
|
||||
private class NullReturningMessageProcessor implements MessageGroupProcessor {
|
||||
public void processAndSend(MessageGroup group, MessageChannelTemplate channelTemplate,
|
||||
MessageChannel outputChannel) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,366 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aggregator;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.integration.channel.MessageChannelTemplate;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.core.MessageHeaders;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHandler;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public class ConcurrentAggregatorTests {
|
||||
|
||||
private TaskExecutor taskExecutor;
|
||||
|
||||
private CorrelatingMessageHandler aggregator;
|
||||
|
||||
private MessageGroupStore store = new SimpleMessageStore();
|
||||
|
||||
@Before
|
||||
public void configureAggregator() {
|
||||
this.taskExecutor = new SimpleAsyncTaskExecutor();
|
||||
this.aggregator = new CorrelatingMessageHandler(new MultiplyingProcessor(), store);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompleteGroupWithinTimeout() throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message1, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message2, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message3, latch));
|
||||
latch.await(10000, TimeUnit.MILLISECONDS);
|
||||
assertThat(latch.getCount(), is(0l));
|
||||
Message<?> reply = replyChannel.receive(2000);
|
||||
assertNotNull(reply);
|
||||
assertEquals(reply.getPayload(), 105);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// dropped backwards compatibility for duplicate ID's
|
||||
public void testCompleteGroupWithinTimeoutWithSameId()
|
||||
throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel,
|
||||
"ID#1");
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel,
|
||||
"ID#1");
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel,
|
||||
"ID#1");
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
// for testing the duplication scenario, the messages must be processed
|
||||
// synchronously
|
||||
new AggregatorTestTask(this.aggregator, message1, latch).run();
|
||||
new AggregatorTestTask(this.aggregator, message2, latch).run();
|
||||
new AggregatorTestTask(this.aggregator, message3, latch).run();
|
||||
Message<?> reply = replyChannel.receive(500);
|
||||
assertNotNull(reply);
|
||||
assertEquals("123456789", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldNotSendPartialResultOnTimeoutByDefault()
|
||||
throws InterruptedException {
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message = createMessage(3, "ABC", 2, 1, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AggregatorTestTask task = new AggregatorTestTask(this.aggregator,
|
||||
message, latch);
|
||||
this.taskExecutor.execute(task);
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
assertEquals("Task should have completed within timeout", 0, latch
|
||||
.getCount());
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNull("No message should have been sent normally", reply);
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> discardedMessage = discardChannel.receive(100);
|
||||
assertNotNull("A message should have been discarded", discardedMessage);
|
||||
assertEquals(message, discardedMessage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldSendPartialResultOnTimeoutTrue()
|
||||
throws InterruptedException {
|
||||
this.aggregator.setSendPartialResultOnExpiry(true);
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(2);
|
||||
AggregatorTestTask task1 = new AggregatorTestTask(this.aggregator,
|
||||
message1, latch);
|
||||
AggregatorTestTask task2 = new AggregatorTestTask(this.aggregator,
|
||||
message2, latch);
|
||||
this.taskExecutor.execute(task1);
|
||||
this.taskExecutor.execute(task2);
|
||||
latch.await(300, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handlers should have been invoked within time limit", 0,
|
||||
latch.getCount());
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull("A reply message should have been received", reply);
|
||||
assertEquals(15, reply.getPayload());
|
||||
assertNull(task1.getException());
|
||||
assertNull(task2.getException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleGroupsSimultaneously() throws InterruptedException {
|
||||
QueueChannel replyChannel1 = new QueueChannel();
|
||||
QueueChannel replyChannel2 = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel1, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel1, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel1, null);
|
||||
Message<?> message4 = createMessage(11, "XYZ", 3, 1, replyChannel2,
|
||||
null);
|
||||
Message<?> message5 = createMessage(13, "XYZ", 3, 2, replyChannel2,
|
||||
null);
|
||||
Message<?> message6 = createMessage(17, "XYZ", 3, 3, replyChannel2,
|
||||
null);
|
||||
CountDownLatch latch = new CountDownLatch(6);
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message1, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message6, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message2, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message5, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message3, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message4, latch));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply1 = (Message<Integer>) replyChannel1.receive(500);
|
||||
assertNotNull(reply1);
|
||||
assertThat(reply1.getPayload(), is(105));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply2 = (Message<Integer>) replyChannel2.receive(500);
|
||||
assertNotNull(reply2);
|
||||
assertThat(reply2.getPayload(), is(2431));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// dropped backwards compatibility for setting capacity limit (it's always
|
||||
// Integer.MAX_VALUE)
|
||||
public void testTrackedCorrelationIdsCapacityAtLimit() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
// this.aggregator.setTrackedCorrelationIdCapacity(3);
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 2, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 3, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
// next message with same correlation ID is discarded
|
||||
this.aggregator.handleMessage(createMessage(2, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(2, discardChannel.receive(100).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
// dropped backwards compatibility for setting capacity limit (it's always
|
||||
// Integer.MAX_VALUE)
|
||||
public void testTrackedCorrelationIdsCapacityPassesLimit() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
// this.aggregator.setTrackedCorrelationIdCapacity(3);
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(2, 2, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(2, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 3, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 4, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(5, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(5, replyChannel.receive(100).getPayload());
|
||||
assertNull(discardChannel.receive(0));
|
||||
}
|
||||
|
||||
@Test(expected = MessageHandlingException.class)
|
||||
public void testExceptionThrownIfNoCorrelationId()
|
||||
throws InterruptedException {
|
||||
Message<?> message = createMessage(3, null, 2, 1, new QueueChannel(),
|
||||
null);
|
||||
this.aggregator.handleMessage(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdditionalMessageAfterCompletion()
|
||||
throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
Message<?> message4 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(4);
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message1, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message2, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message3, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message4, latch));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull("A message should be aggregated", reply);
|
||||
assertThat(((Integer) reply.getPayload()), is(105));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullReturningAggregator() throws InterruptedException {
|
||||
this.aggregator = new CorrelatingMessageHandler(new NullReturningMessageProcessor(), new SimpleMessageStore(
|
||||
50));
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage(3, "ABC", 3, 1, replyChannel, null);
|
||||
Message<?> message2 = createMessage(5, "ABC", 3, 2, replyChannel, null);
|
||||
Message<?> message3 = createMessage(7, "ABC", 3, 3, replyChannel, null);
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
AggregatorTestTask task1 = new AggregatorTestTask(aggregator, message1,
|
||||
latch);
|
||||
this.taskExecutor.execute(task1);
|
||||
AggregatorTestTask task2 = new AggregatorTestTask(aggregator, message2,
|
||||
latch);
|
||||
this.taskExecutor.execute(task2);
|
||||
AggregatorTestTask task3 = new AggregatorTestTask(aggregator, message3,
|
||||
latch);
|
||||
this.taskExecutor.execute(task3);
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
assertNull(task1.getException());
|
||||
assertNull(task2.getException());
|
||||
assertNull(task3.getException());
|
||||
Message<?> reply = replyChannel.receive(500);
|
||||
assertNull(reply);
|
||||
}
|
||||
|
||||
private static Message<?> createMessage(Object payload,
|
||||
Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel replyChannel, String predefinedId) {
|
||||
MessageBuilder<Object> builder = MessageBuilder.withPayload(payload)
|
||||
.setCorrelationId(correlationId).setSequenceSize(sequenceSize)
|
||||
.setSequenceNumber(sequenceNumber)
|
||||
.setReplyChannel(replyChannel);
|
||||
if (predefinedId != null) {
|
||||
builder.setHeader(MessageHeaders.ID, predefinedId);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private static class AggregatorTestTask implements Runnable {
|
||||
|
||||
private MessageHandler aggregator;
|
||||
|
||||
private Message<?> message;
|
||||
|
||||
private Exception exception;
|
||||
|
||||
private CountDownLatch latch;
|
||||
|
||||
AggregatorTestTask(MessageHandler aggregator, Message<?> message,
|
||||
CountDownLatch latch) {
|
||||
this.aggregator = aggregator;
|
||||
this.message = message;
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
public Exception getException() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
this.aggregator.handleMessage(message);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
this.exception = e;
|
||||
} finally {
|
||||
this.latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MultiplyingProcessor implements MessageGroupProcessor {
|
||||
public void processAndSend(MessageGroup group,
|
||||
MessageChannelTemplate channelTemplate,
|
||||
MessageChannel outputChannel) {
|
||||
Integer product = 1;
|
||||
for (Message<?> message : group.getUnmarked()) {
|
||||
product *= (Integer) message.getPayload();
|
||||
}
|
||||
channelTemplate.send(MessageBuilder.withPayload(product).build(),
|
||||
outputChannel);
|
||||
}
|
||||
}
|
||||
|
||||
private class NullReturningMessageProcessor implements
|
||||
MessageGroupProcessor {
|
||||
public void processAndSend(MessageGroup group,
|
||||
MessageChannelTemplate channelTemplate,
|
||||
MessageChannel outputChannel) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator;
|
||||
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
|
||||
public class CorrelatingMessageHandlerIntegrationTests {
|
||||
|
||||
private MessageGroupStore store = new SimpleMessageStore(100);
|
||||
|
||||
private MessageChannel outputChannel = mock(MessageChannel.class);
|
||||
|
||||
private MessageGroupProcessor processor = new PassThroughMessageGroupProcessor();
|
||||
|
||||
private CorrelatingMessageHandler defaultHandler = new CorrelatingMessageHandler(processor, store);
|
||||
|
||||
@Before
|
||||
public void setupHandler() {
|
||||
defaultHandler.setOutputChannel(outputChannel);
|
||||
defaultHandler.setSendTimeout(-1);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void completesSingleMessage() throws Exception {
|
||||
Message<?> message = correlatedMessage(1, 1, 1);
|
||||
defaultHandler.handleMessage(message);
|
||||
verify(outputChannel).send(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void completesAfterThreshold() throws Exception {
|
||||
defaultHandler.setReleaseStrategy(new MessageCountReleaseStrategy());
|
||||
MessageChannel discardChannel = mock(MessageChannel.class);
|
||||
defaultHandler.setDiscardChannel(discardChannel);
|
||||
Message<?> message1 = correlatedMessage(1, 2, 1);
|
||||
Message<?> message2 = correlatedMessage(1, 2, 2);
|
||||
defaultHandler.handleMessage(message1);
|
||||
verify(outputChannel).send(message1);
|
||||
defaultHandler.handleMessage(message2);
|
||||
verify(outputChannel, never()).send(message2);
|
||||
verify(discardChannel).send(message2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void completesIfNoSequence() throws Exception {
|
||||
defaultHandler.setReleaseStrategy(new MessageCountReleaseStrategy(2));
|
||||
Message<?> message1 = MessageBuilder.withPayload(1).setCorrelationId("foo").build();
|
||||
Message<?> message2 = MessageBuilder.withPayload(2).setCorrelationId("foo").build();
|
||||
Message<?> message3 = MessageBuilder.withPayload(3).setCorrelationId("foo").build();
|
||||
defaultHandler.handleMessage(message1);
|
||||
verify(outputChannel, never()).send(message3);
|
||||
defaultHandler.handleMessage(message2);
|
||||
verify(outputChannel).send(message2);
|
||||
defaultHandler.handleMessage(message3);
|
||||
verify(outputChannel, never()).send(message3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void completesWithoutReleasingIncompleteCorrelations() throws Exception {
|
||||
Message<?> message1 = correlatedMessage(1, 2, 1);
|
||||
Message<?> message2 = correlatedMessage(2, 2, 1);
|
||||
Message<?> message1a = correlatedMessage(1, 2, 2);
|
||||
Message<?> message2a = correlatedMessage(2, 2, 2);
|
||||
defaultHandler.handleMessage(message1);
|
||||
defaultHandler.handleMessage(message2);
|
||||
verify(outputChannel, never()).send(message1);
|
||||
verify(outputChannel, never()).send(message2);
|
||||
defaultHandler.handleMessage(message1a);
|
||||
verify(outputChannel).send(message1);
|
||||
verify(outputChannel).send(message1a);
|
||||
verify(outputChannel, never()).send(message2);
|
||||
verify(outputChannel, never()).send(message2a);
|
||||
defaultHandler.handleMessage(message2a);
|
||||
verify(outputChannel).send(message2);
|
||||
verify(outputChannel).send(message2a);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void completesAfterSequenceComplete() throws Exception {
|
||||
Message<?> message1 = correlatedMessage(1, 2, 1);
|
||||
Message<?> message2 = correlatedMessage(1, 2, 2);
|
||||
defaultHandler.handleMessage(message1);
|
||||
verify(outputChannel, never()).send(message1);
|
||||
defaultHandler.handleMessage(message2);
|
||||
verify(outputChannel).send(message1);
|
||||
verify(outputChannel).send(message2);
|
||||
}
|
||||
|
||||
|
||||
private Message<?> correlatedMessage(Object correlationId, Integer sequenceSize, Integer sequenceNumber) {
|
||||
return MessageBuilder.withPayload("test")
|
||||
.setCorrelationId(correlationId)
|
||||
.setSequenceNumber(sequenceNumber)
|
||||
.setSequenceSize(sequenceSize)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.internal.stubbing.answers.DoesNothing;
|
||||
import org.mockito.internal.stubbing.answers.ThrowsException;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.integration.channel.MessageChannelTemplate;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
/**
|
||||
* @author Iwein Fuld
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class CorrelatingMessageHandlerTests {
|
||||
|
||||
private CorrelatingMessageHandler handler;
|
||||
|
||||
@Mock
|
||||
private CorrelationStrategy correlationStrategy;
|
||||
|
||||
private ReleaseStrategy ReleaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
|
||||
@Mock
|
||||
private MessageGroupProcessor processor;
|
||||
|
||||
@Mock
|
||||
private MessageChannel outputChannel;
|
||||
|
||||
private MessageGroupStore store = new SimpleMessageStore();
|
||||
|
||||
@Before
|
||||
public void initializeSubject() {
|
||||
handler = new CorrelatingMessageHandler(processor, store, correlationStrategy,
|
||||
ReleaseStrategy);
|
||||
handler.setOutputChannel(outputChannel);
|
||||
doAnswer(new DoesNothing()).when(processor).processAndSend(isA(SimpleMessageGroup.class),
|
||||
isA(MessageChannelTemplate.class), eq(outputChannel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bufferCompletesNormally() throws Exception {
|
||||
String correlationKey = "key";
|
||||
Message<?> message1 = testMessage(correlationKey, 1, 2);
|
||||
Message<?> message2 = testMessage(correlationKey, 2, 2);
|
||||
|
||||
when(correlationStrategy.getCorrelationKey(isA(Message.class))).thenReturn(correlationKey);
|
||||
|
||||
handler.handleMessage(message1);
|
||||
verifyLocks(handler, 1);
|
||||
|
||||
handler.handleMessage(message2);
|
||||
verifyLocks(handler, 0); // lock is removed when group is complete
|
||||
|
||||
verify(correlationStrategy).getCorrelationKey(message1);
|
||||
verify(correlationStrategy).getCorrelationKey(message2);
|
||||
verify(processor).processAndSend(isA(SimpleMessageGroup.class), isA(MessageChannelTemplate.class), eq(outputChannel));
|
||||
}
|
||||
|
||||
private void verifyLocks(CorrelatingMessageHandler handler, int lockCount) {
|
||||
assertEquals(lockCount, ((Map<?, ?>) ReflectionTestUtils.getField(handler, "locks")).size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bufferCompletesWithException() throws Exception {
|
||||
|
||||
doAnswer(new ThrowsException(new RuntimeException("Planned test exception"))).when(processor).processAndSend(isA(SimpleMessageGroup.class),
|
||||
isA(MessageChannelTemplate.class), eq(outputChannel));
|
||||
|
||||
String correlationKey = "key";
|
||||
Message<?> message1 = testMessage(correlationKey, 1, 2);
|
||||
Message<?> message2 = testMessage(correlationKey, 2, 2);
|
||||
|
||||
when(correlationStrategy.getCorrelationKey(isA(Message.class))).thenReturn(correlationKey);
|
||||
|
||||
handler.handleMessage(message1);
|
||||
|
||||
try {
|
||||
handler.handleMessage(message2);
|
||||
fail("Expected MessageHandlingException");
|
||||
} catch (MessageHandlingException e) {
|
||||
assertEquals(0, store.getMessageGroup(correlationKey).size());
|
||||
}
|
||||
|
||||
verify(correlationStrategy).getCorrelationKey(message1);
|
||||
verify(correlationStrategy).getCorrelationKey(message2);
|
||||
verify(processor).processAndSend(isA(SimpleMessageGroup.class), isA(MessageChannelTemplate.class), eq(outputChannel));
|
||||
}
|
||||
|
||||
/*
|
||||
* The next test verifies that when pruning happens after the completing message arrived, but before the group was
|
||||
* processed locking prevents forced completion and the group completes normally.
|
||||
*/
|
||||
|
||||
@Test
|
||||
public void shouldNotPruneWhileCompleting() throws Exception {
|
||||
String correlationKey = "key";
|
||||
final Message<?> message1 = testMessage(correlationKey, 1, 2);
|
||||
final Message<?> message2 = testMessage(correlationKey, 2, 2);
|
||||
final List<Message<?>> storedMessages = new ArrayList<Message<?>>();
|
||||
|
||||
final CountDownLatch bothMessagesHandled = new CountDownLatch(2);
|
||||
|
||||
when(correlationStrategy.getCorrelationKey(isA(Message.class))).thenReturn(correlationKey);
|
||||
|
||||
handler.handleMessage(message1);
|
||||
bothMessagesHandled.countDown();
|
||||
storedMessages.add(message1);
|
||||
Executors.newSingleThreadExecutor().submit(new Runnable() {
|
||||
public void run() {
|
||||
handler.handleMessage(message2);
|
||||
storedMessages.add(message2);
|
||||
bothMessagesHandled.countDown();
|
||||
}
|
||||
});
|
||||
|
||||
Thread.sleep(20);
|
||||
assertEquals(0, store.expireMessageGroups(10000));
|
||||
|
||||
bothMessagesHandled.await();
|
||||
|
||||
}
|
||||
|
||||
private Message<?> testMessage(String correlationKey, int sequenceNumber, int sequenceSize) {
|
||||
return MessageBuilder.withPayload("test" + sequenceNumber).setCorrelationId(correlationKey).setSequenceNumber(
|
||||
sequenceNumber).setSequenceSize(sequenceSize).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class HeaderAttributeCorrelationStrategyTests {
|
||||
|
||||
@Test
|
||||
public void testHeaderAttributeCorrelationStrategy() {
|
||||
String testedHeaderValue = "@!arbitraryTestValue!@";
|
||||
String testHeaderName = "header.for.test";
|
||||
Message<?> message = MessageBuilder.withPayload("irrelevantData").setHeader(testHeaderName, testedHeaderValue).build();
|
||||
HeaderAttributeCorrelationStrategy correlationStrategy = new HeaderAttributeCorrelationStrategy(testHeaderName);
|
||||
assertEquals(testedHeaderValue, correlationStrategy.getCorrelationKey(message));
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MessageSequenceComparatorTests {
|
||||
|
||||
@Test
|
||||
public void testLessThan() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
Message<String> message1 = MessageBuilder.withPayload("test1")
|
||||
.setSequenceNumber(1).build();
|
||||
Message<String> message2 = MessageBuilder.withPayload("test2")
|
||||
.setSequenceNumber(2).build();
|
||||
assertEquals(-1, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqual() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
Message<String> message1 = MessageBuilder.withPayload("test1")
|
||||
.setSequenceNumber(3).build();
|
||||
Message<String> message2 = MessageBuilder.withPayload("test2")
|
||||
.setSequenceNumber(3).build();
|
||||
assertEquals(0, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreaterThan() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
Message<String> message1 = MessageBuilder.withPayload("test1")
|
||||
.setSequenceNumber(5).build();
|
||||
Message<String> message2 = MessageBuilder.withPayload("test2")
|
||||
.setSequenceNumber(3).build();
|
||||
assertEquals(1, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualWithDefaultValues() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
assertEquals(0, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
package org.springframework.integration.aggregator;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Matchers.isA;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.integration.annotation.Aggregator;
|
||||
import org.springframework.integration.annotation.Header;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.MessageChannelTemplate;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MethodInvokingMessageGroupProcessorTests {
|
||||
|
||||
@Mock
|
||||
private MessageChannel outputChannel;
|
||||
|
||||
private List<Message<?>> messagesUpForProcessing = new ArrayList<Message<?>>(3);
|
||||
|
||||
@Mock
|
||||
private MessageGroup messageGroupMock;
|
||||
|
||||
@Mock
|
||||
private MessageChannelTemplate channelTemplate;
|
||||
|
||||
@Before
|
||||
public void initializeMessagesUpForProcessing() {
|
||||
messagesUpForProcessing.add(MessageBuilder.withPayload(1).build());
|
||||
messagesUpForProcessing.add(MessageBuilder.withPayload(2).build());
|
||||
messagesUpForProcessing.add(MessageBuilder.withPayload(4).build());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class AnnotatedAggregatorMethod {
|
||||
|
||||
@Aggregator
|
||||
public Integer and(List<Integer> flags) {
|
||||
int result = 0;
|
||||
for (Integer flag : flags) {
|
||||
result = result | flag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String know(List<Integer> flags) {
|
||||
return "I'm not the one ";
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindAnnotatedAggregatorMethod() throws Exception {
|
||||
MessageGroupProcessor processor = new MethodInvokingMessageGroupProcessor(new AnnotatedAggregatorMethod());
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
when(outputChannel.send(isA(Message.class))).thenReturn(true);
|
||||
when(messageGroupMock.getUnmarked()).thenReturn(messagesUpForProcessing);
|
||||
processor.processAndSend(messageGroupMock, channelTemplate, outputChannel);
|
||||
// verify
|
||||
verify(channelTemplate).send(messageCaptor.capture(), eq(outputChannel));
|
||||
assertThat((Integer) messageCaptor.getValue().getPayload(), is(7));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class SimpleAggregator {
|
||||
public Integer and(List<Integer> flags) {
|
||||
int result = 0;
|
||||
for (Integer flag : flags) {
|
||||
result = result | flag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindSimpleAggregatorMethod() throws Exception {
|
||||
MessageGroupProcessor processor = new MethodInvokingMessageGroupProcessor(new SimpleAggregator());
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
when(outputChannel.send(isA(Message.class))).thenReturn(true);
|
||||
when(messageGroupMock.getUnmarked()).thenReturn(messagesUpForProcessing);
|
||||
processor.processAndSend(messageGroupMock, channelTemplate, outputChannel);
|
||||
// verify
|
||||
verify(channelTemplate).send(messageCaptor.capture(), eq(outputChannel));
|
||||
assertThat((Integer) messageCaptor.getValue().getPayload(), is(7));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class UnnanotatedAggregator {
|
||||
public Integer and(List<Integer> flags) {
|
||||
int result = 0;
|
||||
for (Integer flag : flags) {
|
||||
result = result | flag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void voidMethodShouldBeIgnored(List<Integer> flags) {
|
||||
fail("this method should not be invoked");
|
||||
}
|
||||
|
||||
public String methodAcceptingNoCollectionShouldBeIgnored(@Header String irrelevant) {
|
||||
fail("this method should not be invoked");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindFittingMethodAmongMultipleUnannotated() {
|
||||
MessageGroupProcessor processor = new MethodInvokingMessageGroupProcessor(new UnnanotatedAggregator());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
|
||||
when(outputChannel.send(isA(Message.class))).thenReturn(true);
|
||||
when(messageGroupMock.getUnmarked()).thenReturn(messagesUpForProcessing);
|
||||
processor.processAndSend(messageGroupMock, channelTemplate, outputChannel);
|
||||
// verify
|
||||
verify(channelTemplate).send(messageCaptor.capture(), eq(outputChannel));
|
||||
assertThat((Integer) messageCaptor.getValue().getPayload(), is(7));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private class AnnotatedParametersAggregator {
|
||||
public Integer and(List<Integer> flags) {
|
||||
int result = 0;
|
||||
for (Integer flag : flags) {
|
||||
result = result | flag;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public String listHeaderShouldBeIgnored(@Header List<Integer> flags) {
|
||||
fail("this method should not be invoked");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldFindFittingMethodAmongMultipleWithAnnotatedParameters() {
|
||||
MessageGroupProcessor processor = new MethodInvokingMessageGroupProcessor(new AnnotatedParametersAggregator());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
ArgumentCaptor<Message> messageCaptor = ArgumentCaptor.forClass(Message.class);
|
||||
|
||||
when(outputChannel.send(isA(Message.class))).thenReturn(true);
|
||||
when(messageGroupMock.getUnmarked()).thenReturn(messagesUpForProcessing);
|
||||
processor.processAndSend(messageGroupMock, channelTemplate, outputChannel);
|
||||
// verify
|
||||
verify(channelTemplate).send(messageCaptor.capture(), eq(outputChannel));
|
||||
assertThat((Integer) messageCaptor.getValue().getPayload(), is(7));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void singleAnnotation() throws Exception {
|
||||
SingleAnnotationTestBean bean = new SingleAnnotationTestBean();
|
||||
MethodInvokingMessageGroupProcessor aggregator = new MethodInvokingMessageGroupProcessor(bean);
|
||||
Method method = this.getMethod(aggregator);
|
||||
Method expected = SingleAnnotationTestBean.class.getMethod("method1", new Class[] { List.class });
|
||||
assertEquals(expected, method);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void multipleAnnotations() {
|
||||
MultipleAnnotationTestBean bean = new MultipleAnnotationTestBean();
|
||||
new MethodInvokingMessageGroupProcessor(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noAnnotations() throws Exception {
|
||||
NoAnnotationTestBean bean = new NoAnnotationTestBean();
|
||||
MethodInvokingMessageGroupProcessor aggregator = new MethodInvokingMessageGroupProcessor(bean);
|
||||
Method method = this.getMethod(aggregator);
|
||||
Method expected = NoAnnotationTestBean.class.getMethod("method1", new Class[] { List.class });
|
||||
assertEquals(expected, method);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void multiplePublicMethods() {
|
||||
MultiplePublicMethodTestBean bean = new MultiplePublicMethodTestBean();
|
||||
new MethodInvokingMessageGroupProcessor(bean);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void noPublicMethods() {
|
||||
NoPublicMethodTestBean bean = new NoPublicMethodTestBean();
|
||||
new MethodInvokingMessageGroupProcessor(bean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void jdkProxy() {
|
||||
DirectChannel input = new DirectChannel();
|
||||
QueueChannel output = new QueueChannel();
|
||||
GreetingService testBean = new GreetingBean();
|
||||
ProxyFactory proxyFactory = new ProxyFactory(testBean);
|
||||
proxyFactory.setProxyTargetClass(false);
|
||||
testBean = (GreetingService) proxyFactory.getProxy();
|
||||
MethodInvokingMessageGroupProcessor aggregator = new MethodInvokingMessageGroupProcessor(testBean);
|
||||
CorrelatingMessageHandler handler = new CorrelatingMessageHandler(aggregator);
|
||||
handler.setReleaseStrategy(new MessageCountReleaseStrategy());
|
||||
handler.setOutputChannel(output);
|
||||
EventDrivenConsumer endpoint = new EventDrivenConsumer(input, handler);
|
||||
endpoint.start();
|
||||
Message<?> message = MessageBuilder.withPayload("proxy").setCorrelationId("abc").build();
|
||||
input.send(message);
|
||||
assertEquals("hello proxy", output.receive(0).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void cglibProxy() {
|
||||
DirectChannel input = new DirectChannel();
|
||||
QueueChannel output = new QueueChannel();
|
||||
GreetingService testBean = new GreetingBean();
|
||||
ProxyFactory proxyFactory = new ProxyFactory(testBean);
|
||||
proxyFactory.setProxyTargetClass(true);
|
||||
testBean = (GreetingService) proxyFactory.getProxy();
|
||||
MethodInvokingMessageGroupProcessor aggregator = new MethodInvokingMessageGroupProcessor(testBean);
|
||||
CorrelatingMessageHandler handler = new CorrelatingMessageHandler(aggregator);
|
||||
handler.setReleaseStrategy(new MessageCountReleaseStrategy());
|
||||
handler.setOutputChannel(output);
|
||||
EventDrivenConsumer endpoint = new EventDrivenConsumer(input, handler);
|
||||
endpoint.start();
|
||||
Message<?> message = MessageBuilder.withPayload("proxy").setCorrelationId("abc").build();
|
||||
input.send(message);
|
||||
assertEquals("hello proxy", output.receive(0).getPayload());
|
||||
}
|
||||
|
||||
private Method getMethod(MethodInvokingMessageGroupProcessor aggregator) {
|
||||
Object invoker = new DirectFieldAccessor(aggregator).getPropertyValue("adapter");
|
||||
return (Method) new DirectFieldAccessor(invoker).getPropertyValue("method");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class SingleAnnotationTestBean {
|
||||
|
||||
@Aggregator
|
||||
public String method1(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
|
||||
public String method2(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class MultipleAnnotationTestBean {
|
||||
|
||||
@Aggregator
|
||||
public String method1(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
|
||||
@Aggregator
|
||||
public String method2(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NoAnnotationTestBean {
|
||||
|
||||
public String method1(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
|
||||
String method2(List<String> input) {
|
||||
return input.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class MultiplePublicMethodTestBean {
|
||||
|
||||
public String upperCase(String s) {
|
||||
return s.toUpperCase();
|
||||
}
|
||||
|
||||
public String lowerCase(String s) {
|
||||
return s.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class NoPublicMethodTestBean {
|
||||
|
||||
String lowerCase(String s) {
|
||||
return s.toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
public interface GreetingService {
|
||||
|
||||
String sayHello(List<String> names);
|
||||
|
||||
}
|
||||
|
||||
public static class GreetingBean implements GreetingService {
|
||||
|
||||
private String greeting = "hello";
|
||||
|
||||
public void setGreeting(String greeting) {
|
||||
this.greeting = greeting;
|
||||
}
|
||||
|
||||
@Aggregator
|
||||
public String sayHello(List<String> names) {
|
||||
return greeting + " " + names.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.aggregator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class ReleaseStrategyAdapterTests {
|
||||
|
||||
private SimpleReleaseStrategy simpleReleaseStrategy;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
simpleReleaseStrategy = new SimpleReleaseStrategy();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTrueConvertedProperly() {
|
||||
ReleaseStrategyAdapter adapter = new ReleaseStrategyAdapter(new AlwaysTrueReleaseStrategy(),
|
||||
"checkCompleteness");
|
||||
Assert.assertTrue(adapter.canRelease(createListOfMessages(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFalseConvertedProperly() {
|
||||
ReleaseStrategyAdapter adapter = new ReleaseStrategyAdapter(new AlwaysFalseReleaseStrategy(),
|
||||
"checkCompleteness");
|
||||
Assert.assertTrue(!adapter.canRelease(createListOfMessages(0)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdapterWithNonParameterizedMessageListBasedMethod() {
|
||||
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy,
|
||||
"checkCompletenessOnNonParameterizedListOfMessages");
|
||||
MessageGroup messages = createListOfMessages(3);
|
||||
Assert.assertTrue(adapter.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdapterWithWildcardParametrizedMessageBasedMethod() {
|
||||
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy,
|
||||
"checkCompletenessOnListOfMessagesParametrizedWithWildcard");
|
||||
MessageGroup messages = createListOfMessages(3);
|
||||
Assert.assertTrue(adapter.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdapterWithTypeParametrizedMessageBasedMethod() {
|
||||
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy,
|
||||
"checkCompletenessOnListOfMessagesParametrizedWithString");
|
||||
MessageGroup messages = createListOfMessages(3);
|
||||
Assert.assertTrue(adapter.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdapterWithPojoBasedMethod() {
|
||||
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy, "checkCompletenessOnListOfStrings");
|
||||
MessageGroup messages = createListOfMessages(3);
|
||||
Assert.assertTrue(adapter.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAdapterWithPojoBasedMethodReturningObject() {
|
||||
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy, "checkCompletenessOnListOfStrings");
|
||||
MessageGroup messages = createListOfMessages(3);
|
||||
Assert.assertTrue(adapter.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testAdapterWithWrongMethodName() {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, "methodThatDoesNotExist");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testInvalidParameterTypeUsingMethodName() {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, "invalidParameterType");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testTooManyParametersUsingMethodName() {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, "tooManyParameters");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNotEnoughParametersUsingMethodName() {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, "notEnoughParameters");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testListSubclassParameterUsingMethodName() {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, "ListSubclassParameter");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testWrongReturnType() throws SecurityException, NoSuchMethodError {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, "wrongReturnType");
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testTooManyParametersUsingMethodObject() throws SecurityException, NoSuchMethodException {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod(
|
||||
"tooManyParameters", List.class, List.class));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNotEnoughParametersUsingMethodObject() throws SecurityException, NoSuchMethodException {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod(
|
||||
"notEnoughParameters", new Class[] {}));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testListSubclassParameterUsingMethodObject() throws SecurityException, NoSuchMethodException {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod(
|
||||
"ListSubclassParameter", new Class[] { LinkedList.class }));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testWrongReturnTypeUsingMethodObject() throws SecurityException, NoSuchMethodException {
|
||||
new ReleaseStrategyAdapter(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod("wrongReturnType",
|
||||
new Class[] { List.class }));
|
||||
}
|
||||
|
||||
private static MessageGroup createListOfMessages(int size) {
|
||||
List<Message<?>> messages = new ArrayList<Message<?>>();
|
||||
if (size > 0) {
|
||||
messages.add(new GenericMessage<String>("123"));
|
||||
}
|
||||
if (size > 1) {
|
||||
messages.add(new GenericMessage<String>("456"));
|
||||
}
|
||||
if (size > 2) {
|
||||
messages.add(new GenericMessage<String>("789"));
|
||||
}
|
||||
return new SimpleMessageGroup(messages, "ABC");
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class AlwaysTrueReleaseStrategy {
|
||||
public boolean checkCompleteness(List<Message<?>> messages) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class AlwaysFalseReleaseStrategy {
|
||||
public boolean checkCompleteness(List<Message<?>> messages) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class SimpleReleaseStrategy {
|
||||
|
||||
public boolean checkCompletenessOnNonParameterizedListOfMessages(List<Message<?>> messages) {
|
||||
Assert.assertTrue(messages.size() > 0);
|
||||
return messages.size() > messages.iterator().next().getHeaders().getSequenceSize();
|
||||
}
|
||||
|
||||
public boolean checkCompletenessOnListOfMessagesParametrizedWithWildcard(List<Message<?>> messages) {
|
||||
Assert.assertTrue(messages.size() > 0);
|
||||
return messages.size() > messages.iterator().next().getHeaders().getSequenceSize();
|
||||
}
|
||||
|
||||
public boolean checkCompletenessOnListOfMessagesParametrizedWithString(List<Message<String>> messages) {
|
||||
Assert.assertTrue(messages.size() > 0);
|
||||
return messages.size() > messages.iterator().next().getHeaders().getSequenceSize();
|
||||
}
|
||||
|
||||
// Example for the case when completeness is checked on the structure of
|
||||
// the data
|
||||
public boolean checkCompletenessOnListOfStrings(List<String> messages) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (String content : messages) {
|
||||
buffer.append(content);
|
||||
}
|
||||
return buffer.length() >= 9;
|
||||
}
|
||||
|
||||
public String wrongReturnType(List<Message<?>> message) {
|
||||
return "";
|
||||
}
|
||||
|
||||
public boolean invalidParameterType(String invalid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean tooManyParameters(List<?> c1, List<?> c2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean notEnoughParameters() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean ListSubclassParameter(LinkedList<?> l1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,294 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Alex Peters
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ResequencerTests {
|
||||
|
||||
private CorrelatingMessageHandler resequencer;
|
||||
|
||||
private ResequencingMessageGroupProcessor processor = new ResequencingMessageGroupProcessor();
|
||||
|
||||
private MessageGroupStore store = new SimpleMessageStore();
|
||||
|
||||
@Before
|
||||
public void configureResequencer() {
|
||||
this.resequencer = new CorrelatingMessageHandler(processor, store, null, null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicResequencing() throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 3, 3, replyChannel);
|
||||
Message<?> message2 = createMessage("456", "ABC", 3, 1, replyChannel);
|
||||
Message<?> message3 = createMessage("789", "ABC", 3, 2, replyChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message3);
|
||||
this.resequencer.handleMessage(message2);
|
||||
Message<?> reply1 = replyChannel.receive(0);
|
||||
Message<?> reply2 = replyChannel.receive(0);
|
||||
Message<?> reply3 = replyChannel.receive(0);
|
||||
assertNotNull(reply1);
|
||||
assertEquals(new Integer(1), reply1.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply2);
|
||||
assertEquals(new Integer(2), reply2.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply3);
|
||||
assertEquals(new Integer(3), reply3.getHeaders().getSequenceNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBasicResequencingWithCustomComparator() throws InterruptedException {
|
||||
this.processor.setComparator(new Comparator<Message<?>>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(Message<?> o1, Message<?> o2) {
|
||||
return ((Comparable)o1.getPayload()).compareTo(o2.getPayload());
|
||||
}
|
||||
});
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("789", "ABC", 3, 1, replyChannel);
|
||||
Message<?> message2 = createMessage("123", "ABC", 3, 2, replyChannel);
|
||||
Message<?> message3 = createMessage("456", "ABC", 3, 3, replyChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message3);
|
||||
this.resequencer.handleMessage(message2);
|
||||
Message<?> reply1 = replyChannel.receive(0);
|
||||
Message<?> reply2 = replyChannel.receive(0);
|
||||
Message<?> reply3 = replyChannel.receive(0);
|
||||
assertNotNull(reply1);
|
||||
assertEquals(new Integer(2), reply1.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply2);
|
||||
assertEquals(new Integer(3), reply2.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply3);
|
||||
assertEquals(new Integer(1), reply3.getHeaders().getSequenceNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithDuplicateMessages() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 3, 3, replyChannel);
|
||||
Message<?> message2 = createMessage("456", "ABC", 3, 1, replyChannel);
|
||||
Message<?> message3 = createMessage("789", "ABC", 3, 2, replyChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message3);
|
||||
this.resequencer.handleMessage(message3);
|
||||
this.resequencer.handleMessage(message2);
|
||||
Message<?> reply1 = replyChannel.receive(0);
|
||||
Message<?> reply2 = replyChannel.receive(0);
|
||||
Message<?> reply3 = replyChannel.receive(0);
|
||||
assertNotNull(reply1);
|
||||
assertEquals(new Integer(1), reply1.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply2);
|
||||
assertEquals(new Integer(2), reply2.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply3);
|
||||
assertEquals(new Integer(3), reply3.getHeaders().getSequenceNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithIncompleteSequenceRelease() throws InterruptedException {
|
||||
this.resequencer.setReleaseStrategy(new SequenceSizeReleaseStrategy(true));
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 4, 2, replyChannel);
|
||||
Message<?> message2 = createMessage("456", "ABC", 4, 1, replyChannel);
|
||||
Message<?> message3 = createMessage("789", "ABC", 4, 4, replyChannel);
|
||||
Message<?> message4 = createMessage("XYZ", "ABC", 4, 3, replyChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message2);
|
||||
this.resequencer.handleMessage(message3);
|
||||
Message<?> reply1 = replyChannel.receive(0);
|
||||
Message<?> reply2 = replyChannel.receive(0);
|
||||
Message<?> reply3 = replyChannel.receive(0);
|
||||
// only messages 1 and 2 should have been received by now
|
||||
assertNotNull(reply1);
|
||||
assertEquals(new Integer(1), reply1.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply2);
|
||||
assertEquals(new Integer(2), reply2.getHeaders().getSequenceNumber());
|
||||
assertNull(reply3);
|
||||
// when sending the last message, the whole sequence must have been sent
|
||||
this.resequencer.handleMessage(message4);
|
||||
reply3 = replyChannel.receive(0); Message<?> reply4 = replyChannel.receive(0);
|
||||
assertNotNull(reply3);
|
||||
assertEquals(new Integer(3), reply3.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply4);
|
||||
assertEquals(new Integer(4), reply4.getHeaders().getSequenceNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithPartialSequenceAndComparator() throws InterruptedException {
|
||||
this.resequencer.setReleaseStrategy(new SequenceSizeReleaseStrategy(true));
|
||||
this.processor.setComparator(new Comparator<Message<?>>() {
|
||||
@SuppressWarnings("unchecked")
|
||||
public int compare(Message<?> o1, Message<?> o2) {
|
||||
return ((Comparable)o1.getPayload()).compareTo(o2.getPayload());
|
||||
}
|
||||
});
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("456", "ABC", 4, 2, replyChannel);
|
||||
Message<?> message2 = createMessage("123", "ABC", 4, 1, replyChannel);
|
||||
Message<?> message3 = createMessage("XYZ", "ABC", 4, 4, replyChannel);
|
||||
Message<?> message4 = createMessage("789", "ABC", 4, 3, replyChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message2);
|
||||
this.resequencer.handleMessage(message3);
|
||||
Message<?> reply1 = replyChannel.receive(0);
|
||||
Message<?> reply2 = replyChannel.receive(0);
|
||||
Message<?> reply3 = replyChannel.receive(0);
|
||||
// only messages 1 and 2 should have been received by now
|
||||
assertNotNull(reply1);
|
||||
assertEquals(new Integer(1), reply1.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply2);
|
||||
assertEquals(new Integer(2), reply2.getHeaders().getSequenceNumber());
|
||||
assertNull(reply3);
|
||||
// when sending the last message, the whole sequence must have been sent
|
||||
this.resequencer.handleMessage(message4);
|
||||
reply3 = replyChannel.receive(0);
|
||||
Message<?> reply4 = replyChannel.receive(0);
|
||||
assertNotNull(reply3);
|
||||
assertEquals(new Integer(3), reply3.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply4);
|
||||
assertEquals(new Integer(4), reply4.getHeaders().getSequenceNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithDiscard() throws InterruptedException {
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 4, 2, null);
|
||||
Message<?> message2 = createMessage("456", "ABC", 4, 1, null);
|
||||
Message<?> message3 = createMessage("789", "ABC", 4, 4, null);
|
||||
this.resequencer.setSendPartialResultOnExpiry(false);
|
||||
this.resequencer.setDiscardChannel(discardChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message2);
|
||||
assertEquals(1, store.expireMessageGroups(-10000));
|
||||
Message<?> reply1 = discardChannel.receive(0);
|
||||
Message<?> reply2 = discardChannel.receive(0);
|
||||
Message<?> reply3 = discardChannel.receive(0);
|
||||
// only messages 1 and 2 should have been received by now
|
||||
assertNotNull(reply1);
|
||||
assertNotNull(reply2);
|
||||
assertNull(reply3);
|
||||
ArrayList<Integer> sequence = new ArrayList<Integer>(Arrays.asList(reply1.getHeaders().getSequenceNumber(), reply2.getHeaders()
|
||||
.getSequenceNumber()));
|
||||
Collections.sort(sequence);
|
||||
assertEquals("[1, 2]", sequence.toString());
|
||||
// when sending the last message, the whole sequence must have been sent
|
||||
this.resequencer.handleMessage(message3);
|
||||
reply3 = discardChannel.receive(0);
|
||||
assertNull(reply3);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithDifferentSequenceSizes() throws InterruptedException {
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 4, 2, null);
|
||||
Message<?> message2 = createMessage("456", "ABC", 5, 1, null);
|
||||
this.resequencer.setSendPartialResultOnExpiry(false);
|
||||
this.resequencer.setDiscardChannel(discardChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message2);
|
||||
// this.resequencer.discardBarrier(this.resequencer.barriers.get("ABC"));
|
||||
Message<?> discard1 = discardChannel.receive(0);
|
||||
Message<?> discard2 = discardChannel.receive(0);
|
||||
// message2 has been discarded because it came in with the wrong sequence size
|
||||
assertNotNull(discard1);
|
||||
assertEquals(new Integer(1), discard1.getHeaders().getSequenceNumber());
|
||||
assertNull(discard2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithWrongSequenceSizeAndNumber() throws InterruptedException {
|
||||
QueueChannel discardChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 2, 4, null);
|
||||
this.resequencer.setSendPartialResultOnExpiry(false);
|
||||
this.resequencer.setDiscardChannel(discardChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
// this.resequencer.discardBarrier(this.resequencer.barriers.get("ABC"));
|
||||
Message<?> reply1 = discardChannel.receive(0);
|
||||
// No message has been received - the message has been rejected.
|
||||
assertNull(reply1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testResequencingWithCompleteSequenceRelease() throws InterruptedException {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 4, 2, replyChannel);
|
||||
Message<?> message2 = createMessage("456", "ABC", 4, 1, replyChannel);
|
||||
Message<?> message3 = createMessage("789", "ABC", 4, 4, replyChannel);
|
||||
Message<?> message4 = createMessage("XYZ", "ABC", 4, 3, replyChannel);
|
||||
this.resequencer.handleMessage(message1);
|
||||
this.resequencer.handleMessage(message2);
|
||||
this.resequencer.handleMessage(message3);
|
||||
Message<?> reply1 = replyChannel.receive(0);
|
||||
Message<?> reply2 = replyChannel.receive(0);
|
||||
Message<?> reply3 = replyChannel.receive(0);
|
||||
// no messages should have been received yet
|
||||
assertNull(reply1);
|
||||
assertNull(reply2);
|
||||
assertNull(reply3);
|
||||
// after sending the last message, the whole sequence should have been sent
|
||||
this.resequencer.handleMessage(message4);
|
||||
reply1 = replyChannel.receive(0);
|
||||
reply2 = replyChannel.receive(0);
|
||||
reply3 = replyChannel.receive(0);
|
||||
Message<?> reply4 = replyChannel.receive(0);
|
||||
assertNotNull(reply1);
|
||||
assertEquals(new Integer(1), reply1.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply2);
|
||||
assertEquals(new Integer(2), reply2.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply3);
|
||||
assertEquals(new Integer(3), reply3.getHeaders().getSequenceNumber());
|
||||
assertNotNull(reply4);
|
||||
assertEquals(new Integer(4), reply4.getHeaders().getSequenceNumber());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testRemovalOfBarrierWhenLastMessageOfSequenceArrives() {
|
||||
QueueChannel replyChannel = new QueueChannel();
|
||||
String correlationId = "ABC";
|
||||
Message<?> message1 = createMessage("123", correlationId, 1, 1, replyChannel);
|
||||
resequencer.handleMessage(message1);
|
||||
assertEquals(0, store.getMessageGroup(correlationId).size());
|
||||
}
|
||||
|
||||
private static Message<?> createMessage(String payload, Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel replyChannel) {
|
||||
return MessageBuilder.withPayload(payload).setCorrelationId(correlationId).setSequenceSize(sequenceSize)
|
||||
.setSequenceNumber(sequenceNumber).setReplyChannel(replyChannel).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class SequenceSizeReleaseStrategyTests {
|
||||
|
||||
@Test
|
||||
public void testIncompleteList() {
|
||||
Message<String> message = MessageBuilder.withPayload("test1")
|
||||
.setSequenceSize(2).build();
|
||||
MessageGroup messages = new SimpleMessageGroup("FOO");
|
||||
messages.add(message);
|
||||
SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
assertFalse(releaseStrategy.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompleteList() {
|
||||
Message<String> message1 = MessageBuilder.withPayload("test1")
|
||||
.setSequenceSize(2).build();
|
||||
Message<String> message2 = MessageBuilder.withPayload("test2")
|
||||
.setSequenceSize(2).build();
|
||||
MessageGroup messages = new SimpleMessageGroup("FOO");
|
||||
messages.add(message1);
|
||||
messages.add(message2);
|
||||
SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
assertTrue(releaseStrategy.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyList() {
|
||||
SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
assertTrue(releaseStrategy.canRelease(new SimpleMessageGroup("FOO")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageGroup;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class TimeoutCountSequenceSizeReleaseStrategyTests {
|
||||
|
||||
@Test
|
||||
public void testIncompleteList() {
|
||||
Message<String> message = MessageBuilder.withPayload("test1")
|
||||
.setSequenceSize(2).build();
|
||||
MessageGroup messages = new SimpleMessageGroup("FOO");
|
||||
messages.add(message);
|
||||
TimeoutCountSequenceSizeReleaseStrategy releaseStrategy = new TimeoutCountSequenceSizeReleaseStrategy();
|
||||
assertFalse(releaseStrategy.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncompleteListWithTimeout() {
|
||||
Message<String> message = MessageBuilder.withPayload("test1")
|
||||
.setSequenceSize(2).build();
|
||||
MessageGroup messages = new SimpleMessageGroup("FOO");
|
||||
messages.add(message);
|
||||
TimeoutCountSequenceSizeReleaseStrategy releaseStrategy = new TimeoutCountSequenceSizeReleaseStrategy(TimeoutCountSequenceSizeReleaseStrategy.DEFAULT_THRESHOLD, -100);
|
||||
assertTrue(releaseStrategy.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIncompleteListWithCount() {
|
||||
Message<String> message = MessageBuilder.withPayload("test1")
|
||||
.setSequenceSize(2).build();
|
||||
MessageGroup messages = new SimpleMessageGroup("FOO");
|
||||
messages.add(message);
|
||||
TimeoutCountSequenceSizeReleaseStrategy releaseStrategy = new TimeoutCountSequenceSizeReleaseStrategy(1, TimeoutCountSequenceSizeReleaseStrategy.DEFAULT_TIMEOUT);
|
||||
assertTrue(releaseStrategy.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompleteList() {
|
||||
Message<String> message1 = MessageBuilder.withPayload("test1")
|
||||
.setSequenceSize(2).build();
|
||||
Message<String> message2 = MessageBuilder.withPayload("test2")
|
||||
.setSequenceSize(2).build();
|
||||
MessageGroup messages = new SimpleMessageGroup("FOO");
|
||||
messages.add(message1);
|
||||
messages.add(message2);
|
||||
SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
assertTrue(releaseStrategy.canRelease(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyList() {
|
||||
SequenceSizeReleaseStrategy releaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
assertTrue(releaseStrategy.canRelease(new SimpleMessageGroup("FOO")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
<aggregator ref="summer" method="sum" input-channel="input"
|
||||
output-channel="output">
|
||||
<poller task-executor="executor" max-messages-per-poll="5">
|
||||
<interval-trigger interval="20" />
|
||||
</poller>
|
||||
</aggregator>
|
||||
|
||||
<task:executor id="executor" pool-size="5"/>
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
<beans:bean id="summer"
|
||||
class="org.springframework.integration.aggregator.integration.AggregatorIntegrationTests$SummingAggregator" />
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.aggregator.integration;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.core.MessageHeaders;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Iwein Fuld
|
||||
* @author Alex Peters
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class AggregatorIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("input")
|
||||
private MessageChannel input;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("output")
|
||||
private PollableChannel output;
|
||||
|
||||
@Test(timeout=5000)
|
||||
public void aggregate() throws Exception {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Map<String, Object> headers = stubHeaders(i, 5, 1);
|
||||
input.send(new GenericMessage<Integer>(i, headers));
|
||||
}
|
||||
assertEquals(0 + 1 + 2 + 3 + 4, output.receive().getPayload());
|
||||
}
|
||||
|
||||
// configured in context associated with this test
|
||||
public static class SummingAggregator {
|
||||
public Integer sum(List<Integer> numbers) {
|
||||
int result = 0;
|
||||
for (Integer number : numbers) {
|
||||
result += number;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, Object> stubHeaders(int sequenceNumber, int sequenceSize, int correllationId) {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
headers.put(MessageHeaders.SEQUENCE_NUMBER, sequenceNumber);
|
||||
headers.put(MessageHeaders.SEQUENCE_SIZE, sequenceSize);
|
||||
headers.put(MessageHeaders.CORRELATION_ID, correllationId);
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:task="http://www.springframework.org/schema/task"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<annotation-config />
|
||||
|
||||
<channel id="input">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
<aggregator input-channel="input" output-channel="output">
|
||||
<poller task-executor="executor" max-messages-per-poll="5">
|
||||
<interval-trigger interval="20" />
|
||||
</poller>
|
||||
</aggregator>
|
||||
|
||||
<task:executor id="executor" pool-size="5"/>
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aggregator.integration;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.core.MessageHeaders;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Alex Peters
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class DefaultMessageAggregatorIntegrationTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("input")
|
||||
private MessageChannel input;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("output")
|
||||
private PollableChannel output;
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test(timeout = 1000)
|
||||
public void aggregate() throws Exception {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
Map<String, Object> headers = stubHeaders(i, 5, 1);
|
||||
input.send(new GenericMessage<Integer>(i, headers));
|
||||
}
|
||||
Object payload = output.receive().getPayload();
|
||||
assertThat(payload, is(List.class));
|
||||
assertTrue(payload + " doesn't contain all of {0,1,2,3,4}",
|
||||
((List) payload).containsAll(Arrays.asList(0, 1, 2, 3, 4)));
|
||||
}
|
||||
|
||||
|
||||
private Map<String, Object> stubHeaders(int sequenceNumber, int sequenceSize, int correllationId) {
|
||||
Map<String, Object> headers = new HashMap<String, Object>();
|
||||
headers.put(MessageHeaders.SEQUENCE_NUMBER, sequenceNumber);
|
||||
headers.put(MessageHeaders.SEQUENCE_SIZE, sequenceSize);
|
||||
headers.put(MessageHeaders.CORRELATION_ID, correllationId);
|
||||
return headers;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
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
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="pojoOutput">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<channel id="defaultOutput">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<splitter input-channel="pojoInput" output-channel="pojoAggregator"/>
|
||||
|
||||
<aggregator input-channel="pojoAggregator" output-channel="pojoOutput" method="aggregate">
|
||||
<beans:bean class="org.springframework.integration.aggregator.integration.MethodInvokingAggregatorReturningMessageTests$TestAggregator"/>
|
||||
</aggregator>
|
||||
|
||||
<splitter input-channel="defaultInput" output-channel="defaultAggregator"/>
|
||||
|
||||
<aggregator input-channel="defaultAggregator" output-channel="defaultOutput"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator.integration;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MethodInvokingAggregatorReturningMessageTests {
|
||||
|
||||
@Autowired
|
||||
DirectChannel pojoInput;
|
||||
|
||||
@Autowired
|
||||
DirectChannel defaultInput;
|
||||
|
||||
@Autowired
|
||||
PollableChannel pojoOutput;
|
||||
|
||||
@Autowired
|
||||
PollableChannel defaultOutput;
|
||||
|
||||
|
||||
@Test // INT-1107
|
||||
public void messageReturningPojoAggregatorResultIsNotWrappedInAnotherMessage() {
|
||||
List<String> payload = Collections.singletonList("test");
|
||||
pojoInput.send(MessageBuilder.withPayload(payload).build());
|
||||
Message<?> result = pojoOutput.receive();
|
||||
assertFalse(Message.class.isAssignableFrom(result.getPayload().getClass()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultAggregatorResultIsNotWrappedInAnotherMessage() {
|
||||
List<String> payload = Collections.singletonList("test");
|
||||
defaultInput.send(MessageBuilder.withPayload(payload).build());
|
||||
Message<?> result = defaultOutput.receive();
|
||||
assertFalse(Message.class.isAssignableFrom(result.getPayload().getClass()));
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class TestAggregator {
|
||||
|
||||
public Message<?> aggregate(final List<Message<?>> messages) {
|
||||
List<String> payload = Collections.singletonList("foo");
|
||||
return MessageBuilder.withPayload(payload).setHeader("bar", 123).build();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns="http://www.springframework.org/schema/integration"
|
||||
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-2.5.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">
|
||||
|
||||
<channel id="input_for_aggregator_with_explicit_timeout"/>
|
||||
<channel id="input_for_aggregator_without_explicit_timeout"/>
|
||||
<channel id="aggregator_with_explicit_timeout_channel"/>
|
||||
<channel id="aggregator_without_explicit_timeout_channel"/>
|
||||
|
||||
<channel id="reply">
|
||||
<queue capacity="10"/>
|
||||
</channel>
|
||||
|
||||
<splitter id="splitter_to_aggregator_with_explicit_timeout"
|
||||
input-channel="input_for_aggregator_with_explicit_timeout"
|
||||
output-channel="aggregator_with_explicit_timeout_channel"/>
|
||||
|
||||
<splitter id="splitter_to_aggregator_without_explicit_timeout"
|
||||
input-channel="input_for_aggregator_without_explicit_timeout"
|
||||
output-channel="aggregator_without_explicit_timeout_channel"/>
|
||||
|
||||
<aggregator id="aggregator_with_explicit_timeout"
|
||||
timeout="1000"
|
||||
input-channel="aggregator_with_explicit_timeout_channel"/>
|
||||
|
||||
<aggregator id="aggregator_without_explicit_timeout"
|
||||
input-channel="aggregator_without_explicit_timeout_channel"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.aggregator.scenarios;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Tests courtesy of Sean Crotty (INT-1093)
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class AggregationResendTests {
|
||||
|
||||
@Autowired
|
||||
DirectChannel input_for_aggregator_with_explicit_timeout;
|
||||
|
||||
@Autowired
|
||||
DirectChannel input_for_aggregator_without_explicit_timeout;
|
||||
|
||||
@Autowired
|
||||
QueueChannel reply;
|
||||
|
||||
|
||||
/**
|
||||
* We expect to get back only one Message from the aggregator. We set an
|
||||
* explicit timeout value of 1 second on the aggregator. What we'll see is
|
||||
* that we get one aggregate Message back immediately.
|
||||
*
|
||||
* <p>We should <emphasis>not</emphasis> get another 3 after the 1 second.
|
||||
*/
|
||||
@Test
|
||||
public void testAggregatorWithoutExplicitTimeoutReturnsOnlyOneMessage() throws Exception {
|
||||
sendMessage(input_for_aggregator_with_explicit_timeout, 2000);
|
||||
}
|
||||
|
||||
/**
|
||||
* We expect to get back only one Message from the aggregator. We set no
|
||||
* explicit timeout value on the aggregator, but it automatically times out
|
||||
* after 60 seconds. What we'll see is that we get one aggregate Message back
|
||||
* immediately.
|
||||
*
|
||||
* <p>We should <emphasis>not</emphasis> get another 3 after the 60 seconds.
|
||||
*/
|
||||
@Test
|
||||
@Ignore // disabling from normal testing, should be the same behavior whether explicit or default
|
||||
public void testAggregatorWithTimeoutReturnsOnlyOneMessage() throws Exception {
|
||||
sendMessage(input_for_aggregator_without_explicit_timeout, 62000);
|
||||
}
|
||||
|
||||
private void sendMessage(DirectChannel channel, int waitSeconds) {
|
||||
List<String> list = new ArrayList<String>();
|
||||
list.add("foo");
|
||||
list.add("bar");
|
||||
list.add("baz");
|
||||
|
||||
reply.purge(null);
|
||||
channel.send(MessageBuilder.withPayload(list).setReplyChannel(reply).build());
|
||||
|
||||
Message<?> replyMessage;
|
||||
int messageCount = 0;
|
||||
do {
|
||||
replyMessage = reply.receive(waitSeconds);
|
||||
if (null != replyMessage) {
|
||||
System.out.println("Message Received: " + replyMessage);
|
||||
messageCount++;
|
||||
}
|
||||
} while (null != replyMessage);
|
||||
|
||||
Assert.assertEquals(1, messageCount);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:si="http://www.springframework.org/schema/integration">
|
||||
|
||||
<bean id="testBean"
|
||||
class="org.springframework.integration.aop.MessagePublishingAnnotationUsageTests$TestBean" />
|
||||
|
||||
<si:channel id="testChannel">
|
||||
<si:queue />
|
||||
</si:channel>
|
||||
|
||||
<bean class="org.springframework.integration.aop.PublisherAnnotationBeanPostProcessor"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aop;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MessagePublishingAnnotationUsageTests {
|
||||
|
||||
@Autowired
|
||||
private TestBean testBean;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel channel;
|
||||
|
||||
@Test
|
||||
public void demoMessagePublishingInterceptor() {
|
||||
String name = testBean.setName("John", "Doe");
|
||||
Assert.assertNotNull(name);
|
||||
Message<?> message = channel.receive(1000);
|
||||
Assert.assertNotNull(message);
|
||||
Assert.assertEquals("John Doe", message.getPayload());
|
||||
Assert.assertEquals("123", message.getHeaders().get("bar"));
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
@Publisher(value="#return", channel="testChannel", headers="bar='123'")
|
||||
public String setName(String fname, String lname){
|
||||
return fname + " " + lname;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.integration.channel.MapBasedChannelResolver;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MessagePublishingInterceptorTests {
|
||||
|
||||
private final ExpressionSource source = new TestExpressionSource();
|
||||
|
||||
private final MapBasedChannelResolver channelResolver = new MapBasedChannelResolver();
|
||||
|
||||
private final QueueChannel testChannel = new QueueChannel();
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
channelResolver.setChannelMap(Collections.singletonMap("c", testChannel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnValue() {
|
||||
MessagePublishingInterceptor interceptor = new MessagePublishingInterceptor(source);
|
||||
interceptor.setChannelResolver(channelResolver);
|
||||
ProxyFactory pf = new ProxyFactory(new TestBeanImpl());
|
||||
pf.addAdvice(interceptor);
|
||||
TestBean proxy = (TestBean) pf.getProxy();
|
||||
proxy.test();
|
||||
Message<?> message = testChannel.receive(0);
|
||||
assertNotNull(message);
|
||||
assertEquals("foo", message.getPayload());
|
||||
}
|
||||
@Test
|
||||
public void demoMethodNameMappingExpressionSource() {
|
||||
Map<String, String> expressionMap = new HashMap<String, String>();
|
||||
expressionMap.put("test", "#return");
|
||||
MethodNameMappingExpressionSource source = new MethodNameMappingExpressionSource(expressionMap);
|
||||
Map<String, String> channelMap = new HashMap<String, String>();
|
||||
channelMap.put("test", "c");
|
||||
source.setChannelMap(channelMap);
|
||||
|
||||
Map<String, String[]> headerExpressionMap = new HashMap<String, String[]>();
|
||||
headerExpressionMap.put("test", new String[]{"bar=#return","name='oleg'"});
|
||||
source.setHeaderExpressionMap(headerExpressionMap);
|
||||
|
||||
|
||||
MessagePublishingInterceptor interceptor = new MessagePublishingInterceptor(source);
|
||||
interceptor.setChannelResolver(channelResolver);
|
||||
ProxyFactory pf = new ProxyFactory(new TestBeanImpl());
|
||||
pf.addAdvice(interceptor);
|
||||
TestBean proxy = (TestBean) pf.getProxy();
|
||||
proxy.test();
|
||||
Message<?> message = testChannel.receive(0);
|
||||
assertNotNull(message);
|
||||
assertEquals("foo", message.getPayload());
|
||||
assertEquals("foo", message.getHeaders().get("bar"));
|
||||
assertEquals("oleg", message.getHeaders().get("name"));
|
||||
}
|
||||
|
||||
|
||||
static interface TestBean {
|
||||
|
||||
String test();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class TestBeanImpl implements TestBean {
|
||||
|
||||
public String test() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static class TestExpressionSource implements ExpressionSource {
|
||||
|
||||
public String getMethodNameVariableName(Method method) {
|
||||
return "m";
|
||||
}
|
||||
|
||||
public String getArgumentMapVariableName(Method method) {
|
||||
return "map";
|
||||
}
|
||||
|
||||
public String[] getArgumentVariableNames(Method method) {
|
||||
return new String[] { "a1", "a2"};
|
||||
}
|
||||
|
||||
public String getReturnValueVariableName(Method method) {
|
||||
return "r";
|
||||
}
|
||||
|
||||
public String getExceptionVariableName(Method method) {
|
||||
return "x";
|
||||
}
|
||||
|
||||
public String getPayloadExpression(Method method) {
|
||||
return "#r";
|
||||
}
|
||||
|
||||
public String[] getHeaderExpressions(Method method) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getChannelName(Method method) {
|
||||
return "c";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?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:aop="http://www.springframework.org/schema/aop"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:si="http://www.springframework.org/schema/integration">
|
||||
|
||||
<bean id="testBean"
|
||||
class="org.springframework.integration.aop.MessagePublishingInterceptorUsageTests$TestBean" />
|
||||
|
||||
<si:channel id="testChannel">
|
||||
<si:queue />
|
||||
</si:channel>
|
||||
|
||||
<aop:config>
|
||||
<aop:advisor advice-ref="interceptor" pointcut="bean(testBean)" />
|
||||
</aop:config>
|
||||
|
||||
<bean id="interceptor"
|
||||
class="org.springframework.integration.aop.MessagePublishingInterceptor">
|
||||
<constructor-arg>
|
||||
<bean
|
||||
class="org.springframework.integration.aop.MethodNameMappingExpressionSource">
|
||||
<constructor-arg>
|
||||
<map>
|
||||
<entry key="setName" value="#return" />
|
||||
</map>
|
||||
</constructor-arg>
|
||||
<property name="headerExpressionMap">
|
||||
<map>
|
||||
<entry key="setName" value="foo='bar'" />
|
||||
</map>
|
||||
</property>
|
||||
<property name="channelMap">
|
||||
<map>
|
||||
<entry key="setName" value="channel" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
</constructor-arg>
|
||||
<property name="channelResolver">
|
||||
<bean
|
||||
class="org.springframework.integration.channel.MapBasedChannelResolver">
|
||||
<property name="channelMap">
|
||||
<map>
|
||||
<entry key="channel" value-ref="testChannel" />
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aop;
|
||||
|
||||
import junit.framework.Assert;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class MessagePublishingInterceptorUsageTests {
|
||||
|
||||
@Autowired
|
||||
private TestBean testBean;
|
||||
|
||||
@Autowired
|
||||
private QueueChannel channel;
|
||||
|
||||
@Test
|
||||
public void demoMessagePublishingInterceptor(){
|
||||
String name = testBean.setName("John", "Doe");
|
||||
Assert.assertNotNull(name);
|
||||
Message<?> message = channel.receive(1000);
|
||||
Assert.assertNotNull(message);
|
||||
Assert.assertEquals("John Doe", message.getPayload());
|
||||
Assert.assertEquals("bar", message.getHeaders().get("foo"));
|
||||
}
|
||||
|
||||
|
||||
public static class TestBean {
|
||||
|
||||
public String setName(String fname, String lname){
|
||||
return fname + " " + lname;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class MethodAnnotationExpressionSourceTests {
|
||||
|
||||
private final MethodAnnotationExpressionSource source = new MethodAnnotationExpressionSource();
|
||||
|
||||
@Test
|
||||
public void defaultBindings() {
|
||||
Method method = getMethod("methodWithExpressionAnnotationOnly", String.class, int.class);
|
||||
String expressionString = source.getPayloadExpression(method);
|
||||
assertEquals("testExpression1", expressionString);
|
||||
assertEquals(2, source.getArgumentVariableNames(method).length);
|
||||
assertEquals("arg1", source.getArgumentVariableNames(method)[0]);
|
||||
assertEquals("arg2", source.getArgumentVariableNames(method)[1]);
|
||||
String[] headerStrings = source.getHeaderExpressions(method);
|
||||
assertNotNull(headerStrings);
|
||||
assertEquals(1, headerStrings.length);
|
||||
assertEquals("", headerStrings[0]);
|
||||
assertEquals(ExpressionSource.DEFAULT_ARGUMENT_MAP_VARIABLE_NAME, source.getArgumentMapVariableName(method));
|
||||
assertEquals(ExpressionSource.DEFAULT_EXCEPTION_VARIABLE_NAME, source.getExceptionVariableName(method));
|
||||
assertEquals(ExpressionSource.DEFAULT_RETURN_VALUE_VARIABLE_NAME, source.getReturnValueVariableName(method));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void annotationBindings() {
|
||||
Method method = getMethod("methodWithExpressionBinding", String.class, int.class);
|
||||
String expressionString = source.getPayloadExpression(method);
|
||||
assertEquals("testExpression2", expressionString);
|
||||
assertEquals(2, source.getArgumentVariableNames(method).length);
|
||||
assertEquals("s", source.getArgumentVariableNames(method)[0]);
|
||||
assertEquals("i", source.getArgumentVariableNames(method)[1]);
|
||||
assertEquals("argz", source.getArgumentMapVariableName(method));
|
||||
assertEquals("x", source.getExceptionVariableName(method));
|
||||
assertEquals("result", source.getReturnValueVariableName(method));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelName() {
|
||||
Method method = getMethod("methodWithChannelAndReturnAsPayload");
|
||||
String channelName = source.getChannelName(method);
|
||||
assertEquals("foo", channelName);
|
||||
}
|
||||
|
||||
|
||||
private static Method getMethod(String name, Class<?> ... params) {
|
||||
try {
|
||||
return MethodAnnotationExpressionSourceTests.class.getMethod(name, params);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new RuntimeException("failed to resolve method", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Publisher("testExpression1")
|
||||
public void methodWithExpressionAnnotationOnly(String arg1, int arg2) {
|
||||
}
|
||||
|
||||
@Publisher(value="#return", channel="foo", headers="bar=123")
|
||||
public void methodWithChannelAndReturnAsPayload() {
|
||||
}
|
||||
|
||||
@Publisher("testExpression2")
|
||||
@ExpressionBinding(argumentVariableNames="s, i", argumentMapVariableName="argz",
|
||||
exceptionVariableName="x", returnValueVariableName="result")
|
||||
public void methodWithExpressionBinding(String arg1, int arg2) {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.aop;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class PublisherAnnotationAdvisorTests {
|
||||
|
||||
private final StaticApplicationContext context = new StaticApplicationContext();
|
||||
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
context.registerSingleton("testChannel", QueueChannel.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void returnValue() {
|
||||
PublisherAnnotationAdvisor advisor = new PublisherAnnotationAdvisor();
|
||||
advisor.setBeanFactory(context);
|
||||
QueueChannel testChannel = context.getBean("testChannel", QueueChannel.class);
|
||||
advisor.setDefaultChannel(testChannel);
|
||||
ProxyFactory pf = new ProxyFactory(new TestBeanImpl());
|
||||
pf.addAdvisor(advisor);
|
||||
TestBean proxy = (TestBean) pf.getProxy();
|
||||
proxy.test();
|
||||
Message<?> message = testChannel.receive(0);
|
||||
assertNotNull(message);
|
||||
assertEquals("foo", message.getPayload());
|
||||
}
|
||||
|
||||
|
||||
static interface TestBean {
|
||||
|
||||
String test();
|
||||
|
||||
}
|
||||
|
||||
|
||||
static class TestBeanImpl implements TestBean {
|
||||
|
||||
@Publisher("#return")
|
||||
public String test() {
|
||||
return "foo";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.bus;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.endpoint.PollingConsumer;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.message.ErrorMessage;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageSource;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.test.util.TestUtils.TestApplicationContext;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ApplicationContextMessageBusTests {
|
||||
|
||||
@Test
|
||||
public void endpointRegistrationWithInputChannelReference() {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
QueueChannel sourceChannel = new QueueChannel();
|
||||
QueueChannel targetChannel = new QueueChannel();
|
||||
context.registerChannel("sourceChannel", sourceChannel);
|
||||
context.registerChannel("targetChannel", targetChannel);
|
||||
Message<String> message = MessageBuilder.withPayload("test")
|
||||
.setReplyChannelName("targetChannel").build();
|
||||
sourceChannel.send(message);
|
||||
AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
return message;
|
||||
}
|
||||
};
|
||||
handler.setBeanFactory(context);
|
||||
PollingConsumer endpoint = new PollingConsumer(sourceChannel, handler);
|
||||
context.registerEndpoint("testEndpoint", endpoint);
|
||||
context.refresh();
|
||||
Message<?> result = targetChannel.receive(3000);
|
||||
assertEquals("test", result.getPayload());
|
||||
context.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelsWithoutHandlers() {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
QueueChannel sourceChannel = new QueueChannel();
|
||||
context.registerChannel("sourceChannel", sourceChannel);
|
||||
sourceChannel.send(new StringMessage("test"));
|
||||
QueueChannel targetChannel = new QueueChannel();
|
||||
context.registerChannel("targetChannel", targetChannel);
|
||||
context.refresh();
|
||||
Message<?> result = targetChannel.receive(100);
|
||||
assertNull(result);
|
||||
context.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autodetectionWithApplicationContext() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("messageBusTests.xml", this.getClass());
|
||||
context.start();
|
||||
PollableChannel sourceChannel = (PollableChannel) context.getBean("sourceChannel");
|
||||
sourceChannel.send(new GenericMessage<String>("test"));
|
||||
PollableChannel targetChannel = (PollableChannel) context.getBean("targetChannel");
|
||||
Message<?> result = targetChannel.receive(3000);
|
||||
assertEquals("test", result.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exactlyOneConsumerReceivesPointToPointMessage() {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
QueueChannel inputChannel = new QueueChannel();
|
||||
QueueChannel outputChannel1 = new QueueChannel();
|
||||
QueueChannel outputChannel2 = new QueueChannel();
|
||||
AbstractReplyProducingMessageHandler handler1 = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
return message;
|
||||
}
|
||||
};
|
||||
AbstractReplyProducingMessageHandler handler2 = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
return message;
|
||||
}
|
||||
};
|
||||
context.registerChannel("input", inputChannel);
|
||||
context.registerChannel("output1", outputChannel1);
|
||||
context.registerChannel("output2", outputChannel2);
|
||||
handler1.setOutputChannel(outputChannel1);
|
||||
handler2.setOutputChannel(outputChannel2);
|
||||
PollingConsumer endpoint1 = new PollingConsumer(inputChannel, handler1);
|
||||
PollingConsumer endpoint2 = new PollingConsumer(inputChannel, handler2);
|
||||
context.registerEndpoint("testEndpoint1", endpoint1);
|
||||
context.registerEndpoint("testEndpoint2", endpoint2);
|
||||
context.refresh();
|
||||
inputChannel.send(new StringMessage("testing"));
|
||||
Message<?> message1 = outputChannel1.receive(3000);
|
||||
Message<?> message2 = outputChannel2.receive(0);
|
||||
context.stop();
|
||||
assertTrue("exactly one message should be null", message1 == null ^ message2 == null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bothConsumersReceivePublishSubscribeMessage() throws InterruptedException {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
PublishSubscribeChannel inputChannel = new PublishSubscribeChannel();
|
||||
QueueChannel outputChannel1 = new QueueChannel();
|
||||
QueueChannel outputChannel2 = new QueueChannel();
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
AbstractReplyProducingMessageHandler handler1 = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
latch.countDown();
|
||||
return message;
|
||||
}
|
||||
};
|
||||
AbstractReplyProducingMessageHandler handler2 = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
latch.countDown();
|
||||
return message;
|
||||
}
|
||||
};
|
||||
context.registerChannel("input", inputChannel);
|
||||
context.registerChannel("output1", outputChannel1);
|
||||
context.registerChannel("output2", outputChannel2);
|
||||
handler1.setOutputChannel(outputChannel1);
|
||||
handler2.setOutputChannel(outputChannel2);
|
||||
EventDrivenConsumer endpoint1 = new EventDrivenConsumer(inputChannel, handler1);
|
||||
EventDrivenConsumer endpoint2 = new EventDrivenConsumer(inputChannel, handler2);
|
||||
context.registerEndpoint("testEndpoint1", endpoint1);
|
||||
context.registerEndpoint("testEndpoint2", endpoint2);
|
||||
context.refresh();
|
||||
inputChannel.send(new StringMessage("testing"));
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("both handlers should have been invoked", 0, latch.getCount());
|
||||
Message<?> message1 = outputChannel1.receive(500);
|
||||
Message<?> message2 = outputChannel2.receive(500);
|
||||
context.stop();
|
||||
assertNotNull("both handlers should have replied to the message", message1);
|
||||
assertNotNull("both handlers should have replied to the message", message2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void errorChannelWithFailedDispatch() throws InterruptedException {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
QueueChannel errorChannel = new QueueChannel();
|
||||
QueueChannel outputChannel = new QueueChannel();
|
||||
context.registerChannel("errorChannel", errorChannel);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
SourcePollingChannelAdapter channelAdapter = new SourcePollingChannelAdapter();
|
||||
channelAdapter.setSource(new FailingSource(latch));
|
||||
channelAdapter.setTrigger(new PeriodicTrigger(1000));
|
||||
channelAdapter.setOutputChannel(outputChannel);
|
||||
context.registerEndpoint("testChannel", channelAdapter);
|
||||
context.refresh();
|
||||
latch.await(2000, TimeUnit.MILLISECONDS);
|
||||
Message<?> message = errorChannel.receive(5000);
|
||||
context.stop();
|
||||
assertNull(outputChannel.receive(100));
|
||||
assertNotNull("message should not be null", message);
|
||||
assertTrue(message instanceof ErrorMessage);
|
||||
Throwable exception = ((ErrorMessage) message).getPayload();
|
||||
assertEquals("intentional test failure", exception.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void consumerSubscribedToErrorChannel() throws InterruptedException {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
QueueChannel errorChannel = new QueueChannel();
|
||||
context.registerChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, errorChannel);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
latch.countDown();
|
||||
return null;
|
||||
}
|
||||
};
|
||||
PollingConsumer endpoint = new PollingConsumer(errorChannel, handler);
|
||||
context.registerEndpoint("testEndpoint", endpoint);
|
||||
context.refresh();
|
||||
errorChannel.send(new ErrorMessage(new RuntimeException("test-exception")));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have received error message", 0, latch.getCount());
|
||||
context.stop();
|
||||
}
|
||||
|
||||
|
||||
private static class FailingSource implements MessageSource<Object> {
|
||||
|
||||
private CountDownLatch latch;
|
||||
|
||||
public FailingSource(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
public Message<Object> receive() {
|
||||
latch.countDown();
|
||||
throw new RuntimeException("intentional test failure");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.bus;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.annotation.MessageEndpoint;
|
||||
import org.springframework.integration.annotation.ServiceActivator;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.channel.ThreadLocalChannel;
|
||||
import org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessagingException;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.handler.ServiceActivatingHandler;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.test.util.TestUtils.TestApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DirectChannelSubscriptionTests {
|
||||
|
||||
private TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
|
||||
private DirectChannel sourceChannel = new DirectChannel();
|
||||
|
||||
private ThreadLocalChannel targetChannel = new ThreadLocalChannel();
|
||||
|
||||
|
||||
@Before
|
||||
public void setupChannels() {
|
||||
context.registerChannel("sourceChannel", sourceChannel);
|
||||
context.registerChannel("targetChannel", targetChannel);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void sendAndReceiveForRegisteredEndpoint() {
|
||||
TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
ServiceActivatingHandler serviceActivator = new ServiceActivatingHandler(new TestBean(), "handle");
|
||||
serviceActivator.setOutputChannel(targetChannel);
|
||||
EventDrivenConsumer endpoint = new EventDrivenConsumer(sourceChannel, serviceActivator);
|
||||
context.registerEndpoint("testEndpoint", endpoint);
|
||||
context.refresh();
|
||||
this.sourceChannel.send(new StringMessage("foo"));
|
||||
Message<?> response = this.targetChannel.receive();
|
||||
assertEquals("foo!", response.getPayload());
|
||||
context.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendAndReceiveForAnnotatedEndpoint() {
|
||||
MessagingAnnotationPostProcessor postProcessor = new MessagingAnnotationPostProcessor();
|
||||
postProcessor.setBeanFactory(context.getBeanFactory());
|
||||
postProcessor.afterPropertiesSet();
|
||||
TestEndpoint endpoint = new TestEndpoint();
|
||||
postProcessor.postProcessAfterInitialization(endpoint, "testEndpoint");
|
||||
context.refresh();
|
||||
this.sourceChannel.send(new StringMessage("foo"));
|
||||
Message<?> response = this.targetChannel.receive();
|
||||
assertEquals("foo-from-annotated-endpoint", response.getPayload());
|
||||
context.stop();
|
||||
}
|
||||
|
||||
@Test(expected = MessagingException.class)
|
||||
public void exceptionThrownFromRegisteredEndpoint() {
|
||||
AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
throw new RuntimeException("intentional test failure");
|
||||
}
|
||||
};
|
||||
handler.setOutputChannel(targetChannel);
|
||||
EventDrivenConsumer endpoint = new EventDrivenConsumer(sourceChannel, handler);
|
||||
context.registerEndpoint("testEndpoint", endpoint);
|
||||
context.refresh();
|
||||
try {
|
||||
this.sourceChannel.send(new StringMessage("foo"));
|
||||
}
|
||||
finally {
|
||||
context.stop();
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = MessagingException.class)
|
||||
public void exceptionThrownFromAnnotatedEndpoint() {
|
||||
QueueChannel errorChannel = new QueueChannel();
|
||||
context.registerChannel(IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, errorChannel);
|
||||
MessagingAnnotationPostProcessor postProcessor = new MessagingAnnotationPostProcessor();
|
||||
postProcessor.setBeanFactory(context.getBeanFactory());
|
||||
postProcessor.afterPropertiesSet();
|
||||
FailingTestEndpoint endpoint = new FailingTestEndpoint();
|
||||
postProcessor.postProcessAfterInitialization(endpoint, "testEndpoint");
|
||||
context.refresh();
|
||||
try {
|
||||
this.sourceChannel.send(new StringMessage("foo"));
|
||||
}
|
||||
finally {
|
||||
context.stop();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static class TestBean {
|
||||
|
||||
public Message<?> handle(Message<?> message) {
|
||||
return new StringMessage(message.getPayload() + "!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MessageEndpoint
|
||||
public static class TestEndpoint {
|
||||
|
||||
@ServiceActivator(inputChannel="sourceChannel", outputChannel="targetChannel")
|
||||
public Message<?> handle(Message<?> message) {
|
||||
return new StringMessage(message.getPayload() + "-from-annotated-endpoint");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@MessageEndpoint
|
||||
public static class FailingTestEndpoint {
|
||||
|
||||
@ServiceActivator(inputChannel="sourceChannel", outputChannel="targetChannel")
|
||||
public Message<?> handle(Message<?> message) {
|
||||
throw new RuntimeException("intentional test failure");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?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">
|
||||
|
||||
<bean id="taskScheduler" class="org.springframework.integration.test.util.TestUtils"
|
||||
factory-method="createTaskScheduler">
|
||||
<constructor-arg value="10"/>
|
||||
</bean>
|
||||
|
||||
<bean id="sourceChannel" class="org.springframework.integration.channel.QueueChannel"/>
|
||||
|
||||
<bean id="targetChannel" class="org.springframework.integration.channel.QueueChannel"/>
|
||||
|
||||
<bean id="endpoint" class="org.springframework.integration.endpoint.PollingConsumer">
|
||||
<constructor-arg ref="sourceChannel"/>
|
||||
<constructor-arg ref="serviceActivator"/>
|
||||
<property name="trigger">
|
||||
<bean class="org.springframework.scheduling.support.PeriodicTrigger">
|
||||
<constructor-arg value="100"/>
|
||||
</bean>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="serviceActivator" class="org.springframework.integration.handler.ServiceActivatingHandler">
|
||||
<constructor-arg ref="handler"/>
|
||||
<property name="outputChannel" ref="targetChannel"/>
|
||||
</bean>
|
||||
|
||||
<bean id="handler" class="org.springframework.integration.message.TestHandlers" factory-method="echoHandler"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class BeanFactoryChannelResolverTests {
|
||||
|
||||
@Test
|
||||
public void lookupRegisteredChannel() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
QueueChannel testChannel = new QueueChannel();
|
||||
testChannel.setBeanName("testChannel");
|
||||
context.getBeanFactory().registerSingleton("testChannel", testChannel);
|
||||
BeanFactoryChannelResolver resolver = new BeanFactoryChannelResolver(context);
|
||||
MessageChannel lookedUpChannel = resolver.resolveChannelName("testChannel");
|
||||
assertNotNull(testChannel);
|
||||
assertSame(testChannel, lookedUpChannel);
|
||||
}
|
||||
|
||||
@Test(expected = ChannelResolutionException.class)
|
||||
public void lookupNonRegisteredChannel() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
BeanFactoryChannelResolver resolver = new BeanFactoryChannelResolver(context);
|
||||
resolver.resolveChannelName("noSuchChannel");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.selector.MessageSelector;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ChannelPurgerTests {
|
||||
|
||||
@Test
|
||||
public void testPurgeAllWithoutSelector() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test1"));
|
||||
channel.send(new StringMessage("test2"));
|
||||
channel.send(new StringMessage("test3"));
|
||||
ChannelPurger purger = new ChannelPurger(channel);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(3, purgedMessages.size());
|
||||
assertNull(channel.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurgeAllWithSelector() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test1"));
|
||||
channel.send(new StringMessage("test2"));
|
||||
channel.send(new StringMessage("test3"));
|
||||
ChannelPurger purger = new ChannelPurger(new MessageSelector() {
|
||||
public boolean accept(Message<?> message) {
|
||||
return false;
|
||||
}
|
||||
}, channel);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(3, purgedMessages.size());
|
||||
assertNull(channel.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurgeNoneWithSelector() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test1"));
|
||||
channel.send(new StringMessage("test2"));
|
||||
channel.send(new StringMessage("test3"));
|
||||
ChannelPurger purger = new ChannelPurger(new MessageSelector() {
|
||||
public boolean accept(Message<?> message) {
|
||||
return true;
|
||||
}
|
||||
}, channel);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(0, purgedMessages.size());
|
||||
assertNotNull(channel.receive(0));
|
||||
assertNotNull(channel.receive(0));
|
||||
assertNotNull(channel.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurgeSubsetWithSelector() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test1"));
|
||||
channel.send(new StringMessage("test2"));
|
||||
channel.send(new StringMessage("test3"));
|
||||
ChannelPurger purger = new ChannelPurger(new MessageSelector() {
|
||||
public boolean accept(Message<?> message) {
|
||||
return (message.getPayload().equals("test2"));
|
||||
}
|
||||
}, channel);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(2, purgedMessages.size());
|
||||
Message<?> message = channel.receive(0);
|
||||
assertNotNull(message);
|
||||
assertEquals("test2", message.getPayload());
|
||||
assertNull(channel.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleChannelsWithNoSelector() {
|
||||
QueueChannel channel1 = new QueueChannel();
|
||||
QueueChannel channel2 = new QueueChannel();
|
||||
channel1.send(new StringMessage("test1"));
|
||||
channel1.send(new StringMessage("test2"));
|
||||
channel2.send(new StringMessage("test1"));
|
||||
channel2.send(new StringMessage("test2"));
|
||||
ChannelPurger purger = new ChannelPurger(channel1, channel2);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(4, purgedMessages.size());
|
||||
assertNull(channel1.receive(0));
|
||||
assertNull(channel2.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleChannelsWithSelector() {
|
||||
QueueChannel channel1 = new QueueChannel();
|
||||
QueueChannel channel2 = new QueueChannel();
|
||||
channel1.send(new StringMessage("test1"));
|
||||
channel1.send(new StringMessage("test2"));
|
||||
channel1.send(new StringMessage("test3"));
|
||||
channel2.send(new StringMessage("test1"));
|
||||
channel2.send(new StringMessage("test2"));
|
||||
channel2.send(new StringMessage("test3"));
|
||||
ChannelPurger purger = new ChannelPurger(new MessageSelector() {
|
||||
public boolean accept(Message<?> message) {
|
||||
return (message.getPayload().equals("test2"));
|
||||
}
|
||||
}, channel1, channel2);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(4, purgedMessages.size());
|
||||
Message<?> message1 = channel1.receive(0);
|
||||
assertNotNull(message1);
|
||||
assertEquals("test2", message1.getPayload());
|
||||
assertNull(channel1.receive(0));
|
||||
Message<?> message2 = channel2.receive(0);
|
||||
assertNotNull(message2);
|
||||
assertEquals("test2", message2.getPayload());
|
||||
assertNull(channel2.receive(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurgeNoneWithSelectorAndMultipleChannels() {
|
||||
QueueChannel channel1 = new QueueChannel();
|
||||
QueueChannel channel2 = new QueueChannel();
|
||||
channel1.send(new StringMessage("test1"));
|
||||
channel1.send(new StringMessage("test2"));
|
||||
channel2.send(new StringMessage("test1"));
|
||||
channel2.send(new StringMessage("test2"));
|
||||
ChannelPurger purger = new ChannelPurger(new MessageSelector() {
|
||||
public boolean accept(Message<?> message) {
|
||||
return true;
|
||||
}
|
||||
}, channel1, channel2);
|
||||
List<Message<?>> purgedMessages = purger.purge();
|
||||
assertEquals(0, purgedMessages.size());
|
||||
assertNotNull(channel1.receive(0));
|
||||
assertNotNull(channel1.receive(0));
|
||||
assertNotNull(channel2.receive(0));
|
||||
assertNotNull(channel2.receive(0));
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullChannel() {
|
||||
QueueChannel channel = null;
|
||||
new ChannelPurger(channel);
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testEmptyChannelArray() {
|
||||
QueueChannel[] channels = new QueueChannel[0];
|
||||
new ChannelPurger(channels);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.context.support.ConversionServiceFactoryBean;
|
||||
import org.springframework.context.support.GenericApplicationContext;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.convert.support.ConversionServiceFactory;
|
||||
import org.springframework.core.convert.support.GenericConversionService;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.core.MessagingException;
|
||||
import org.springframework.integration.message.ErrorMessage;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.MessageDeliveryException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 2.0
|
||||
*/
|
||||
public class DatatypeChannelTests {
|
||||
|
||||
@Test
|
||||
public void supportedType() {
|
||||
MessageChannel channel = createChannel(String.class);
|
||||
assertTrue(channel.send(new StringMessage("test")));
|
||||
}
|
||||
|
||||
@Test(expected = MessageDeliveryException.class)
|
||||
public void unsupportedTypeAndNoConversionService() {
|
||||
MessageChannel channel = createChannel(Integer.class);
|
||||
channel.send(new StringMessage("123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unsupportedTypeButConversionServiceSupports() {
|
||||
QueueChannel channel = createChannel(Integer.class);
|
||||
ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
channel.setConversionService(conversionService);
|
||||
assertTrue(channel.send(new StringMessage("123")));
|
||||
}
|
||||
|
||||
@Test(expected = MessageDeliveryException.class)
|
||||
public void unsupportedTypeAndConversionServiceDoesNotSupport() {
|
||||
QueueChannel channel = createChannel(Integer.class);
|
||||
ConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
channel.setConversionService(conversionService);
|
||||
assertTrue(channel.send(new GenericMessage<Boolean>(Boolean.TRUE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void unsupportedTypeButCustomConversionServiceSupports() {
|
||||
QueueChannel channel = createChannel(Integer.class);
|
||||
GenericConversionService conversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
conversionService.addConverter(new Converter<Boolean, Integer>() {
|
||||
public Integer convert(Boolean source) {
|
||||
return source ? 1 : 0;
|
||||
}
|
||||
});
|
||||
channel.setConversionService(conversionService);
|
||||
assertTrue(channel.send(new GenericMessage<Boolean>(Boolean.TRUE)));
|
||||
assertEquals(new Integer(1), channel.receive().getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversionServiceBeanUsedByDefault() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
Converter<Boolean, Integer> converter = new Converter<Boolean, Integer>() {
|
||||
public Integer convert(Boolean source) {
|
||||
return source ? 1 : 0;
|
||||
}
|
||||
};
|
||||
BeanDefinitionBuilder conversionServiceBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(ConversionServiceFactoryBean.class);
|
||||
conversionServiceBuilder.addPropertyValue("converters", Collections.singleton(converter));
|
||||
context.registerBeanDefinition(IntegrationContextUtils.INTEGRATION_CONVERSION_SERVICE_BEAN_NAME,
|
||||
conversionServiceBuilder.getBeanDefinition());
|
||||
BeanDefinitionBuilder channelBuilder = BeanDefinitionBuilder.genericBeanDefinition(QueueChannel.class);
|
||||
channelBuilder.addPropertyValue("datatypes", "java.lang.Integer, java.util.Date");
|
||||
context.registerBeanDefinition("testChannel", channelBuilder.getBeanDefinition());
|
||||
QueueChannel channel = context.getBean("testChannel", QueueChannel.class);
|
||||
assertTrue(channel.send(new GenericMessage<Boolean>(Boolean.TRUE)));
|
||||
assertEquals(new Integer(1), channel.receive().getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void conversionServiceReferenceOverridesDefault() {
|
||||
GenericApplicationContext context = new GenericApplicationContext();
|
||||
Converter<Boolean, Integer> defaultConverter = new Converter<Boolean, Integer>() {
|
||||
public Integer convert(Boolean source) {
|
||||
return source ? 1 : 0;
|
||||
}
|
||||
};
|
||||
GenericConversionService customConversionService = ConversionServiceFactory.createDefaultConversionService();
|
||||
customConversionService.addConverter(new Converter<Boolean, Integer>() {
|
||||
public Integer convert(Boolean source) {
|
||||
return source ? 99 : -99;
|
||||
}
|
||||
});
|
||||
BeanDefinitionBuilder conversionServiceBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(ConversionServiceFactoryBean.class);
|
||||
conversionServiceBuilder.addPropertyValue("converters", Collections.singleton(defaultConverter));
|
||||
context.registerBeanDefinition("conversionService", conversionServiceBuilder.getBeanDefinition());
|
||||
BeanDefinitionBuilder channelBuilder = BeanDefinitionBuilder.genericBeanDefinition(QueueChannel.class);
|
||||
channelBuilder.addPropertyValue("datatypes", "java.lang.Integer, java.util.Date");
|
||||
channelBuilder.addPropertyValue("conversionService", customConversionService);
|
||||
context.registerBeanDefinition("testChannel", channelBuilder.getBeanDefinition());
|
||||
QueueChannel channel = context.getBean("testChannel", QueueChannel.class);
|
||||
assertTrue(channel.send(new GenericMessage<Boolean>(Boolean.TRUE)));
|
||||
assertEquals(new Integer(99), channel.receive().getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleTypes() {
|
||||
MessageChannel channel = createChannel(String.class, Integer.class);
|
||||
assertTrue(channel.send(new StringMessage("test1")));
|
||||
assertTrue(channel.send(new GenericMessage<Integer>(2)));
|
||||
Exception exception = null;
|
||||
try {
|
||||
channel.send(new GenericMessage<Date>(new Date()));
|
||||
}
|
||||
catch (MessageDeliveryException e) {
|
||||
exception = e;
|
||||
}
|
||||
assertNotNull(exception);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void subclassOfAcceptedType() {
|
||||
MessageChannel channel = createChannel(RuntimeException.class);
|
||||
assertTrue(channel.send(new ErrorMessage(new MessagingException("test"))));
|
||||
}
|
||||
|
||||
@Test(expected = MessageDeliveryException.class)
|
||||
public void superclassOfAcceptedTypeNotAccepted() {
|
||||
MessageChannel channel = createChannel(RuntimeException.class);
|
||||
channel.send(new ErrorMessage(new Exception("test")));
|
||||
}
|
||||
|
||||
|
||||
private static QueueChannel createChannel(Class<?> ... datatypes) {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.setBeanName("testChannel");
|
||||
channel.setDatatypes(datatypes);
|
||||
return channel;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DirectChannelParserTests {
|
||||
|
||||
@Test
|
||||
public void testReceivesMessageFromChannelWithSource() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"directChannelParserTests.xml", DirectChannelParserTests.class);
|
||||
Object channel = context.getBean("channel");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageHandler;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class DirectChannelTests {
|
||||
|
||||
@Test
|
||||
public void testSend() {
|
||||
DirectChannel channel = new DirectChannel();
|
||||
ThreadNameExtractingTestTarget target = new ThreadNameExtractingTestTarget();
|
||||
channel.subscribe(target);
|
||||
StringMessage message = new StringMessage("test");
|
||||
assertTrue(channel.send(message));
|
||||
assertEquals(Thread.currentThread().getName(), target.threadName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendInSeparateThread() throws InterruptedException {
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
final DirectChannel channel = new DirectChannel();
|
||||
ThreadNameExtractingTestTarget target = new ThreadNameExtractingTestTarget(latch);
|
||||
channel.subscribe(target);
|
||||
final StringMessage message = new StringMessage("test");
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
channel.send(message);
|
||||
}
|
||||
}, "test-thread").start();
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
assertEquals("test-thread", target.threadName);
|
||||
}
|
||||
|
||||
|
||||
private static class ThreadNameExtractingTestTarget implements MessageHandler {
|
||||
|
||||
private String threadName;
|
||||
|
||||
private final CountDownLatch latch;
|
||||
|
||||
|
||||
ThreadNameExtractingTestTarget() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
ThreadNameExtractingTestTarget(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
public void handleMessage(Message<?> message) {
|
||||
this.threadName = Thread.currentThread().getName();
|
||||
if (this.latch != null) {
|
||||
this.latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotSame;
|
||||
import static org.junit.Assert.assertSame;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.StaticApplicationContext;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessagingException;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageDeliveryException;
|
||||
import org.springframework.integration.message.MessageHandler;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 1.0.3
|
||||
*/
|
||||
public class DispatchingChannelErrorHandlingTests {
|
||||
|
||||
private final CountDownLatch latch = new CountDownLatch(1);
|
||||
|
||||
|
||||
@Test(expected = MessageDeliveryException.class)
|
||||
public void handlerThrowsExceptionPublishSubscribeWithoutExecutor() {
|
||||
PublishSubscribeChannel channel = new PublishSubscribeChannel();
|
||||
channel.subscribe(new MessageHandler() {
|
||||
public void handleMessage(Message<?> message) {
|
||||
throw new UnsupportedOperationException("intentional test failure");
|
||||
}
|
||||
});
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
channel.send(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlerThrowsExceptionPublishSubscribeWithExecutor() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
context.registerSingleton(
|
||||
IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, DirectChannel.class);
|
||||
context.refresh();
|
||||
DirectChannel defaultErrorChannel = (DirectChannel) context.getBean(
|
||||
IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
|
||||
TaskExecutor executor = new SimpleAsyncTaskExecutor();
|
||||
PublishSubscribeChannel channel = new PublishSubscribeChannel(executor);
|
||||
channel.setBeanFactory(context);
|
||||
channel.afterPropertiesSet();
|
||||
ResultHandler resultHandler = new ResultHandler();
|
||||
defaultErrorChannel.subscribe(resultHandler);
|
||||
channel.subscribe(new MessageHandler() {
|
||||
public void handleMessage(Message<?> message) {
|
||||
throw new MessagingException(message,
|
||||
new UnsupportedOperationException("intentional test failure"));
|
||||
}
|
||||
});
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
channel.send(message);
|
||||
this.waitForLatch(1000);
|
||||
Message<?> errorMessage = resultHandler.lastMessage;
|
||||
assertEquals(MessagingException.class, errorMessage.getPayload().getClass());
|
||||
MessagingException exceptionPayload = (MessagingException) errorMessage.getPayload();
|
||||
assertEquals(UnsupportedOperationException.class, exceptionPayload.getCause().getClass());
|
||||
assertSame(message, exceptionPayload.getFailedMessage());
|
||||
assertNotSame(Thread.currentThread(), resultHandler.lastThread);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlerThrowsExceptionExecutorChannel() {
|
||||
StaticApplicationContext context = new StaticApplicationContext();
|
||||
context.registerSingleton(
|
||||
IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME, DirectChannel.class);
|
||||
context.refresh();
|
||||
DirectChannel defaultErrorChannel = (DirectChannel) context.getBean(
|
||||
IntegrationContextUtils.ERROR_CHANNEL_BEAN_NAME);
|
||||
TaskExecutor executor = new SimpleAsyncTaskExecutor();
|
||||
ExecutorChannel channel = new ExecutorChannel(executor);
|
||||
channel.setBeanFactory(context);
|
||||
channel.afterPropertiesSet();
|
||||
ResultHandler resultHandler = new ResultHandler();
|
||||
defaultErrorChannel.subscribe(resultHandler);
|
||||
channel.subscribe(new MessageHandler() {
|
||||
public void handleMessage(Message<?> message) {
|
||||
throw new MessagingException(message,
|
||||
new UnsupportedOperationException("intentional test failure"));
|
||||
}
|
||||
});
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
channel.send(message);
|
||||
this.waitForLatch(1000);
|
||||
Message<?> errorMessage = resultHandler.lastMessage;
|
||||
assertEquals(MessagingException.class, errorMessage.getPayload().getClass());
|
||||
MessagingException exceptionPayload = (MessagingException) errorMessage.getPayload();
|
||||
assertEquals(UnsupportedOperationException.class, exceptionPayload.getCause().getClass());
|
||||
assertSame(message, exceptionPayload.getFailedMessage());
|
||||
assertNotSame(Thread.currentThread(), resultHandler.lastThread);
|
||||
}
|
||||
|
||||
|
||||
private void waitForLatch(long timeout) {
|
||||
try {
|
||||
this.latch.await(timeout, TimeUnit.MILLISECONDS);
|
||||
if (latch.getCount() != 0) {
|
||||
throw new TestTimedOutException();
|
||||
}
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
throw new RuntimeException("interrupted while waiting for latch");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class ResultHandler implements MessageHandler {
|
||||
|
||||
private volatile Message<?> lastMessage;
|
||||
|
||||
private volatile Thread lastThread;
|
||||
|
||||
public void handleMessage(Message<?> message) {
|
||||
this.lastMessage = message;
|
||||
this.lastThread = Thread.currentThread();
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
private static class TestTimedOutException extends RuntimeException {
|
||||
|
||||
public TestTimedOutException() {
|
||||
super("timed out while waiting for latch");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,184 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
|
||||
import org.springframework.integration.message.MessageHandler;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
||||
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ExecutorChannelTests {
|
||||
|
||||
@Test
|
||||
public void verifyDifferentThread() throws Exception {
|
||||
SimpleAsyncTaskExecutor taskExecutor = new SimpleAsyncTaskExecutor();
|
||||
taskExecutor.setThreadNamePrefix("test-");
|
||||
ExecutorChannel channel = new ExecutorChannel(taskExecutor);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
TestHandler handler = new TestHandler(latch);
|
||||
channel.subscribe(handler);
|
||||
channel.send(new StringMessage("test"));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
assertEquals(0, latch.getCount());
|
||||
assertNotNull(handler.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler.thread));
|
||||
assertEquals("test-1", handler.thread.getName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundRobinLoadBalancing() throws Exception {
|
||||
int numberOfMessages = 11;
|
||||
ConcurrentTaskExecutor taskExecutor = new ConcurrentTaskExecutor(
|
||||
Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("test-")));
|
||||
ExecutorChannel channel = new ExecutorChannel(
|
||||
taskExecutor, new RoundRobinLoadBalancingStrategy());
|
||||
CountDownLatch latch = new CountDownLatch(numberOfMessages);
|
||||
TestHandler handler1 = new TestHandler(latch);
|
||||
TestHandler handler2 = new TestHandler(latch);
|
||||
TestHandler handler3 = new TestHandler(latch);
|
||||
channel.subscribe(handler1);
|
||||
channel.subscribe(handler2);
|
||||
channel.subscribe(handler3);
|
||||
for (int i = 0; i < numberOfMessages; i++) {
|
||||
channel.send(new StringMessage("test-" + i));
|
||||
}
|
||||
latch.await(3000, TimeUnit.MILLISECONDS);
|
||||
assertEquals(0, latch.getCount());
|
||||
assertNotNull(handler1.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler1.thread));
|
||||
assertTrue(handler1.thread.getName().startsWith("test-"));
|
||||
assertNotNull(handler2.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler2.thread));
|
||||
assertTrue(handler2.thread.getName().startsWith("test-"));
|
||||
assertNotNull(handler3.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler3.thread));
|
||||
assertTrue(handler3.thread.getName().startsWith("test-"));
|
||||
assertEquals(4, handler1.count.get());
|
||||
assertEquals(4, handler2.count.get());
|
||||
assertEquals(3, handler3.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyFailoverWithLoadBalancing() throws Exception {
|
||||
int numberOfMessages = 11;
|
||||
ConcurrentTaskExecutor taskExecutor = new ConcurrentTaskExecutor(
|
||||
Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("test-")));
|
||||
ExecutorChannel channel = new ExecutorChannel(
|
||||
taskExecutor, new RoundRobinLoadBalancingStrategy());
|
||||
CountDownLatch latch = new CountDownLatch(numberOfMessages);
|
||||
TestHandler handler1 = new TestHandler(latch);
|
||||
TestHandler handler2 = new TestHandler(latch);
|
||||
TestHandler handler3 = new TestHandler(latch);
|
||||
channel.subscribe(handler1);
|
||||
channel.subscribe(handler2);
|
||||
channel.subscribe(handler3);
|
||||
handler2.shouldFail = true;
|
||||
for (int i = 0; i < numberOfMessages; i++) {
|
||||
channel.send(new StringMessage("test-" + i));
|
||||
}
|
||||
latch.await(3000, TimeUnit.MILLISECONDS);
|
||||
assertEquals(0, latch.getCount());
|
||||
assertNotNull(handler1.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler1.thread));
|
||||
assertTrue(handler1.thread.getName().startsWith("test-"));
|
||||
assertNotNull(handler2.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler2.thread));
|
||||
assertTrue(handler2.thread.getName().startsWith("test-"));
|
||||
assertNotNull(handler3.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler3.thread));
|
||||
assertTrue(handler3.thread.getName().startsWith("test-"));
|
||||
assertEquals(0, handler2.count.get());
|
||||
assertEquals(4, handler1.count.get());
|
||||
assertEquals(7, handler3.count.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyFailoverWithoutLoadBalancing() throws Exception {
|
||||
int numberOfMessages = 11;
|
||||
ConcurrentTaskExecutor taskExecutor = new ConcurrentTaskExecutor(
|
||||
Executors.newSingleThreadScheduledExecutor(new CustomizableThreadFactory("test-")));
|
||||
ExecutorChannel channel = new ExecutorChannel(taskExecutor);
|
||||
CountDownLatch latch = new CountDownLatch(numberOfMessages);
|
||||
TestHandler handler1 = new TestHandler(latch);
|
||||
TestHandler handler2 = new TestHandler(latch);
|
||||
TestHandler handler3 = new TestHandler(latch);
|
||||
channel.subscribe(handler1);
|
||||
channel.subscribe(handler2);
|
||||
channel.subscribe(handler3);
|
||||
handler1.shouldFail = true;
|
||||
for (int i = 0; i < numberOfMessages; i++) {
|
||||
channel.send(new StringMessage("test-" + i));
|
||||
}
|
||||
latch.await(3000, TimeUnit.MILLISECONDS);
|
||||
assertEquals(0, latch.getCount());
|
||||
assertNotNull(handler1.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler1.thread));
|
||||
assertTrue(handler1.thread.getName().startsWith("test-"));
|
||||
assertNotNull(handler2.thread);
|
||||
assertFalse(Thread.currentThread().equals(handler2.thread));
|
||||
assertTrue(handler2.thread.getName().startsWith("test-"));
|
||||
assertNull(handler3.thread);
|
||||
assertEquals(0, handler1.count.get());
|
||||
assertEquals(0, handler3.count.get());
|
||||
assertEquals(numberOfMessages, handler2.count.get());
|
||||
}
|
||||
|
||||
|
||||
private static class TestHandler implements MessageHandler {
|
||||
|
||||
private final CountDownLatch latch;
|
||||
|
||||
private final AtomicInteger count = new AtomicInteger();
|
||||
|
||||
private volatile Thread thread;
|
||||
|
||||
private volatile boolean shouldFail;
|
||||
|
||||
public TestHandler(CountDownLatch latch) {
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
public void handleMessage(Message<?> message) {
|
||||
this.thread = Thread.currentThread();
|
||||
if (this.shouldFail) {
|
||||
throw new RuntimeException("intentional test failure");
|
||||
}
|
||||
this.count.incrementAndGet();
|
||||
this.latch.countDown();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MapBasedChannelResolverTests {
|
||||
|
||||
@Test
|
||||
public void mapContainsChannel() {
|
||||
MessageChannel testChannel = new QueueChannel();
|
||||
Map<String, MessageChannel> channelMap = new HashMap<String, MessageChannel>();
|
||||
channelMap.put("testChannel", testChannel);
|
||||
MapBasedChannelResolver resolver = new MapBasedChannelResolver();
|
||||
resolver.setChannelMap(channelMap);
|
||||
MessageChannel result = resolver.resolveChannelName("testChannel");
|
||||
assertNotNull(result);
|
||||
assertEquals(testChannel, result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapDoesNotContainChannel() {
|
||||
MessageChannel testChannel = new QueueChannel();
|
||||
Map<String, MessageChannel> channelMap = new HashMap<String, MessageChannel>();
|
||||
channelMap.put("testChannel", testChannel);
|
||||
MapBasedChannelResolver resolver = new MapBasedChannelResolver();
|
||||
resolver.setChannelMap(channelMap);
|
||||
MessageChannel result = resolver.resolveChannelName("noSuchChannel");
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyMap() {
|
||||
Map<String, MessageChannel> channelMap = new HashMap<String, MessageChannel>();
|
||||
MapBasedChannelResolver resolver = new MapBasedChannelResolver();
|
||||
resolver.setChannelMap(channelMap);
|
||||
MessageChannel result = resolver.resolveChannelName("testChannel");
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void nullMapRejected() {
|
||||
MapBasedChannelResolver resolver = new MapBasedChannelResolver();
|
||||
resolver.setChannelMap(null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.endpoint.PollingConsumer;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.test.util.TestUtils.TestApplicationContext;
|
||||
import org.springframework.scheduling.support.PeriodicTrigger;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MessageChannelTemplateTests {
|
||||
|
||||
private TestApplicationContext context = TestUtils.createTestApplicationContext();
|
||||
|
||||
private QueueChannel requestChannel;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.requestChannel = new QueueChannel();
|
||||
context.registerChannel("requestChannel", requestChannel);
|
||||
AbstractReplyProducingMessageHandler handler = new AbstractReplyProducingMessageHandler() {
|
||||
@Override
|
||||
public Object handleRequestMessage(Message<?> message) {
|
||||
return message.getPayload().toString().toUpperCase();
|
||||
}
|
||||
};
|
||||
PollingConsumer endpoint = new PollingConsumer(requestChannel, handler);
|
||||
endpoint.setTrigger(new PeriodicTrigger(10));
|
||||
context.registerEndpoint("testEndpoint", endpoint);
|
||||
context.refresh();
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
try {
|
||||
context.stop();
|
||||
}
|
||||
catch (Exception e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void send() {
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
QueueChannel channel = new QueueChannel();
|
||||
template.send(new StringMessage("test"), channel);
|
||||
Message<?> reply = channel.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendWithDefaultChannelProvidedBySetter() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.setDefaultChannel(channel);
|
||||
template.send(new StringMessage("test"));
|
||||
Message<?> reply = channel.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendWithDefaultChannelProvidedByConstructor() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
MessageChannelTemplate template = new MessageChannelTemplate(channel);
|
||||
template.send(new StringMessage("test"));
|
||||
Message<?> reply = channel.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendWithExplicitChannelTakesPrecedenceOverDefault() {
|
||||
QueueChannel explicitChannel = new QueueChannel();
|
||||
QueueChannel defaultChannel = new QueueChannel();
|
||||
MessageChannelTemplate template = new MessageChannelTemplate(defaultChannel);
|
||||
template.send(new StringMessage("test"), explicitChannel);
|
||||
Message<?> reply = explicitChannel.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("test", reply.getPayload());
|
||||
assertNull(defaultChannel.receive(0));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void sendWithoutChannelArgFailsIfNoDefaultAvailable() {
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.send(new StringMessage("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receive() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test"));
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
Message<?> reply = template.receive(channel);
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receiveWithDefaultChannelProvidedBySetter() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test"));
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.setDefaultChannel(channel);
|
||||
Message<?> reply = template.receive();
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receiveWithDefaultChannelProvidedByConstructor() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.send(new StringMessage("test"));
|
||||
MessageChannelTemplate template = new MessageChannelTemplate(channel);
|
||||
Message<?> reply = template.receive();
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void receiveWithExplicitChannelTakesPrecedenceOverDefault() {
|
||||
QueueChannel explicitChannel = new QueueChannel();
|
||||
QueueChannel defaultChannel = new QueueChannel();
|
||||
explicitChannel.send(new StringMessage("test"));
|
||||
MessageChannelTemplate template = new MessageChannelTemplate(defaultChannel);
|
||||
template.setReceiveTimeout(0);
|
||||
Message<?> reply = template.receive(explicitChannel);
|
||||
assertEquals("test", reply.getPayload());
|
||||
assertNull(template.receive());
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void receiveWithoutChannelArgFailsIfNoDefaultAvailable() {
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.receive();
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void receiveWithNonPollableDefaultFails() {
|
||||
DirectChannel channel = new DirectChannel();
|
||||
MessageChannelTemplate template = new MessageChannelTemplate(channel);
|
||||
template.receive();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendAndReceive() {
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.setReceiveTimeout(3000);
|
||||
Message<?> reply = template.sendAndReceive(new StringMessage("test"), this.requestChannel);
|
||||
assertEquals("TEST", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendAndReceiveWithDefaultChannel() {
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.setReceiveTimeout(3000);
|
||||
template.setDefaultChannel(this.requestChannel);
|
||||
Message<?> reply = template.sendAndReceive(new StringMessage("test"));
|
||||
assertEquals("TEST", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendAndReceiveWithExplicitChannelTakesPrecedenceOverDefault() {
|
||||
QueueChannel defaultChannel = new QueueChannel();
|
||||
MessageChannelTemplate template = new MessageChannelTemplate(defaultChannel);
|
||||
template.setReceiveTimeout(3000);
|
||||
Message<?> message = new StringMessage("test");
|
||||
Message<?> reply = template.sendAndReceive(message, this.requestChannel);
|
||||
assertEquals("TEST", reply.getPayload());
|
||||
assertNull(defaultChannel.receive(0));
|
||||
}
|
||||
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void sendAndReceiveWithoutChannelArgFailsIfNoDefaultAvailable() {
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
template.sendAndReceive(new StringMessage("test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sendWithReturnAddress() throws InterruptedException {
|
||||
final List<String> replies = new ArrayList<String>(3);
|
||||
final CountDownLatch latch = new CountDownLatch(3);
|
||||
MessageChannel replyChannel = new AbstractMessageChannel() {
|
||||
@Override
|
||||
protected boolean doSend(Message<?> message, long timeout) {
|
||||
replies.add((String) message.getPayload());
|
||||
latch.countDown();
|
||||
return true;
|
||||
}
|
||||
};
|
||||
MessageChannelTemplate template = new MessageChannelTemplate();
|
||||
Message<String> message1 = MessageBuilder.withPayload("test1").setReplyChannel(replyChannel).build();
|
||||
Message<String> message2 = MessageBuilder.withPayload("test2").setReplyChannel(replyChannel).build();
|
||||
Message<String> message3 = MessageBuilder.withPayload("test3").setReplyChannel(replyChannel).build();
|
||||
template.send(message1, this.requestChannel);
|
||||
template.send(message2, this.requestChannel);
|
||||
template.send(message3, this.requestChannel);
|
||||
latch.await(2000, TimeUnit.MILLISECONDS);
|
||||
assertEquals(0, latch.getCount());
|
||||
assertTrue(replies.contains("TEST1"));
|
||||
assertTrue(replies.contains("TEST2"));
|
||||
assertTrue(replies.contains("TEST3"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MessagePayloadTestComparator implements Comparator<Message<Comparable<Object>>> {
|
||||
|
||||
public int compare(Message<Comparable<Object>> message1, Message<Comparable<Object>> message2) {
|
||||
return message1.getPayload().compareTo(message2.getPayload());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:util="http://www.springframework.org/schema/util">
|
||||
|
||||
<channel id="noLoadBalancerNoFailover" >
|
||||
<dispatcher load-balancer="none" failover="false"/>
|
||||
</channel>
|
||||
<channel id="noLoadBalancerNoFailoverExecutor" >
|
||||
<dispatcher load-balancer="none" failover="false" task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
<channel id="loadBalancerNoFailover">
|
||||
<dispatcher load-balancer="round-robin" failover="false"/>
|
||||
</channel>
|
||||
<channel id="loadBalancerNoFailoverExecutor">
|
||||
<dispatcher load-balancer="round-robin" failover="false" task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
<channel id="noLoadBalancerFailover">
|
||||
<dispatcher load-balancer="none" failover="true"/>
|
||||
</channel>
|
||||
<channel id="noLoadBalancerFailoverExecutor">
|
||||
<dispatcher load-balancer="none" failover="true" task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
<beans:bean id="taskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor">
|
||||
<beans:property name="threadGroupName" value="dispatchers"/>
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,473 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.mockito.stubbing.Answer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
|
||||
import org.springframework.integration.dispatcher.UnicastingDispatcher;
|
||||
import org.springframework.integration.message.MessageHandler;
|
||||
import org.springframework.integration.message.MessageRejectedException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Matchers.anyObject;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MixedDispatcherConfigurationScenarioTests {
|
||||
|
||||
private static final int TOTAL_EXECUTIONS = 40;
|
||||
|
||||
private ThreadPoolTaskExecutor scheduler = new ThreadPoolTaskExecutor();
|
||||
|
||||
private CountDownLatch allDone;
|
||||
private CountDownLatch start;
|
||||
private AtomicBoolean failed;
|
||||
|
||||
@Mock
|
||||
private List<Exception> exceptionRegistry;
|
||||
|
||||
private ApplicationContext ac;
|
||||
|
||||
@Mock
|
||||
private MessageHandler handlerA;
|
||||
|
||||
@Mock
|
||||
private MessageHandler handlerB;
|
||||
|
||||
@Mock
|
||||
private MessageHandler handlerC;
|
||||
|
||||
private Message<?> message = new StringMessage("test");
|
||||
|
||||
|
||||
@Before
|
||||
public void initialize() throws Exception {
|
||||
ac = new ClassPathXmlApplicationContext("MixedDispatcherConfigurationScenarioTests-context.xml",
|
||||
MixedDispatcherConfigurationScenarioTests.class);
|
||||
allDone = new CountDownLatch(TOTAL_EXECUTIONS);
|
||||
start = new CountDownLatch(1);
|
||||
failed = new AtomicBoolean(false);
|
||||
scheduler.setCorePoolSize(10);
|
||||
scheduler.setMaxPoolSize(10);
|
||||
scheduler.initialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noFailoverNoLoadBalancing() {
|
||||
DirectChannel channel = (DirectChannel) ac.getBean("noLoadBalancerNoFailover");
|
||||
doThrow(new MessageRejectedException(message)).when(handlerA).handleMessage(message);
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
verify(handlerA, times(2)).handleMessage(message);
|
||||
verify(handlerB, times(0)).handleMessage(message);
|
||||
}
|
||||
|
||||
@Test(timeout = 5000)
|
||||
public void noFailoverNoLoadBalancingConcurrent() throws Exception {
|
||||
final DirectChannel channel = (DirectChannel) ac.getBean("noLoadBalancerNoFailover");
|
||||
doThrow(new MessageRejectedException(message)).when(handlerA).handleMessage(message);
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
|
||||
Runnable messageSenderTask = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
boolean sent = false;
|
||||
try {
|
||||
sent = channel.send(message);
|
||||
} catch (Exception e) {
|
||||
exceptionRegistry.add(e);
|
||||
}
|
||||
if (!sent) {
|
||||
failed.set(true);
|
||||
}
|
||||
allDone.countDown();
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < TOTAL_EXECUTIONS; i++) {
|
||||
scheduler.execute(messageSenderTask);
|
||||
}
|
||||
start.countDown();
|
||||
allDone.await();
|
||||
assertTrue("not all messages were accepted", failed.get());
|
||||
verify(handlerA, times(TOTAL_EXECUTIONS)).handleMessage(message);
|
||||
verify(handlerB, times(0)).handleMessage(message);
|
||||
verify(exceptionRegistry, times(TOTAL_EXECUTIONS)).add((Exception) anyObject());
|
||||
}
|
||||
|
||||
@Test(timeout = 5000)
|
||||
public void noFailoverNoLoadBalancingWithExecutorConcurrent()
|
||||
throws Exception {
|
||||
final ExecutorChannel channel = (ExecutorChannel) ac.getBean("noLoadBalancerNoFailoverExecutor");
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
RuntimeException e = new RuntimeException();
|
||||
allDone.countDown();
|
||||
failed.set(true);
|
||||
exceptionRegistry.add(e);
|
||||
throw e;
|
||||
}
|
||||
}).when(handlerA).handleMessage(message);
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
allDone.countDown();
|
||||
return null;
|
||||
}
|
||||
}).when(handlerB).handleMessage(message);
|
||||
|
||||
Runnable messageSenderTask = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
channel.send(message);
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < TOTAL_EXECUTIONS; i++) {
|
||||
scheduler.execute(messageSenderTask);
|
||||
}
|
||||
start.countDown();
|
||||
allDone.await();
|
||||
// Mockito threads might still be lingering, so wait till they are all finished to avoid
|
||||
// Mockito concurrency issues
|
||||
this.waitTillAllFinished((SimpleAsyncTaskExecutor) ac.getBean("taskExecutor"));
|
||||
assertTrue("not all messages were accepted", failed.get());
|
||||
verify(handlerA, times(TOTAL_EXECUTIONS)).handleMessage(message);
|
||||
verify(handlerB, times(0)).handleMessage(message);
|
||||
verify(exceptionRegistry, times(TOTAL_EXECUTIONS)).add((Exception) anyObject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noFailoverLoadBalancing() {
|
||||
DirectChannel channel = (DirectChannel) ac.getBean("loadBalancerNoFailover");
|
||||
doThrow(new MessageRejectedException(message)).when(handlerA).handleMessage(message);
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.setLoadBalancingStrategy(new RoundRobinLoadBalancingStrategy());
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
dispatcher.addHandler(handlerC);
|
||||
InOrder inOrder = inOrder(handlerA, handlerB, handlerC);
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
inOrder.verify(handlerA).handleMessage(message);
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
inOrder.verify(handlerB).handleMessage(message);
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
inOrder.verify(handlerC).handleMessage(message);
|
||||
|
||||
verify(handlerA, times(1)).handleMessage(message);
|
||||
verify(handlerB, times(1)).handleMessage(message);
|
||||
verify(handlerC, times(1)).handleMessage(message);
|
||||
}
|
||||
|
||||
@Test(timeout = 5000)
|
||||
public void noFailoverLoadBalancingConcurrent() throws Exception {
|
||||
final DirectChannel channel = (DirectChannel) ac.getBean("loadBalancerNoFailover");
|
||||
doThrow(new MessageRejectedException(message)).when(handlerA).handleMessage(message);
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
dispatcher.addHandler(handlerC);
|
||||
|
||||
final CountDownLatch start = new CountDownLatch(1);
|
||||
final CountDownLatch allDone = new CountDownLatch(TOTAL_EXECUTIONS);
|
||||
final Message<?> message = this.message;
|
||||
final AtomicBoolean failed = new AtomicBoolean(false);
|
||||
Runnable messageSenderTask = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
boolean sent = false;
|
||||
try {
|
||||
sent = channel.send(message);
|
||||
} catch (Exception e) {
|
||||
exceptionRegistry.add(e);
|
||||
}
|
||||
if (!sent) {
|
||||
failed.set(true);
|
||||
}
|
||||
allDone.countDown();
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < TOTAL_EXECUTIONS; i++) {
|
||||
scheduler.execute(messageSenderTask);
|
||||
}
|
||||
start.countDown();
|
||||
allDone.await();
|
||||
assertTrue("not all messages were accepted", failed.get());
|
||||
verify(handlerA, times(14)).handleMessage(message);
|
||||
verify(handlerB, times(13)).handleMessage(message);
|
||||
verify(handlerC, times(13)).handleMessage(message);
|
||||
verify(exceptionRegistry, times(14)).add((Exception) anyObject());
|
||||
}
|
||||
|
||||
@Test(timeout = 5000)
|
||||
public void noFailoverLoadBalancingWithExecutorConcurrent() throws Exception {
|
||||
final ExecutorChannel channel = (ExecutorChannel) ac.getBean("loadBalancerNoFailoverExecutor");
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
dispatcher.addHandler(handlerC);
|
||||
|
||||
final CountDownLatch start = new CountDownLatch(1);
|
||||
final CountDownLatch allDone = new CountDownLatch(TOTAL_EXECUTIONS);
|
||||
final Message<?> message = this.message;
|
||||
final AtomicBoolean failed = new AtomicBoolean(false);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
failed.set(true);
|
||||
RuntimeException e = new RuntimeException();
|
||||
exceptionRegistry.add(e);
|
||||
allDone.countDown();
|
||||
throw e;
|
||||
}
|
||||
}).when(handlerA).handleMessage(message);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
allDone.countDown();
|
||||
return null;
|
||||
}
|
||||
}).when(handlerB).handleMessage(message);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
allDone.countDown();
|
||||
return null;
|
||||
}
|
||||
}).when(handlerC).handleMessage(message);
|
||||
|
||||
Runnable messageSenderTask = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
channel.send(message);
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < TOTAL_EXECUTIONS; i++) {
|
||||
scheduler.execute(messageSenderTask);
|
||||
}
|
||||
start.countDown();
|
||||
allDone.await();
|
||||
// Mockito threads might still be lingering, so wait till they are all finished to avoid
|
||||
// Mockito concurrency
|
||||
this.waitTillAllFinished((SimpleAsyncTaskExecutor) ac.getBean("taskExecutor"));
|
||||
assertTrue("not all messages were accepted", failed.get());
|
||||
verify(handlerA, times(14)).handleMessage(message);
|
||||
verify(handlerB, times(13)).handleMessage(message);
|
||||
verify(handlerC, times(13)).handleMessage(message);
|
||||
verify(exceptionRegistry, times(14)).add((Exception) anyObject());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failoverNoLoadBalancing() {
|
||||
DirectChannel channel = (DirectChannel) ac
|
||||
.getBean("noLoadBalancerFailover");
|
||||
doThrow(new MessageRejectedException(message)).when(handlerA)
|
||||
.handleMessage(message);
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
InOrder inOrder = inOrder(handlerA, handlerB);
|
||||
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
inOrder.verify(handlerA).handleMessage(message);
|
||||
inOrder.verify(handlerB).handleMessage(message);
|
||||
|
||||
try {
|
||||
channel.send(message);
|
||||
} catch (Exception e) {/* ignore */
|
||||
}
|
||||
inOrder.verify(handlerA).handleMessage(message);
|
||||
inOrder.verify(handlerB).handleMessage(message);
|
||||
|
||||
verify(handlerA, times(2)).handleMessage(message);
|
||||
verify(handlerB, times(2)).handleMessage(message);
|
||||
}
|
||||
|
||||
@Test(timeout = 5000)
|
||||
public void failoverNoLoadBalancingConcurrent()
|
||||
throws Exception {
|
||||
final DirectChannel channel = (DirectChannel) ac
|
||||
.getBean("noLoadBalancerFailover");
|
||||
doThrow(new MessageRejectedException(message)).when(handlerA).handleMessage(message);
|
||||
UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
dispatcher.addHandler(handlerC);
|
||||
|
||||
final CountDownLatch start = new CountDownLatch(1);
|
||||
final CountDownLatch allDone = new CountDownLatch(TOTAL_EXECUTIONS);
|
||||
final Message<?> message = this.message;
|
||||
final AtomicBoolean failed = new AtomicBoolean(false);
|
||||
Runnable messageSenderTask = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
boolean sent = false;
|
||||
try {
|
||||
sent = channel.send(message);
|
||||
} catch (Exception e) {
|
||||
exceptionRegistry.add(e);
|
||||
}
|
||||
if (!sent) {
|
||||
failed.set(true);
|
||||
}
|
||||
allDone.countDown();
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < TOTAL_EXECUTIONS; i++) {
|
||||
scheduler.execute(messageSenderTask);
|
||||
}
|
||||
start.countDown();
|
||||
allDone.await();
|
||||
assertFalse("not all messages were accepted", failed.get());
|
||||
verify(handlerA, times(TOTAL_EXECUTIONS)).handleMessage(message);
|
||||
verify(handlerB, times(TOTAL_EXECUTIONS)).handleMessage(message);
|
||||
verify(handlerC, never()).handleMessage(message);
|
||||
verify(exceptionRegistry, never()).add((Exception) anyObject());
|
||||
}
|
||||
|
||||
@Test(timeout = 5000)
|
||||
public void failoverNoLoadBalancingWithExecutorConcurrent() throws Exception {
|
||||
final ExecutorChannel channel = (ExecutorChannel) ac.getBean("noLoadBalancerFailoverExecutor");
|
||||
final UnicastingDispatcher dispatcher = channel.getDispatcher();
|
||||
dispatcher.addHandler(handlerA);
|
||||
dispatcher.addHandler(handlerB);
|
||||
dispatcher.addHandler(handlerC);
|
||||
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
RuntimeException e = new RuntimeException();
|
||||
failed.set(true);
|
||||
allDone.countDown();
|
||||
throw e;
|
||||
}
|
||||
}).when(handlerA).handleMessage(message);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
allDone.countDown();
|
||||
return null;
|
||||
}
|
||||
}).when(handlerB).handleMessage(message);
|
||||
doAnswer(new Answer<Object>() {
|
||||
public Object answer(InvocationOnMock invocation) {
|
||||
allDone.countDown();
|
||||
return null;
|
||||
}
|
||||
}).when(handlerC).handleMessage(message);
|
||||
|
||||
Runnable messageSenderTask = new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
channel.send(message);
|
||||
}
|
||||
};
|
||||
for (int i = 0; i < TOTAL_EXECUTIONS; i++) {
|
||||
scheduler.execute(messageSenderTask);
|
||||
}
|
||||
start.countDown();
|
||||
allDone.await();
|
||||
// Mockito threads might still be lingering, so wait till they are all finished to avoid
|
||||
// Mockito concurrency
|
||||
this.waitTillAllFinished((SimpleAsyncTaskExecutor) ac.getBean("taskExecutor"));
|
||||
|
||||
verify(handlerA, times(TOTAL_EXECUTIONS)).handleMessage(message);
|
||||
verify(handlerB, times(TOTAL_EXECUTIONS)).handleMessage(message);
|
||||
verify(handlerC, never()).handleMessage(message);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param taskExecutor
|
||||
*/
|
||||
private void waitTillAllFinished(SimpleAsyncTaskExecutor taskExecutor){
|
||||
for (int i = 0; i < 1000; i++) {
|
||||
if (taskExecutor.getThreadGroup().activeCount() == 0){
|
||||
break;
|
||||
}
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {/*ignore*/}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Comparator;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessagePriority;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class PriorityChannelTests {
|
||||
|
||||
@Test
|
||||
public void testCapacityEnforced() {
|
||||
PriorityChannel channel = new PriorityChannel(3);
|
||||
assertTrue(channel.send(new StringMessage("test1"), 0));
|
||||
assertTrue(channel.send(new StringMessage("test2"), 0));
|
||||
assertTrue(channel.send(new StringMessage("test3"), 0));
|
||||
assertFalse(channel.send(new StringMessage("test4"), 0));
|
||||
channel.receive(0);
|
||||
assertTrue(channel.send(new StringMessage("test5")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultComparator() {
|
||||
PriorityChannel channel = new PriorityChannel(5);
|
||||
Message<?> priority1 = createPriorityMessage(MessagePriority.HIGHEST);
|
||||
Message<?> priority2 = createPriorityMessage(MessagePriority.HIGH);
|
||||
Message<?> priority3 = createPriorityMessage(MessagePriority.NORMAL);
|
||||
Message<?> priority4 = createPriorityMessage(MessagePriority.LOW);
|
||||
Message<?> priority5 = createPriorityMessage(MessagePriority.LOWEST);
|
||||
channel.send(priority4);
|
||||
channel.send(priority3);
|
||||
channel.send(priority5);
|
||||
channel.send(priority1);
|
||||
channel.send(priority2);
|
||||
assertEquals("test-HIGHEST", channel.receive(0).getPayload());
|
||||
assertEquals("test-HIGH", channel.receive(0).getPayload());
|
||||
assertEquals("test-NORMAL", channel.receive(0).getPayload());
|
||||
assertEquals("test-LOW", channel.receive(0).getPayload());
|
||||
assertEquals("test-LOWEST", channel.receive(0).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomComparator() {
|
||||
PriorityChannel channel = new PriorityChannel(5, new StringPayloadComparator());
|
||||
Message<?> messageA = new StringMessage("A");
|
||||
Message<?> messageB = new StringMessage("B");
|
||||
Message<?> messageC = new StringMessage("C");
|
||||
Message<?> messageD = new StringMessage("D");
|
||||
Message<?> messageE = new StringMessage("E");
|
||||
channel.send(messageC);
|
||||
channel.send(messageA);
|
||||
channel.send(messageE);
|
||||
channel.send(messageD);
|
||||
channel.send(messageB);
|
||||
assertEquals("A", channel.receive(0).getPayload());
|
||||
assertEquals("B", channel.receive(0).getPayload());
|
||||
assertEquals("C", channel.receive(0).getPayload());
|
||||
assertEquals("D", channel.receive(0).getPayload());
|
||||
assertEquals("E", channel.receive(0).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullPriorityIsConsideredNormal() {
|
||||
PriorityChannel channel = new PriorityChannel(5);
|
||||
Message<?> highPriority = createPriorityMessage(MessagePriority.HIGH);
|
||||
Message<?> lowPriority = createPriorityMessage(MessagePriority.LOW);
|
||||
Message<?> nullPriority = new StringMessage("test-NULL");
|
||||
channel.send(lowPriority);
|
||||
channel.send(highPriority);
|
||||
channel.send(nullPriority);
|
||||
assertEquals("test-HIGH", channel.receive(0).getPayload());
|
||||
assertEquals("test-NULL", channel.receive(0).getPayload());
|
||||
assertEquals("test-LOW", channel.receive(0).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUnboundedCapacity() {
|
||||
PriorityChannel channel = new PriorityChannel();
|
||||
Message<?> highPriority = createPriorityMessage(MessagePriority.HIGH);
|
||||
Message<?> lowPriority = createPriorityMessage(MessagePriority.LOW);
|
||||
Message<?> nullPriority = new StringMessage("test-NULL");
|
||||
channel.send(lowPriority);
|
||||
channel.send(highPriority);
|
||||
channel.send(nullPriority);
|
||||
assertEquals("test-HIGH", channel.receive(0).getPayload());
|
||||
assertEquals("test-NULL", channel.receive(0).getPayload());
|
||||
assertEquals("test-LOW", channel.receive(0).getPayload());
|
||||
}
|
||||
|
||||
|
||||
private static Message<String> createPriorityMessage(MessagePriority priority) {
|
||||
return MessageBuilder.withPayload("test-" + priority).setPriority(priority).build();
|
||||
}
|
||||
|
||||
|
||||
public static class StringPayloadComparator implements Comparator<Message<?>> {
|
||||
|
||||
public int compare(Message<?> message1, Message<?> message2) {
|
||||
String s1 = (String) message1.getPayload();
|
||||
String s2 = (String) message2.getPayload();
|
||||
return s1.compareTo(s2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.selector.UnexpiredMessageSelector;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class QueueChannelTests {
|
||||
|
||||
@Test
|
||||
public void testSimpleSendAndReceive() throws Exception {
|
||||
final AtomicBoolean messageReceived = new AtomicBoolean(false);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
final QueueChannel channel = new QueueChannel();
|
||||
new Thread(new Runnable() {
|
||||
public void run() {
|
||||
Message<?> message = channel.receive();
|
||||
if (message != null) {
|
||||
messageReceived.set(true);
|
||||
latch.countDown();
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
assertFalse(messageReceived.get());
|
||||
channel.send(new GenericMessage<String>("testing"));
|
||||
latch.await(25, TimeUnit.MILLISECONDS);
|
||||
assertTrue(messageReceived.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediateReceive() throws Exception {
|
||||
final AtomicBoolean messageReceived = new AtomicBoolean(false);
|
||||
final QueueChannel channel = new QueueChannel();
|
||||
final CountDownLatch latch1 = new CountDownLatch(1);
|
||||
final CountDownLatch latch2 = new CountDownLatch(1);
|
||||
Executor singleThreadExecutor = Executors.newSingleThreadExecutor();
|
||||
Runnable receiveTask1 = new Runnable() {
|
||||
public void run() {
|
||||
Message<?> message = channel.receive(0);
|
||||
if (message != null) {
|
||||
messageReceived.set(true);
|
||||
}
|
||||
latch1.countDown();
|
||||
}
|
||||
};
|
||||
Runnable sendTask = new Runnable() {
|
||||
public void run() {
|
||||
channel.send(new GenericMessage<String>("testing"));
|
||||
}
|
||||
};
|
||||
singleThreadExecutor.execute(receiveTask1);
|
||||
latch1.await();
|
||||
singleThreadExecutor.execute(sendTask);
|
||||
assertFalse(messageReceived.get());
|
||||
Runnable receiveTask2 = new Runnable() {
|
||||
public void run() {
|
||||
Message<?> message = channel.receive(0);
|
||||
if (message != null) {
|
||||
messageReceived.set(true);
|
||||
}
|
||||
latch2.countDown();
|
||||
}
|
||||
};
|
||||
singleThreadExecutor.execute(receiveTask2);
|
||||
latch2.await();
|
||||
assertTrue(messageReceived.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingReceiveWithNoTimeout() throws Exception{
|
||||
final QueueChannel channel = new QueueChannel();
|
||||
final AtomicBoolean receiveInterrupted = new AtomicBoolean(false);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
Message<?> message = channel.receive();
|
||||
receiveInterrupted.set(true);
|
||||
assertTrue(message == null);
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
assertFalse(receiveInterrupted.get());
|
||||
t.interrupt();
|
||||
latch.await();
|
||||
assertTrue(receiveInterrupted.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingReceiveWithTimeout() throws Exception{
|
||||
final QueueChannel channel = new QueueChannel();
|
||||
final AtomicBoolean receiveInterrupted = new AtomicBoolean(false);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
Message<?> message = channel.receive(10000);
|
||||
receiveInterrupted.set(true);
|
||||
assertTrue(message == null);
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
assertFalse(receiveInterrupted.get());
|
||||
t.interrupt();
|
||||
latch.await();
|
||||
assertTrue(receiveInterrupted.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testImmediateSend() {
|
||||
QueueChannel channel = new QueueChannel(3);
|
||||
boolean result1 = channel.send(new GenericMessage<String>("test-1"));
|
||||
assertTrue(result1);
|
||||
boolean result2 = channel.send(new GenericMessage<String>("test-2"), 100);
|
||||
assertTrue(result2);
|
||||
boolean result3 = channel.send(new GenericMessage<String>("test-3"), 0);
|
||||
assertTrue(result3);
|
||||
boolean result4 = channel.send(new GenericMessage<String>("test-4"), 0);
|
||||
assertFalse(result4);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingSendWithNoTimeout() throws Exception{
|
||||
final QueueChannel channel = new QueueChannel(1);
|
||||
boolean result1 = channel.send(new GenericMessage<String>("test-1"));
|
||||
assertTrue(result1);
|
||||
final AtomicBoolean sendInterrupted = new AtomicBoolean(false);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
channel.send(new GenericMessage<String>("test-2"));
|
||||
sendInterrupted.set(true);
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
assertFalse(sendInterrupted.get());
|
||||
t.interrupt();
|
||||
latch.await();
|
||||
assertTrue(sendInterrupted.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockingSendWithTimeout() throws Exception{
|
||||
final QueueChannel channel = new QueueChannel(1);
|
||||
boolean result1 = channel.send(new GenericMessage<String>("test-1"));
|
||||
assertTrue(result1);
|
||||
final AtomicBoolean sendInterrupted = new AtomicBoolean(false);
|
||||
final CountDownLatch latch = new CountDownLatch(1);
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
channel.send(new GenericMessage<String>("test-2"), 10000);
|
||||
sendInterrupted.set(true);
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
assertFalse(sendInterrupted.get());
|
||||
t.interrupt();
|
||||
latch.await();
|
||||
assertTrue(sendInterrupted.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClear() {
|
||||
QueueChannel channel = new QueueChannel(2);
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
StringMessage message3 = new StringMessage("test3");
|
||||
assertTrue(channel.send(message1));
|
||||
assertTrue(channel.send(message2));
|
||||
assertFalse(channel.send(message3, 0));
|
||||
List<Message<?>> clearedMessages = channel.clear();
|
||||
assertNotNull(clearedMessages);
|
||||
assertEquals(2, clearedMessages.size());
|
||||
assertTrue(channel.send(message3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClearEmptyChannel() {
|
||||
QueueChannel channel = new QueueChannel();
|
||||
List<Message<?>> clearedMessages = channel.clear();
|
||||
assertNotNull(clearedMessages);
|
||||
assertEquals(0, clearedMessages.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPurge() {
|
||||
QueueChannel channel = new QueueChannel(2);
|
||||
long minute = 60 * 1000;
|
||||
long time = System.currentTimeMillis();
|
||||
long past = time - minute;
|
||||
long future = time + minute;
|
||||
Message<String> expiredMessage = MessageBuilder.withPayload("test1")
|
||||
.setExpirationDate(past).build();
|
||||
Message<String> unexpiredMessage = MessageBuilder.withPayload("test2")
|
||||
.setExpirationDate(future).build();
|
||||
assertTrue(channel.send(expiredMessage, 0));
|
||||
assertTrue(channel.send(unexpiredMessage, 0));
|
||||
assertFalse(channel.send(new StringMessage("atCapacity"), 0));
|
||||
List<Message<?>> purgedMessages = channel.purge(new UnexpiredMessageSelector());
|
||||
assertNotNull(purgedMessages);
|
||||
assertEquals(1, purgedMessages.size());
|
||||
assertTrue(channel.send(new StringMessage("roomAvailable"), 0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class TestChannelResolver implements ChannelResolver {
|
||||
|
||||
private volatile Map<String, MessageChannel> channels = new ConcurrentHashMap<String, MessageChannel>();
|
||||
|
||||
|
||||
public MessageChannel resolveChannelName(String channelName) {
|
||||
return this.channels.get(channelName);
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setChannels(Map<String, MessageChannel> channels) {
|
||||
this.channels = channels;
|
||||
}
|
||||
|
||||
public void addChannel(String name, MessageChannel channel) {
|
||||
Assert.notNull(name, "name must not be null");
|
||||
Assert.notNull(channel, "channel must not be null");
|
||||
this.channels.put(name, channel);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.channel;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ThreadLocalChannelTests {
|
||||
|
||||
@Before
|
||||
public void clearThreadLocalQueue() {
|
||||
ThreadLocalChannel channel = new ThreadLocalChannel();
|
||||
Message<?> result = null;
|
||||
do {
|
||||
result = channel.receive(0);
|
||||
} while (result != null);
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testSendAndReceive() {
|
||||
ThreadLocalChannel channel = new ThreadLocalChannel();
|
||||
StringMessage message = new StringMessage("test");
|
||||
assertNull(channel.receive());
|
||||
assertTrue(channel.send(message));
|
||||
Message<?> response = channel.receive();
|
||||
assertNotNull(response);
|
||||
assertEquals(response, message);
|
||||
assertNull(channel.receive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSendAndReceiveMultipleMessages() {
|
||||
ThreadLocalChannel channel = new ThreadLocalChannel();
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
assertNull(channel.receive());
|
||||
assertTrue(channel.send(message1));
|
||||
assertTrue(channel.send(message2));
|
||||
List<Message<?>> receivedMessages = new ArrayList<Message<?>>();
|
||||
receivedMessages.add(channel.receive(0));
|
||||
receivedMessages.add(channel.receive(0));
|
||||
assertEquals(2, receivedMessages.size());
|
||||
assertEquals(message1, receivedMessages.get(0));
|
||||
assertEquals(message2, receivedMessages.get(1));
|
||||
assertNull(channel.receive());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleThreadLocalChannels() throws Exception {
|
||||
final ThreadLocalChannel channel1 = new ThreadLocalChannel();
|
||||
final ThreadLocalChannel channel2 = new ThreadLocalChannel();
|
||||
channel1.send(new StringMessage("test-1.1"));
|
||||
channel1.send(new StringMessage("test-1.2"));
|
||||
channel1.send(new StringMessage("test-1.3"));
|
||||
channel2.send(new StringMessage("test-2.1"));
|
||||
channel2.send(new StringMessage("test-2.2"));
|
||||
Executor otherThreadExecutor = Executors.newSingleThreadExecutor();
|
||||
final List<Object> otherThreadResults = new ArrayList<Object>();
|
||||
final CountDownLatch latch = new CountDownLatch(2);
|
||||
otherThreadExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
otherThreadResults.add(channel1.receive(0));
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
otherThreadExecutor.execute(new Runnable() {
|
||||
public void run() {
|
||||
otherThreadResults.add(channel2.receive(0));
|
||||
latch.countDown();
|
||||
}
|
||||
});
|
||||
latch.await(1, TimeUnit.SECONDS);
|
||||
assertEquals(2, otherThreadResults.size());
|
||||
assertNull(otherThreadResults.get(0));
|
||||
assertNull(otherThreadResults.get(1));
|
||||
assertEquals("test-1.1", channel1.receive(0).getPayload());
|
||||
assertEquals("test-1.2", channel1.receive(0).getPayload());
|
||||
assertEquals("test-1.3", channel1.receive(0).getPayload());
|
||||
assertNull(channel1.receive(0));
|
||||
assertEquals("test-2.1", channel2.receive(0).getPayload());
|
||||
assertEquals("test-2.2", channel2.receive(0).getPayload());
|
||||
assertNull(channel2.receive(0));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<transformer id="transformer"
|
||||
input-channel="input"
|
||||
output-channel="output">
|
||||
<beans:bean class="org.springframework.integration.channel.config.TestTransformer"/>
|
||||
</transformer>
|
||||
|
||||
<channel id="output">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class AutoGeneratedChannelTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void checkConfig() {
|
||||
Object input = context.getBean("input");
|
||||
assertNotNull(input);
|
||||
assertEquals(DirectChannel.class, input.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xmlns:context="http://www.springframework.org/schema/context"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/context
|
||||
http://www.springframework.org/schema/context/spring-context.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<context:property-placeholder
|
||||
location="/org/springframework/integration/channel/config/ChannelCapacityPlaceholderTests.properties"/>
|
||||
|
||||
<gateway id="gateway"
|
||||
service-interface="org.springframework.integration.channel.config.ChannelCapacityPlaceholderTests$TestService"/>
|
||||
|
||||
<channel id="channel">
|
||||
<queue capacity="${capacity}"/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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.channel.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class ChannelCapacityPlaceholderTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Test
|
||||
public void verifyCapacityValueChanges() {
|
||||
QueueChannel channel = context.getBean("channel", QueueChannel.class);
|
||||
assertNotNull(channel);
|
||||
assertEquals(99, channel.getRemainingCapacity());
|
||||
channel.send(MessageBuilder.withPayload("test1").build());
|
||||
channel.send(MessageBuilder.withPayload("test2").build());
|
||||
assertEquals(97, channel.getRemainingCapacity());
|
||||
assertNotNull(channel.receive(0));
|
||||
assertEquals(98, channel.getRemainingCapacity());
|
||||
}
|
||||
|
||||
|
||||
public static interface TestService {
|
||||
|
||||
@org.springframework.integration.annotation.Gateway(requestChannel="channel")
|
||||
void test();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
capacity=99
|
||||
@@ -0,0 +1,266 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel.config;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.config.TestChannelInterceptor;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.core.MessagePriority;
|
||||
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
|
||||
import org.springframework.integration.dispatcher.UnicastingDispatcher;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageDeliveryException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.util.ErrorHandlingTaskExecutor;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Iwein Fuld
|
||||
*
|
||||
* @see ChannelWithCustomQueueParserTests
|
||||
*/
|
||||
public class ChannelParserTests {
|
||||
|
||||
@Test(expected = FatalBeanException.class)
|
||||
public void testChannelWithoutId() {
|
||||
new ClassPathXmlApplicationContext("channelWithoutId.xml", this.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChannelWithCapacity() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("capacityChannel");
|
||||
for (int i = 0; i < 10; i++) {
|
||||
boolean result = channel.send(new GenericMessage<String>("test"), 10);
|
||||
assertTrue(result);
|
||||
}
|
||||
assertFalse(channel.send(new GenericMessage<String>("test"), 3));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDirectChannelByDefault() throws InterruptedException {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("defaultChannel");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
Object dispatcher = accessor.getPropertyValue("dispatcher");
|
||||
assertThat(dispatcher, is(UnicastingDispatcher.class));
|
||||
assertThat(new DirectFieldAccessor(dispatcher).getPropertyValue("loadBalancingStrategy"),
|
||||
is(RoundRobinLoadBalancingStrategy.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelWithFailoverDispatcherAttribute() throws Exception {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("channelWithFailoverAttribute");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
Object dispatcher = accessor.getPropertyValue("dispatcher");
|
||||
assertThat(dispatcher, is(UnicastingDispatcher.class));
|
||||
assertNull(new DirectFieldAccessor(dispatcher).getPropertyValue("loadBalancingStrategy"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublishSubscribeChannel() throws InterruptedException {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("publishSubscribeChannel");
|
||||
assertEquals(PublishSubscribeChannel.class, channel.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPublishSubscribeChannelWithTaskExecutorReference() throws InterruptedException {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("publishSubscribeChannelWithTaskExecutorRef");
|
||||
assertEquals(PublishSubscribeChannel.class, channel.getClass());
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
accessor = new DirectFieldAccessor(accessor.getPropertyValue("dispatcher"));
|
||||
Object executorProperty = accessor.getPropertyValue("executor");
|
||||
assertNotNull(executorProperty);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executorProperty.getClass());
|
||||
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executorProperty);
|
||||
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
|
||||
Object executorBean = context.getBean("taskExecutor");
|
||||
assertEquals(executorBean, innerExecutor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelWithCustomQueue() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"channelParserTests.xml", this.getClass());
|
||||
Object customQueue = context.getBean("customQueue");
|
||||
Object channelWithCustomQueue = context.getBean("channelWithCustomQueue");
|
||||
assertEquals(QueueChannel.class, channelWithCustomQueue.getClass());
|
||||
Object actualQueue = new DirectFieldAccessor(channelWithCustomQueue).getPropertyValue("queue");
|
||||
assertSame(customQueue, actualQueue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDatatypeChannelWithCorrectType() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("integerChannel");
|
||||
assertTrue(channel.send(new GenericMessage<Integer>(123)));
|
||||
}
|
||||
|
||||
@Test(expected = MessageDeliveryException.class)
|
||||
public void testDatatypeChannelWithIncorrectType() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("integerChannel");
|
||||
channel.send(new StringMessage("incorrect type"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDatatypeChannelWithAssignableSubTypes() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("numberChannel");
|
||||
assertTrue(channel.send(new GenericMessage<Integer>(123)));
|
||||
assertTrue(channel.send(new GenericMessage<Double>(123.45)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleDatatypeChannelWithCorrectTypes() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("stringOrNumberChannel");
|
||||
assertTrue(channel.send(new GenericMessage<Integer>(123)));
|
||||
assertTrue(channel.send(new StringMessage("accepted type")));
|
||||
}
|
||||
|
||||
@Test(expected = MessageDeliveryException.class)
|
||||
public void testMultipleDatatypeChannelWithIncorrectType() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("channelParserTests.xml", this
|
||||
.getClass());
|
||||
MessageChannel channel = (MessageChannel) context.getBean("stringOrNumberChannel");
|
||||
channel.send(new GenericMessage<Boolean>(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChannelInteceptorRef() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("channelInterceptorParserTests.xml", this
|
||||
.getClass());
|
||||
PollableChannel channel = (PollableChannel) context.getBean("channelWithInterceptorRef");
|
||||
TestChannelInterceptor interceptor = (TestChannelInterceptor) context.getBean("interceptor");
|
||||
assertEquals(0, interceptor.getSendCount());
|
||||
channel.send(new StringMessage("test"));
|
||||
assertEquals(1, interceptor.getSendCount());
|
||||
assertEquals(0, interceptor.getReceiveCount());
|
||||
channel.receive();
|
||||
assertEquals(1, interceptor.getReceiveCount());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testChannelInteceptorInnerBean() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("channelInterceptorParserTests.xml", this
|
||||
.getClass());
|
||||
PollableChannel channel = (PollableChannel) context.getBean("channelWithInterceptorInnerBean");
|
||||
channel.send(new StringMessage("test"));
|
||||
Message<?> transformed = channel.receive(1000);
|
||||
assertEquals("TEST", transformed.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriorityChannelWithDefaultComparator() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("priorityChannelParserTests.xml", this
|
||||
.getClass());
|
||||
PollableChannel channel = (PollableChannel) context.getBean("priorityChannelWithDefaultComparator");
|
||||
Message<String> lowPriorityMessage = MessageBuilder.withPayload("low").setPriority(MessagePriority.LOW).build();
|
||||
Message<String> midPriorityMessage = MessageBuilder.withPayload("mid").setPriority(MessagePriority.NORMAL)
|
||||
.build();
|
||||
Message<String> highPriorityMessage = MessageBuilder.withPayload("high").setPriority(MessagePriority.HIGH)
|
||||
.build();
|
||||
channel.send(lowPriorityMessage);
|
||||
channel.send(highPriorityMessage);
|
||||
channel.send(midPriorityMessage);
|
||||
Message<?> reply1 = channel.receive(0);
|
||||
Message<?> reply2 = channel.receive(0);
|
||||
Message<?> reply3 = channel.receive(0);
|
||||
assertEquals("high", reply1.getPayload());
|
||||
assertEquals("mid", reply2.getPayload());
|
||||
assertEquals("low", reply3.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriorityChannelWithCustomComparator() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("priorityChannelParserTests.xml", this
|
||||
.getClass());
|
||||
PollableChannel channel = (PollableChannel) context.getBean("priorityChannelWithCustomComparator");
|
||||
channel.send(new StringMessage("C"));
|
||||
channel.send(new StringMessage("A"));
|
||||
channel.send(new StringMessage("D"));
|
||||
channel.send(new StringMessage("B"));
|
||||
Message<?> reply1 = channel.receive(0);
|
||||
Message<?> reply2 = channel.receive(0);
|
||||
Message<?> reply3 = channel.receive(0);
|
||||
Message<?> reply4 = channel.receive(0);
|
||||
assertEquals("A", reply1.getPayload());
|
||||
assertEquals("B", reply2.getPayload());
|
||||
assertEquals("C", reply3.getPayload());
|
||||
assertEquals("D", reply4.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPriorityChannelWithIntegerDatatypeEnforced() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext("priorityChannelParserTests.xml", this
|
||||
.getClass());
|
||||
PollableChannel channel = (PollableChannel) context.getBean("integerOnlyPriorityChannel");
|
||||
channel.send(new GenericMessage<Integer>(3));
|
||||
channel.send(new GenericMessage<Integer>(2));
|
||||
channel.send(new GenericMessage<Integer>(1));
|
||||
assertEquals(1, channel.receive(0).getPayload());
|
||||
assertEquals(2, channel.receive(0).getPayload());
|
||||
assertEquals(3, channel.receive(0).getPayload());
|
||||
boolean threwException = false;
|
||||
try {
|
||||
channel.send(new StringMessage("wrong type"));
|
||||
}
|
||||
catch (MessageDeliveryException e) {
|
||||
assertEquals("wrong type", e.getFailedMessage().getPayload());
|
||||
threwException = true;
|
||||
}
|
||||
assertTrue(threwException);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="customQueueChannel">
|
||||
<queue ref="queue" />
|
||||
</channel>
|
||||
|
||||
<beans:bean id="queue" class="java.util.concurrent.ArrayBlockingQueue">
|
||||
<beans:constructor-arg value="2" />
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.config;
|
||||
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.hamcrest.CoreMatchers.*;
|
||||
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* Testcases for detailed namespace support for <queue/> element under
|
||||
* <channel/>
|
||||
*
|
||||
* @author Iwein Fuld
|
||||
*
|
||||
* @see ChannelWithCustomQueueParserTests
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class ChannelWithCustomQueueParserTests {
|
||||
|
||||
@Qualifier("customQueueChannel")
|
||||
@Autowired
|
||||
QueueChannel customQueueChannel;
|
||||
|
||||
@Test
|
||||
public void parseConfig() throws Exception {
|
||||
assertNotNull(customQueueChannel);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void queueTypeSet() throws Exception {
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(customQueueChannel);
|
||||
Object queue = accessor.getPropertyValue("queue");
|
||||
assertNotNull(queue);
|
||||
assertThat(queue, is(ArrayBlockingQueue.class));
|
||||
assertThat(((BlockingQueue<?>)queue).remainingCapacity(), is(2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="dispatcherAttribute" dispatcher="failover"/>
|
||||
|
||||
<channel id="taskExecutorOnly">
|
||||
<dispatcher task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
<channel id="failoverFalse">
|
||||
<dispatcher failover="false"/>
|
||||
</channel>
|
||||
|
||||
<channel id="failoverTrue">
|
||||
<dispatcher failover="true"/>
|
||||
</channel>
|
||||
|
||||
<channel id="loadBalancerDisabled">
|
||||
<dispatcher load-balancer="none"/>
|
||||
</channel>
|
||||
|
||||
<channel id="loadBalancerDisabledAndTaskExecutor">
|
||||
<dispatcher load-balancer="none" task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
<channel id="roundRobinLoadBalancerAndTaskExecutor">
|
||||
<dispatcher load-balancer="round-robin" task-executor="taskExecutor"/>
|
||||
</channel>
|
||||
|
||||
<beans:bean id="taskExecutor"
|
||||
class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.FatalBeanException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.ExecutorChannel;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.dispatcher.RoundRobinLoadBalancingStrategy;
|
||||
import org.springframework.integration.util.ErrorHandlingTaskExecutor;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @since 1.0.3
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class DispatchingChannelParserTests {
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Autowired
|
||||
private Map<String, MessageChannel> channels;
|
||||
|
||||
|
||||
@Test(expected = FatalBeanException.class)
|
||||
public void dispatcherAttributeAndSubElement() {
|
||||
new ClassPathXmlApplicationContext("dispatcherAttributeAndSubElement.xml", this.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void dispatcherAttribute() {
|
||||
MessageChannel channel = channels.get("dispatcherAttribute");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
assertTrue((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertNull(getDispatcherProperty("loadBalancingStrategy", channel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void taskExecutorOnly() {
|
||||
MessageChannel channel = channels.get("taskExecutorOnly");
|
||||
assertEquals(ExecutorChannel.class, channel.getClass());
|
||||
Object executor = getDispatcherProperty("executor", channel);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executor.getClass());
|
||||
assertSame(context.getBean("taskExecutor"),
|
||||
new DirectFieldAccessor(executor).getPropertyValue("executor"));
|
||||
assertTrue((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertEquals(RoundRobinLoadBalancingStrategy.class,
|
||||
getDispatcherProperty("loadBalancingStrategy", channel).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failoverFalse() {
|
||||
MessageChannel channel = channels.get("failoverFalse");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
assertFalse((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertEquals(RoundRobinLoadBalancingStrategy.class,
|
||||
getDispatcherProperty("loadBalancingStrategy", channel).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void failoverTrue() {
|
||||
MessageChannel channel = channels.get("failoverTrue");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
assertTrue((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertEquals(RoundRobinLoadBalancingStrategy.class,
|
||||
getDispatcherProperty("loadBalancingStrategy", channel).getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadBalancerDisabled() {
|
||||
MessageChannel channel = channels.get("loadBalancerDisabled");
|
||||
assertEquals(DirectChannel.class, channel.getClass());
|
||||
assertTrue((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertNull(getDispatcherProperty("loadBalancingStrategy", channel));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loadBalancerDisabledAndTaskExecutor() {
|
||||
MessageChannel channel = channels.get("loadBalancerDisabledAndTaskExecutor");
|
||||
assertEquals(ExecutorChannel.class, channel.getClass());
|
||||
assertTrue((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertNull(getDispatcherProperty("loadBalancingStrategy", channel));
|
||||
Object executor = getDispatcherProperty("executor", channel);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executor.getClass());
|
||||
assertSame(context.getBean("taskExecutor"),
|
||||
new DirectFieldAccessor(executor).getPropertyValue("executor"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void roundRobinLoadBalancerAndTaskExecutor() {
|
||||
MessageChannel channel = channels.get("roundRobinLoadBalancerAndTaskExecutor");
|
||||
assertEquals(ExecutorChannel.class, channel.getClass());
|
||||
assertTrue((Boolean) getDispatcherProperty("failover", channel));
|
||||
assertEquals(RoundRobinLoadBalancingStrategy.class,
|
||||
getDispatcherProperty("loadBalancingStrategy", channel).getClass());
|
||||
Object executor = getDispatcherProperty("executor", channel);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executor.getClass());
|
||||
assertSame(context.getBean("taskExecutor"),
|
||||
new DirectFieldAccessor(executor).getPropertyValue("executor"));
|
||||
}
|
||||
|
||||
|
||||
private static Object getDispatcherProperty(String propertyName, MessageChannel channel) {
|
||||
return new DirectFieldAccessor(
|
||||
new DirectFieldAccessor(channel).getPropertyValue("dispatcher"))
|
||||
.getPropertyValue(propertyName);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.RendezvousChannel;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class RendezvousChannelParserTests {
|
||||
|
||||
@Test
|
||||
public void testRendezvous() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"rendezvousChannelParserTests.xml", RendezvousChannelParserTests.class);
|
||||
MessageChannel channel = (MessageChannel) context.getBean("channel");
|
||||
assertEquals(RendezvousChannel.class, channel.getClass());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.config;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageSource;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class TestSource implements MessageSource<String> {
|
||||
|
||||
private final String text;
|
||||
|
||||
|
||||
public TestSource(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public Message<String> receive() {
|
||||
return new StringMessage(this.text);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.config;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.transformer.Transformer;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class TestTransformer implements Transformer {
|
||||
|
||||
public Message<?> transform(Message<?> message) {
|
||||
return MessageBuilder.withPayload(message.getPayload().toString().toUpperCase()).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<thread-local-channel id="simpleChannel"/>
|
||||
|
||||
<thread-local-channel id="channelWithInterceptor">
|
||||
<interceptors>
|
||||
<beans:ref bean="interceptor"/>
|
||||
</interceptors>
|
||||
</thread-local-channel>
|
||||
|
||||
<beans:bean id="interceptor" class="org.springframework.integration.config.TestChannelInterceptor"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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.channel.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.ThreadLocalChannel;
|
||||
import org.springframework.integration.config.TestChannelInterceptor;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class ThreadLocalChannelParserTests {
|
||||
|
||||
@Autowired @Qualifier("simpleChannel")
|
||||
private MessageChannel simpleChannel;
|
||||
|
||||
@Autowired @Qualifier("channelWithInterceptor")
|
||||
private MessageChannel channelWithInterceptor;
|
||||
|
||||
@Autowired
|
||||
private TestChannelInterceptor interceptor;
|
||||
|
||||
|
||||
@Test
|
||||
public void checkType() {
|
||||
assertEquals(ThreadLocalChannel.class, simpleChannel.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void verifyInterceptor() {
|
||||
assertEquals(0, interceptor.getSendCount());
|
||||
channelWithInterceptor.send(new StringMessage("test"));
|
||||
assertEquals(1, interceptor.getSendCount());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="channelWithInterceptorRef">
|
||||
<queue capacity="5"/>
|
||||
<interceptors>
|
||||
<ref bean="interceptor"/>
|
||||
</interceptors>
|
||||
</channel>
|
||||
|
||||
<channel id="channelWithInterceptorInnerBean">
|
||||
<queue capacity="5"/>
|
||||
<interceptors>
|
||||
<beans:bean class="org.springframework.integration.transformer.MessageTransformingChannelInterceptor">
|
||||
<beans:constructor-arg>
|
||||
<beans:bean class="org.springframework.integration.channel.config.TestTransformer"/>
|
||||
</beans:constructor-arg>
|
||||
</beans:bean>
|
||||
</interceptors>
|
||||
</channel>
|
||||
|
||||
<beans:bean id="interceptor" class="org.springframework.integration.config.TestChannelInterceptor"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,43 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="capacityChannel">
|
||||
<queue capacity="10" />
|
||||
</channel>
|
||||
|
||||
<channel id="defaultChannel" />
|
||||
|
||||
<channel id="channelWithFailoverAttribute" dispatcher="failover"/>
|
||||
|
||||
<channel id="channelWithCustomQueue">
|
||||
<queue ref="customQueue"/>
|
||||
</channel>
|
||||
|
||||
<beans:bean id="customQueue" class="java.util.concurrent.LinkedBlockingQueue"/>
|
||||
|
||||
<publish-subscribe-channel id="publishSubscribeChannel" />
|
||||
|
||||
<publish-subscribe-channel id="publishSubscribeChannelWithTaskExecutorRef"
|
||||
task-executor="taskExecutor" />
|
||||
|
||||
<channel id="integerChannel" datatype="java.lang.Integer">
|
||||
<queue capacity="10" />
|
||||
</channel>
|
||||
|
||||
<channel id="numberChannel" datatype="java.lang.Number">
|
||||
<queue capacity="10" />
|
||||
</channel>
|
||||
|
||||
<channel id="stringOrNumberChannel" datatype="java.lang.String,java.lang.Number">
|
||||
<queue capacity="10" />
|
||||
</channel>
|
||||
|
||||
<beans:bean id="taskExecutor"
|
||||
class="org.springframework.core.task.SimpleAsyncTaskExecutor" />
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?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:integration="http://www.springframework.org/schema/integration"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<integration:channel/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="dispatcherAttributeAndSubElement" dispatcher="failover">
|
||||
<dispatcher/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="priorityChannelWithDefaultComparator">
|
||||
<priority-queue capacity="10"/>
|
||||
</channel>
|
||||
|
||||
<channel id="priorityChannelWithCustomComparator">
|
||||
<priority-queue capacity="10" comparator="payloadComparator"/>
|
||||
</channel>
|
||||
|
||||
<channel id="integerOnlyPriorityChannel" datatype="java.lang.Integer">
|
||||
<priority-queue capacity="10" comparator="payloadComparator"/>
|
||||
</channel>
|
||||
|
||||
<beans:bean id="payloadComparator"
|
||||
class="org.springframework.integration.channel.MessagePayloadTestComparator"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="channel">
|
||||
<rendezvous-queue/>
|
||||
</channel>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="channel"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,16 @@
|
||||
<?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-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p">
|
||||
|
||||
|
||||
<int:channel id="input">
|
||||
<int:interceptors>
|
||||
<bean class="org.springframework.integration.channel.interceptor.ChannelInterceptorTests$PreSendReturnsMessageInterceptor"
|
||||
p:foo="foo"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
</beans>
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.interceptor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class ChannelInterceptorTests {
|
||||
|
||||
private final QueueChannel channel = new QueueChannel();
|
||||
|
||||
|
||||
@Test
|
||||
public void testPreSendInterceptorReturnsMessage() {
|
||||
channel.addInterceptor(new PreSendReturnsMessageInterceptor());
|
||||
channel.send(new StringMessage("test"));
|
||||
Message<?> result = channel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals("test", result.getPayload());
|
||||
assertEquals(1, result.getHeaders().get(PreSendReturnsMessageInterceptor.class.getSimpleName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreSendInterceptorReturnsNull() {
|
||||
PreSendReturnsNullInterceptor interceptor = new PreSendReturnsNullInterceptor();
|
||||
channel.addInterceptor(interceptor);
|
||||
Message<?> message = new StringMessage("test");
|
||||
channel.send(message);
|
||||
assertEquals(1, interceptor.getCount());
|
||||
Message<?> result = channel.receive(0);
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostSendInterceptorWithSentMessage() {
|
||||
final AtomicBoolean invoked = new AtomicBoolean(false);
|
||||
channel.addInterceptor(new ChannelInterceptorAdapter() {
|
||||
@Override
|
||||
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
||||
assertNotNull(message);
|
||||
assertNotNull(channel);
|
||||
assertSame(ChannelInterceptorTests.this.channel, channel);
|
||||
assertTrue(sent);
|
||||
invoked.set(true);
|
||||
}
|
||||
});
|
||||
channel.send(new StringMessage("test"));
|
||||
assertTrue(invoked.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostSendInterceptorWithUnsentMessage() {
|
||||
final AtomicInteger invokedCounter = new AtomicInteger(0);
|
||||
final AtomicInteger sentCounter = new AtomicInteger(0);
|
||||
final QueueChannel singleItemChannel = new QueueChannel(1);
|
||||
singleItemChannel.addInterceptor(new ChannelInterceptorAdapter() {
|
||||
@Override
|
||||
public void postSend(Message<?> message, MessageChannel channel, boolean sent) {
|
||||
assertNotNull(message);
|
||||
assertNotNull(channel);
|
||||
assertSame(singleItemChannel, channel);
|
||||
if (sent) {
|
||||
sentCounter.incrementAndGet();
|
||||
}
|
||||
invokedCounter.incrementAndGet();
|
||||
}
|
||||
});
|
||||
assertEquals(0, invokedCounter.get());
|
||||
assertEquals(0, sentCounter.get());
|
||||
singleItemChannel.send(new StringMessage("test1"));
|
||||
assertEquals(1, invokedCounter.get());
|
||||
assertEquals(1, sentCounter.get());
|
||||
singleItemChannel.send(new StringMessage("test2"), 0);
|
||||
assertEquals(2, invokedCounter.get());
|
||||
assertEquals(1, sentCounter.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreReceiveInterceptorReturnsTrue() {
|
||||
channel.addInterceptor(new PreReceiveReturnsTrueInterceptor());
|
||||
Message<?> message = new StringMessage("test");
|
||||
channel.send(message);
|
||||
Message<?> result = channel.receive(0);
|
||||
assertEquals(1, PreReceiveReturnsTrueInterceptor.counter.get());
|
||||
assertNotNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPreReceiveInterceptorReturnsFalse() {
|
||||
channel.addInterceptor(new PreReceiveReturnsFalseInterceptor());
|
||||
Message<?> message = new StringMessage("test");
|
||||
channel.send(message);
|
||||
Message<?> result = channel.receive(0);
|
||||
assertEquals(1, PreReceiveReturnsFalseInterceptor.counter.get());
|
||||
assertNull(result);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPostReceiveInterceptor() {
|
||||
final AtomicInteger invokedCount = new AtomicInteger();
|
||||
final AtomicInteger messageCount = new AtomicInteger();
|
||||
channel.addInterceptor(new ChannelInterceptorAdapter() {
|
||||
@Override
|
||||
public Message<?> postReceive(Message<?> message, MessageChannel channel) {
|
||||
assertNotNull(channel);
|
||||
assertSame(ChannelInterceptorTests.this.channel, channel);
|
||||
if (message != null) {
|
||||
messageCount.incrementAndGet();
|
||||
}
|
||||
invokedCount.incrementAndGet();
|
||||
return message;
|
||||
}
|
||||
});
|
||||
channel.receive(0);
|
||||
assertEquals(1, invokedCount.get());
|
||||
assertEquals(0, messageCount.get());
|
||||
channel.send(new StringMessage("test"));
|
||||
Message<?> result = channel.receive(0);
|
||||
assertNotNull(result);
|
||||
assertEquals(2, invokedCount.get());
|
||||
assertEquals(1, messageCount.get());
|
||||
}
|
||||
@Test
|
||||
public void testInterceptorBeanWithPnamespace(){
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("ChannelInterceptorTests-context.xml", ChannelInterceptorTests.class);
|
||||
AbstractMessageChannel channel = ac.getBean("input", AbstractMessageChannel.class);
|
||||
DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel);
|
||||
Object iList = cAccessor.getPropertyValue("interceptors");
|
||||
DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList);
|
||||
List<PreSendReturnsMessageInterceptor> interceptoList =
|
||||
(List<PreSendReturnsMessageInterceptor>) iAccessor.getPropertyValue("interceptors");
|
||||
String foo = interceptoList.get(0).getFoo();
|
||||
assertTrue(StringUtils.hasText(foo));
|
||||
assertEquals("foo", foo);
|
||||
}
|
||||
|
||||
|
||||
public static class PreSendReturnsMessageInterceptor extends ChannelInterceptorAdapter {
|
||||
private String foo;
|
||||
|
||||
private static AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
assertNotNull(message);
|
||||
Message<?> reply = MessageBuilder.fromMessage(message)
|
||||
.setHeader(this.getClass().getSimpleName(), counter.incrementAndGet()).build();
|
||||
return reply;
|
||||
}
|
||||
public String getFoo() {
|
||||
return foo;
|
||||
}
|
||||
|
||||
public void setFoo(String foo) {
|
||||
this.foo = foo;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PreSendReturnsNullInterceptor extends ChannelInterceptorAdapter {
|
||||
|
||||
private static AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
protected int getCount() {
|
||||
return counter.get();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
assertNotNull(message);
|
||||
counter.incrementAndGet();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PreReceiveReturnsTrueInterceptor extends ChannelInterceptorAdapter {
|
||||
|
||||
private static AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public boolean preReceive(MessageChannel channel) {
|
||||
counter.incrementAndGet();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class PreReceiveReturnsFalseInterceptor extends ChannelInterceptorAdapter {
|
||||
|
||||
private static AtomicInteger counter = new AtomicInteger();
|
||||
|
||||
@Override
|
||||
public boolean preReceive(MessageChannel channel) {
|
||||
counter.incrementAndGet();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?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-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p">
|
||||
|
||||
<int:channel id="inputA">
|
||||
<int:interceptors>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="eight"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="inputB"/>
|
||||
|
||||
<int:channel id="inputC"/>
|
||||
|
||||
<int:channel-interceptor-chain channel-name-pattern="*" order="3">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="six"/>
|
||||
</int:channel-interceptor-chain>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,54 @@
|
||||
<?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-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p">
|
||||
|
||||
<int:channel id="inputA">
|
||||
<int:interceptors>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="eight"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="inputB">
|
||||
<int:queue capacity="1"/>
|
||||
</int:channel>
|
||||
|
||||
<int:publish-subscribe-channel id="foo"/>
|
||||
|
||||
<int:channel id="bar">
|
||||
<int:interceptors>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="eight"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:channel id="baz"/>
|
||||
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object" order="3">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="six"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, fooA" order="1">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="one"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="two"/>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="three"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object" order="-1">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="four"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object" order="-5">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="five"/>
|
||||
<ref bean="channelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
|
||||
|
||||
<bean id="channelInterceptor" class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="seven"/>
|
||||
<!-- <bean id="object" class="java.lang.Object"/>-->
|
||||
</beans>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?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-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p">
|
||||
|
||||
|
||||
|
||||
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object" order="3">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="six"/>
|
||||
</int:channel-interceptor-chain>
|
||||
|
||||
<bean id="object" class="java.lang.Object"/>
|
||||
</beans>
|
||||
@@ -0,0 +1,40 @@
|
||||
<?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-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p">
|
||||
|
||||
<int:channel id="inputA">
|
||||
<int:interceptors>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleOrderedInterceptor"
|
||||
p:testIdentifier="eight"
|
||||
p:order="5"/>
|
||||
<ref bean="unorderedChannelInterceptor"/>
|
||||
<ref bean="orderedChannelInterceptor"/>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="five"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object" order="3">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="six"/>
|
||||
<ref bean="unorderedChannelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*" order="1">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor" p:testIdentifier="one"/>
|
||||
<ref bean="orderedChannelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object" order="-1">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleOrderedInterceptor"
|
||||
p:testIdentifier="four"
|
||||
p:order="7"/>
|
||||
<ref bean="orderedChannelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
|
||||
<bean id="unorderedChannelInterceptor" class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor"
|
||||
p:testIdentifier="seven"/>
|
||||
<bean id="orderedChannelInterceptor" class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleOrderedInterceptor"
|
||||
p:testIdentifier="ten"
|
||||
p:order="4"/>
|
||||
</beans>
|
||||
@@ -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"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
|
||||
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd"
|
||||
xmlns:int="http://www.springframework.org/schema/integration"
|
||||
xmlns:p="http://www.springframework.org/schema/p">
|
||||
|
||||
<int:channel id="inputA">
|
||||
<int:interceptors>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor"
|
||||
p:testIdentifier="eight"/>
|
||||
<ref bean="unorderedChannelInterceptor"/>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor"
|
||||
p:testIdentifier="five"/>
|
||||
</int:interceptors>
|
||||
</int:channel>
|
||||
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*, foo, object">
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor"
|
||||
p:testIdentifier="six"/>
|
||||
<ref bean="unorderedChannelInterceptor"/>
|
||||
</int:channel-interceptor-chain>
|
||||
<int:channel-interceptor-chain channel-name-pattern="input*">
|
||||
<ref bean="unorderedChannelInterceptor"/>
|
||||
<bean class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor"
|
||||
p:testIdentifier="one"/>
|
||||
</int:channel-interceptor-chain>
|
||||
|
||||
|
||||
<bean id="unorderedChannelInterceptor" class="org.springframework.integration.channel.interceptor.GlobalChannelInterceptorTests$SampleInterceptor"
|
||||
p:testIdentifier="seven"/>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,224 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.interceptor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.integration.channel.AbstractMessageChannel;
|
||||
import org.springframework.integration.channel.ChannelInterceptor;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @since 2.0
|
||||
*/
|
||||
public class GlobalChannelInterceptorTests {
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void validateGlobalInterceptor(){
|
||||
ApplicationContext applicationContext =
|
||||
new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-context.xml", GlobalChannelInterceptorTests.class);
|
||||
Map<String, AbstractMessageChannel> channels = applicationContext.getBeansOfType(AbstractMessageChannel.class);
|
||||
for (String channelName : channels.keySet()) {
|
||||
AbstractMessageChannel channel = channels.get(channelName);
|
||||
DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel);
|
||||
Object iList = cAccessor.getPropertyValue("interceptors");
|
||||
DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList);
|
||||
List<SampleInterceptor> interceptoList = (List<SampleInterceptor>) iAccessor.getPropertyValue("interceptors");
|
||||
if (channelName.equals("inputA")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 13);
|
||||
Assert.assertEquals("four", inter[0].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[1].getTestIdentifier());
|
||||
Assert.assertEquals("five", inter[2].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[3].getTestIdentifier());
|
||||
Assert.assertEquals("eight", inter[4].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[5].getTestIdentifier());
|
||||
Assert.assertEquals("one", inter[6].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[7].getTestIdentifier());
|
||||
Assert.assertEquals("two", inter[8].getTestIdentifier());
|
||||
Assert.assertEquals("three", inter[9].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[10].getTestIdentifier());
|
||||
Assert.assertEquals("six", inter[11].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[12].getTestIdentifier());
|
||||
}
|
||||
else
|
||||
if (channelName.equals("inputB")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 11);
|
||||
Assert.assertEquals("four", inter[0].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[1].getTestIdentifier());
|
||||
Assert.assertEquals("five", inter[2].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[3].getTestIdentifier());
|
||||
Assert.assertEquals("one", inter[4].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[5].getTestIdentifier());
|
||||
Assert.assertEquals("two", inter[6].getTestIdentifier());
|
||||
Assert.assertEquals("three", inter[7].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[8].getTestIdentifier());
|
||||
Assert.assertEquals("six", inter[9].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[10].getTestIdentifier());
|
||||
}
|
||||
else
|
||||
if (channelName.equals("foo")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 6);
|
||||
Assert.assertEquals("four", inter[0].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[1].getTestIdentifier());
|
||||
Assert.assertEquals("five", inter[2].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[3].getTestIdentifier());
|
||||
Assert.assertEquals("six", inter[4].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[5].getTestIdentifier());
|
||||
}
|
||||
else
|
||||
if (channelName.equals("bar")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 2);
|
||||
Assert.assertEquals("eight", inter[0].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[1].getTestIdentifier());
|
||||
}
|
||||
else
|
||||
if (channelName.equals("baz")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Will test mix of Ordered and un-Ordered ChannelInterceptors
|
||||
* Individual interceptors will only be sorted within groups they are defined.
|
||||
* For example: interceptors defined inside of channels will be sorted according to Ordered implementation
|
||||
* If global interceptors were added BEFORE (negative order) or AFTER (ppositive order) the global stack will be sorted
|
||||
* and added before/after the existing stack
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void validateGlobalInterceptorsOrdered(){
|
||||
ApplicationContext applicationContext =
|
||||
new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-ordered-context.xml", GlobalChannelInterceptorTests.class);
|
||||
Map<String, AbstractMessageChannel> channels = applicationContext.getBeansOfType(AbstractMessageChannel.class);
|
||||
for (String channelName : channels.keySet()) {
|
||||
AbstractMessageChannel channel = channels.get(channelName);
|
||||
DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel);
|
||||
Object iList = cAccessor.getPropertyValue("interceptors");
|
||||
DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList);
|
||||
List<SampleInterceptor> interceptoList = (List<SampleInterceptor>) iAccessor.getPropertyValue("interceptors");
|
||||
if (channelName.equals("inputA")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 10);
|
||||
Assert.assertEquals("ten", inter[0].getTestIdentifier());
|
||||
Assert.assertEquals("four", inter[1].getTestIdentifier());
|
||||
Assert.assertEquals("ten", inter[2].getTestIdentifier());
|
||||
Assert.assertEquals("eight", inter[3].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[4].getTestIdentifier());
|
||||
Assert.assertEquals("five", inter[5].getTestIdentifier());
|
||||
Assert.assertEquals("ten", inter[6].getTestIdentifier());
|
||||
Assert.assertEquals("one", inter[7].getTestIdentifier());
|
||||
Assert.assertEquals("six", inter[8].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[9].getTestIdentifier());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void validateGlobalInterceptorsUnOrdered(){
|
||||
ApplicationContext applicationContext =
|
||||
new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-unordered-context.xml", GlobalChannelInterceptorTests.class);
|
||||
Map<String, AbstractMessageChannel> channels = applicationContext.getBeansOfType(AbstractMessageChannel.class);
|
||||
for (String channelName : channels.keySet()) {
|
||||
AbstractMessageChannel channel = channels.get(channelName);
|
||||
DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel);
|
||||
Object iList = cAccessor.getPropertyValue("interceptors");
|
||||
DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList);
|
||||
List<SampleInterceptor> interceptoList = (List<SampleInterceptor>) iAccessor.getPropertyValue("interceptors");
|
||||
if (channelName.equals("inputA")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 7);
|
||||
Assert.assertEquals("eight", inter[0].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[1].getTestIdentifier());
|
||||
Assert.assertEquals("five", inter[2].getTestIdentifier());
|
||||
Assert.assertEquals("six", inter[3].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[4].getTestIdentifier());
|
||||
Assert.assertEquals("seven", inter[5].getTestIdentifier());
|
||||
Assert.assertEquals("one", inter[6].getTestIdentifier());
|
||||
}
|
||||
}
|
||||
}
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void validateGlobalInterceptorsAllPattern(){
|
||||
ApplicationContext applicationContext =
|
||||
new ClassPathXmlApplicationContext("GlobalChannelInterceptorTests-all-context.xml", GlobalChannelInterceptorTests.class);
|
||||
Map<String, AbstractMessageChannel> channels = applicationContext.getBeansOfType(AbstractMessageChannel.class);
|
||||
for (String channelName : channels.keySet()) {
|
||||
AbstractMessageChannel channel = channels.get(channelName);
|
||||
DirectFieldAccessor cAccessor = new DirectFieldAccessor(channel);
|
||||
Object iList = cAccessor.getPropertyValue("interceptors");
|
||||
DirectFieldAccessor iAccessor = new DirectFieldAccessor(iList);
|
||||
List<SampleInterceptor> interceptoList = (List<SampleInterceptor>) iAccessor.getPropertyValue("interceptors");
|
||||
if (channelName.equals("inputA")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 2);
|
||||
} else if (channelName.equals("inputB")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 1);
|
||||
} else if (channelName.equals("inputC")){
|
||||
SampleInterceptor[] inter = interceptoList.toArray(new SampleInterceptor[]{});
|
||||
Assert.assertTrue(inter.length == 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SampleInterceptor implements ChannelInterceptor {
|
||||
private String testIdentifier;
|
||||
public String getTestIdentifier() {
|
||||
return testIdentifier;
|
||||
}
|
||||
public void setTestIdentifier(String testIdentifier) {
|
||||
this.testIdentifier = testIdentifier;
|
||||
}
|
||||
public Message<?> postReceive(Message<?> message, MessageChannel channel) {
|
||||
return null;
|
||||
}
|
||||
public void postSend(Message<?> message, MessageChannel channel,
|
||||
boolean sent) {
|
||||
}
|
||||
public boolean preReceive(MessageChannel channel) {
|
||||
return false;
|
||||
}
|
||||
public Message<?> preSend(Message<?> message, MessageChannel channel) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
public static class SampleOrderedInterceptor extends SampleInterceptor implements Ordered {
|
||||
private int order;
|
||||
public int getOrder() {
|
||||
return order;
|
||||
}
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.interceptor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageDeliveryException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.selector.MessageSelector;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MessageSelectingInterceptorTests {
|
||||
|
||||
@Test
|
||||
public void testSingleSelectorAccepts() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
MessageSelector selector = new TestMessageSelector(true, counter);
|
||||
MessageSelectingInterceptor interceptor = new MessageSelectingInterceptor(selector);
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.addInterceptor(interceptor);
|
||||
assertTrue(channel.send(new StringMessage("test1")));
|
||||
}
|
||||
|
||||
@Test(expected=MessageDeliveryException.class)
|
||||
public void testSingleSelectorRejects() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
MessageSelector selector = new TestMessageSelector(false, counter);
|
||||
MessageSelectingInterceptor interceptor = new MessageSelectingInterceptor(selector);
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.addInterceptor(interceptor);
|
||||
channel.send(new StringMessage("test1"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSelectorsAccept() {
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
MessageSelector selector1 = new TestMessageSelector(true, counter);
|
||||
MessageSelector selector2 = new TestMessageSelector(true, counter);
|
||||
MessageSelectingInterceptor interceptor = new MessageSelectingInterceptor(selector1, selector2);
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.addInterceptor(interceptor);
|
||||
assertTrue(channel.send(new StringMessage("test1")));
|
||||
assertEquals(2, counter.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleSelectorsReject() {
|
||||
boolean exceptionThrown = false;
|
||||
final AtomicInteger counter = new AtomicInteger();
|
||||
MessageSelector selector1 = new TestMessageSelector(true, counter);
|
||||
MessageSelector selector2 = new TestMessageSelector(false, counter);
|
||||
MessageSelector selector3 = new TestMessageSelector(false, counter);
|
||||
MessageSelector selector4 = new TestMessageSelector(true, counter);
|
||||
MessageSelectingInterceptor interceptor = new MessageSelectingInterceptor(selector1, selector2, selector3, selector4);
|
||||
QueueChannel channel = new QueueChannel();
|
||||
channel.addInterceptor(interceptor);
|
||||
try {
|
||||
channel.send(new StringMessage("test1"));
|
||||
}
|
||||
catch (MessageDeliveryException e) {
|
||||
exceptionThrown = true;
|
||||
}
|
||||
assertTrue(exceptionThrown);
|
||||
assertEquals(2, counter.get());
|
||||
}
|
||||
|
||||
|
||||
private static class TestMessageSelector implements MessageSelector {
|
||||
|
||||
private final boolean shouldAccept;
|
||||
|
||||
private final AtomicInteger counter;
|
||||
|
||||
|
||||
public TestMessageSelector(boolean shouldAccept, AtomicInteger counter) {
|
||||
this.shouldAccept = shouldAccept;
|
||||
this.counter = counter;
|
||||
}
|
||||
|
||||
|
||||
public boolean accept(Message<?> message) {
|
||||
this.counter.incrementAndGet();
|
||||
return this.shouldAccept;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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.channel.interceptor;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.selector.MessageSelector;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class WireTapTests {
|
||||
|
||||
@Test
|
||||
public void wireTapWithNoSelector() {
|
||||
QueueChannel mainChannel = new QueueChannel();
|
||||
QueueChannel secondaryChannel = new QueueChannel();
|
||||
mainChannel.addInterceptor(new WireTap(secondaryChannel));
|
||||
mainChannel.send(new StringMessage("testing"));
|
||||
Message<?> original = mainChannel.receive(0);
|
||||
assertNotNull(original);
|
||||
Message<?> intercepted = secondaryChannel.receive(0);
|
||||
assertNotNull(intercepted);
|
||||
assertEquals(original, intercepted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wireTapWithRejectingSelector() {
|
||||
QueueChannel mainChannel = new QueueChannel();
|
||||
QueueChannel secondaryChannel = new QueueChannel();
|
||||
mainChannel.addInterceptor(new WireTap(secondaryChannel, new TestSelector(false)));
|
||||
mainChannel.send(new StringMessage("testing"));
|
||||
Message<?> original = mainChannel.receive(0);
|
||||
assertNotNull(original);
|
||||
Message<?> intercepted = secondaryChannel.receive(0);
|
||||
assertNull(intercepted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void wireTapWithAcceptingSelector() {
|
||||
QueueChannel mainChannel = new QueueChannel();
|
||||
QueueChannel secondaryChannel = new QueueChannel();
|
||||
mainChannel.addInterceptor(new WireTap(secondaryChannel, new TestSelector(true)));
|
||||
mainChannel.send(new StringMessage("testing"));
|
||||
Message<?> original = mainChannel.receive(0);
|
||||
assertNotNull(original);
|
||||
Message<?> intercepted = secondaryChannel.receive(0);
|
||||
assertNotNull(intercepted);
|
||||
assertEquals(original, intercepted);
|
||||
}
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void wireTapTargetMustNotBeNull() {
|
||||
new WireTap(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void simpleTargetWireTap() {
|
||||
QueueChannel mainChannel = new QueueChannel();
|
||||
QueueChannel secondaryChannel = new QueueChannel();
|
||||
mainChannel.addInterceptor(new WireTap(secondaryChannel));
|
||||
assertNull(secondaryChannel.receive(0));
|
||||
Message<?> message = new StringMessage("testing");
|
||||
mainChannel.send(message);
|
||||
Message<?> original = mainChannel.receive(0);
|
||||
Message<?> intercepted = secondaryChannel.receive(0);
|
||||
assertNotNull(original);
|
||||
assertNotNull(intercepted);
|
||||
assertEquals(original, intercepted);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void interceptedMessageContainsHeaderValue() {
|
||||
QueueChannel mainChannel = new QueueChannel();
|
||||
QueueChannel secondaryChannel = new QueueChannel();
|
||||
mainChannel.addInterceptor(new WireTap(secondaryChannel));
|
||||
String headerName = "testAttribute";
|
||||
Message<String> message = MessageBuilder.withPayload("testing")
|
||||
.setHeader(headerName, new Integer(123)).build();
|
||||
mainChannel.send(message);
|
||||
Message<?> original = mainChannel.receive(0);
|
||||
Message<?> intercepted = secondaryChannel.receive(0);
|
||||
Object originalAttribute = original.getHeaders().get(headerName);
|
||||
Object interceptedAttribute = intercepted.getHeaders().get(headerName);
|
||||
assertNotNull(originalAttribute);
|
||||
assertNotNull(interceptedAttribute);
|
||||
assertEquals(originalAttribute, interceptedAttribute);
|
||||
}
|
||||
|
||||
|
||||
private static class TestSelector implements MessageSelector {
|
||||
|
||||
private boolean shouldAccept;
|
||||
|
||||
public TestSelector(boolean shouldAccept) {
|
||||
this.shouldAccept = shouldAccept;
|
||||
}
|
||||
|
||||
public boolean accept(Message<?> message) {
|
||||
return this.shouldAccept;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2002-2007 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class Adder {
|
||||
|
||||
public Long add(List<Long> results) {
|
||||
long total = 0l;
|
||||
for (long partialResult: results) {
|
||||
total += partialResult;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.aggregator.*;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.test.util.TestUtils;
|
||||
import org.springframework.integration.util.MethodInvoker;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Mark Fisher
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
public class AggregatorParserTests {
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.context = new ClassPathXmlApplicationContext("aggregatorParserTests.xml", this.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregation() {
|
||||
MessageChannel input = (MessageChannel) context.getBean("aggregatorWithReferenceInput");
|
||||
TestAggregatorBean aggregatorBean = (TestAggregatorBean) context.getBean("aggregatorBean");
|
||||
List<Message<?>> outboundMessages = new ArrayList<Message<?>>();
|
||||
outboundMessages.add(createMessage("123", "id1", 3, 1, null));
|
||||
outboundMessages.add(createMessage("789", "id1", 3, 3, null));
|
||||
outboundMessages.add(createMessage("456", "id1", 3, 2, null));
|
||||
for (Message<?> message : outboundMessages) {
|
||||
input.send(message);
|
||||
}
|
||||
assertEquals("One and only one message must have been aggregated", 1, aggregatorBean
|
||||
.getAggregatedMessages().size());
|
||||
Message<?> aggregatedMessage = aggregatorBean.getAggregatedMessages().get("id1");
|
||||
assertEquals("The aggregated message payload is not correct", "123456789", aggregatedMessage
|
||||
.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPropertyAssignment() throws Exception {
|
||||
EventDrivenConsumer endpoint =
|
||||
(EventDrivenConsumer) context.getBean("completelyDefinedAggregator");
|
||||
ReleaseStrategy ReleaseStrategy = (ReleaseStrategy) context.getBean("releaseStrategy");
|
||||
CorrelationStrategy correlationStrategy = (CorrelationStrategy) context.getBean("correlationStrategy");
|
||||
MessageChannel outputChannel = (MessageChannel) context.getBean("outputChannel");
|
||||
MessageChannel discardChannel = (MessageChannel) context.getBean("discardChannel");
|
||||
Object consumer = new DirectFieldAccessor(endpoint).getPropertyValue("handler");
|
||||
assertThat(consumer, is(CorrelatingMessageHandler.class));
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(consumer);
|
||||
Method expectedMethod = TestAggregatorBean.class.getMethod("createSingleMessageFromGroup", List.class);
|
||||
assertEquals("The MethodInvokingAggregator is not injected with the appropriate aggregation method",
|
||||
expectedMethod, ((MessageListMethodAdapter) new DirectFieldAccessor(accessor.getPropertyValue("outputProcessor")).getPropertyValue("adapter")).getMethod());
|
||||
assertEquals(
|
||||
"The AggregatorEndpoint is not injected with the appropriate ReleaseStrategy instance",
|
||||
ReleaseStrategy, accessor.getPropertyValue("releaseStrategy"));
|
||||
assertEquals("The AggregatorEndpoint is not injected with the appropriate CorrelationStrategy instance",
|
||||
correlationStrategy, accessor.getPropertyValue("correlationStrategy"));
|
||||
Assert.assertEquals("The AggregatorEndpoint is not injected with the appropriate output channel",
|
||||
outputChannel, accessor.getPropertyValue("outputChannel"));
|
||||
Assert.assertEquals("The AggregatorEndpoint is not injected with the appropriate discard channel",
|
||||
discardChannel, accessor.getPropertyValue("discardChannel"));
|
||||
Assert.assertEquals("The AggregatorEndpoint is not set with the appropriate timeout value",
|
||||
86420000l, TestUtils.getPropertyValue(consumer, "channelTemplate.sendTimeout"));
|
||||
Assert.assertEquals(
|
||||
"The AggregatorEndpoint is not configured with the appropriate 'send partial results on timeout' flag",
|
||||
true, accessor.getPropertyValue("sendPartialResultOnExpiry"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSimpleJavaBeanAggregator() {
|
||||
List<Message<?>> outboundMessages = new ArrayList<Message<?>>();
|
||||
MessageChannel input =
|
||||
(MessageChannel) context.getBean("aggregatorWithReferenceAndMethodInput");
|
||||
outboundMessages.add(createMessage(1l, "id1", 3, 1, null));
|
||||
outboundMessages.add(createMessage(2l, "id1", 3, 3, null));
|
||||
outboundMessages.add(createMessage(3l, "id1", 3, 2, null));
|
||||
for (Message<?> message : outboundMessages) {
|
||||
input.send(message);
|
||||
}
|
||||
PollableChannel outputChannel = (PollableChannel) context.getBean("outputChannel");
|
||||
Message<?> response = outputChannel.receive(10);
|
||||
Assert.assertEquals(6l, response.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected=BeanCreationException.class)
|
||||
public void testMissingMethodOnAggregator() {
|
||||
context = new ClassPathXmlApplicationContext("invalidMethodNameAggregator.xml", this.getClass());
|
||||
}
|
||||
|
||||
@Test(expected=BeanCreationException.class)
|
||||
public void testDuplicateReleaseStrategyDefinition() {
|
||||
context = new ClassPathXmlApplicationContext(
|
||||
"ReleaseStrategyMethodWithMissingReference.xml", this.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAggregatorWithPojoReleaseStrategy() {
|
||||
MessageChannel input = (MessageChannel) context.getBean("aggregatorWithPojoReleaseStrategyInput");
|
||||
EventDrivenConsumer endpoint =
|
||||
(EventDrivenConsumer) context.getBean("aggregatorWithPojoReleaseStrategy");
|
||||
ReleaseStrategy ReleaseStrategy = (ReleaseStrategy) new DirectFieldAccessor(
|
||||
new DirectFieldAccessor(endpoint).getPropertyValue("handler")).getPropertyValue("releaseStrategy");
|
||||
Assert.assertTrue(ReleaseStrategy instanceof ReleaseStrategyAdapter);
|
||||
DirectFieldAccessor ReleaseStrategyAccessor = new DirectFieldAccessor(ReleaseStrategy);
|
||||
MethodInvoker invoker = (MethodInvoker) ReleaseStrategyAccessor.getPropertyValue("invoker");
|
||||
Assert.assertTrue(new DirectFieldAccessor(invoker).getPropertyValue("object") instanceof MaxValueReleaseStrategy);
|
||||
Assert.assertTrue(((Method) ReleaseStrategyAccessor.getPropertyValue("method")).getName().equals("checkCompleteness"));
|
||||
input.send(createMessage(1l, "correllationId", 4, 0, null));
|
||||
input.send(createMessage(2l, "correllationId", 4, 1, null));
|
||||
input.send(createMessage(3l, "correllationId", 4, 2, null));
|
||||
PollableChannel outputChannel = (PollableChannel) context.getBean("outputChannel");
|
||||
Message<?> reply = outputChannel.receive(0);
|
||||
Assert.assertNull(reply);
|
||||
input.send(createMessage(5l, "correllationId", 4, 3, null));
|
||||
reply = outputChannel.receive(0);
|
||||
Assert.assertNotNull(reply);
|
||||
assertEquals(11l, reply.getPayload());
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testAggregatorWithInvalidReleaseStrategyMethod() {
|
||||
context = new ClassPathXmlApplicationContext("invalidReleaseStrategyMethod.xml", this.getClass());
|
||||
}
|
||||
|
||||
|
||||
private static <T> Message<T> createMessage(T payload, Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel outputChannel) {
|
||||
return MessageBuilder.withPayload(payload)
|
||||
.setCorrelationId(correlationId)
|
||||
.setSequenceSize(sequenceSize)
|
||||
.setSequenceNumber(sequenceNumber)
|
||||
.setReplyChannel(outputChannel).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<beans:bean id="correlationStrategy"
|
||||
class="org.springframework.integration.config.AggregatorWithCorrelationStrategyTests$FirstLetterCorrelationStrategy"/>
|
||||
|
||||
<beans:bean id="pojoCorrelationStrategy"
|
||||
class="org.springframework.integration.config.AggregatorWithCorrelationStrategyTests$PojoCorrelationStrategy"/>
|
||||
|
||||
<beans:bean id="releaseStrategy" class="org.springframework.integration.config.AggregatorWithCorrelationStrategyTests$MessageCountReleaseStrategy">
|
||||
<beans:constructor-arg value="3"/>
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean name="aggregator" class="org.springframework.integration.config.AggregatorWithCorrelationStrategyTests$SimpleAggregator"/>
|
||||
|
||||
<channel id="inputChannel"/>
|
||||
|
||||
<channel id="outputChannel">
|
||||
<queue capacity="10"/>
|
||||
</channel>
|
||||
|
||||
<channel id="pojoInputChannel"/>
|
||||
|
||||
<channel id="pojoOutputChannel">
|
||||
<queue capacity="10"/>
|
||||
</channel>
|
||||
|
||||
<aggregator ref="aggregator"
|
||||
release-strategy="releaseStrategy"
|
||||
correlation-strategy="correlationStrategy"
|
||||
input-channel="inputChannel"
|
||||
output-channel="outputChannel"/>
|
||||
|
||||
<aggregator ref="aggregator"
|
||||
release-strategy="releaseStrategy"
|
||||
correlation-strategy="pojoCorrelationStrategy" correlation-strategy-method="correlate"
|
||||
input-channel="pojoInputChannel"
|
||||
output-channel="pojoOutputChannel"/>
|
||||
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.aggregator.ReleaseStrategy;
|
||||
import org.springframework.integration.aggregator.CorrelationStrategy;
|
||||
import org.springframework.integration.annotation.Aggregator;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.matchers.JUnitMatchers.containsString;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class AggregatorWithCorrelationStrategyTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("inputChannel")
|
||||
MessageChannel inputChannel;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("outputChannel")
|
||||
PollableChannel outputChannel;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("pojoInputChannel")
|
||||
MessageChannel pojoInputChannel;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("pojoOutputChannel")
|
||||
PollableChannel pojoOutputChannel;
|
||||
|
||||
@Test
|
||||
public void testCorrelationAndCompletion() {
|
||||
inputChannel.send(MessageBuilder.withPayload("A1").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("B2").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("C3").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("A4").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("B5").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("C6").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("A7").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("B8").build());
|
||||
inputChannel.send(MessageBuilder.withPayload("C9").build());
|
||||
receiveAndCompare(outputChannel, "A1", "A4", "A7");
|
||||
receiveAndCompare(outputChannel, "B2", "B5", "B8");
|
||||
receiveAndCompare(outputChannel, "C3", "C6", "C9");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCorrelationAndCompletionWithPojo() {
|
||||
// the test verifies how a pojo strategy is applied
|
||||
// Strings are correlated by their first letter, integers are correlated
|
||||
// by the last digit
|
||||
pojoInputChannel.send(MessageBuilder.withPayload("X1").build());
|
||||
pojoInputChannel.send(MessageBuilder.withPayload(93).build());
|
||||
pojoInputChannel.send(MessageBuilder.withPayload("X4").build());
|
||||
pojoInputChannel.send(MessageBuilder.withPayload(113).build());
|
||||
pojoInputChannel.send(MessageBuilder.withPayload("X7").build());
|
||||
pojoInputChannel.send(MessageBuilder.withPayload(213).build());
|
||||
receiveAndCompare(pojoOutputChannel, "X1", "X4", "X7");
|
||||
receiveAndCompare(pojoOutputChannel, "93", "113", "213");
|
||||
}
|
||||
|
||||
private void receiveAndCompare(PollableChannel outputChannel, String... expectedValues) {
|
||||
Message<?> message = outputChannel.receive(500);
|
||||
Assert.assertNotNull(message);
|
||||
for (String expectedValue : expectedValues) {
|
||||
assertThat((String) message.getPayload(), containsString(expectedValue));
|
||||
}
|
||||
}
|
||||
|
||||
public static class MessageCountReleaseStrategy implements ReleaseStrategy {
|
||||
|
||||
private final int expectedSize;
|
||||
|
||||
public MessageCountReleaseStrategy(int expectedSize) {
|
||||
this.expectedSize = expectedSize;
|
||||
}
|
||||
|
||||
public boolean canRelease(MessageGroup messages) {
|
||||
return messages.size() == expectedSize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class FirstLetterCorrelationStrategy implements CorrelationStrategy {
|
||||
|
||||
public Object getCorrelationKey(Message<?> message) {
|
||||
return message.getPayload().toString().subSequence(0, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class PojoCorrelationStrategy {
|
||||
|
||||
public String correlate(String message) {
|
||||
return message.substring(0, 1);
|
||||
}
|
||||
|
||||
public String correlate(Integer message) {
|
||||
return Integer.toString(message % 10);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class SimpleAggregator {
|
||||
|
||||
@Aggregator
|
||||
public String concatenate(List<Object> payloads) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (Object payload : payloads) {
|
||||
buffer.append(payload.toString());
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="output">
|
||||
<queue capacity="5" />
|
||||
</channel>
|
||||
|
||||
<channel id="input" />
|
||||
|
||||
<aggregator id="aggregator" ref="aggregatorBean"
|
||||
input-channel="input" output-channel="output" message-store="messageStore" send-partial-result-on-expiry="true"/>
|
||||
|
||||
<beans:bean id="messageStore" class="org.springframework.integration.store.SimpleMessageStore"/>
|
||||
|
||||
<beans:bean id="aggregatorBean"
|
||||
class="org.springframework.integration.config.TestAggregatorBean" />
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class AggregatorWithMessageStoreParserTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("input")
|
||||
private MessageChannel input;
|
||||
|
||||
@Autowired
|
||||
private TestAggregatorBean aggregatorBean;
|
||||
|
||||
@Autowired
|
||||
private MessageGroupStore messageGroupStore;
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testAggregation() {
|
||||
|
||||
input.send(createMessage("123", "id1", 3, 1, null));
|
||||
assertEquals(1, messageGroupStore.getMessageGroup("id1").size());
|
||||
input.send(createMessage("789", "id1", 3, 3, null));
|
||||
assertEquals(2, messageGroupStore.getMessageGroup("id1").size());
|
||||
input.send(createMessage("456", "id1", 3, 2, null));
|
||||
assertEquals("One and only one message should have been aggregated", 1, aggregatorBean
|
||||
.getAggregatedMessages().size());
|
||||
Message<?> aggregatedMessage = aggregatorBean.getAggregatedMessages().get("id1");
|
||||
assertEquals("The aggregated message payload is not correct", "123456789", aggregatedMessage
|
||||
.getPayload());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@DirtiesContext
|
||||
public void testExpiry() {
|
||||
|
||||
input.send(createMessage("123", "id1", 3, 1, null));
|
||||
assertEquals(1, messageGroupStore.getMessageGroup("id1").size());
|
||||
input.send(createMessage("456", "id1", 3, 2, null));
|
||||
assertEquals(2, messageGroupStore.getMessageGroup("id1").size());
|
||||
messageGroupStore.expireMessageGroups(-10000);
|
||||
assertEquals("One and only one message should have been aggregated", 1, aggregatorBean
|
||||
.getAggregatedMessages().size());
|
||||
Message<?> aggregatedMessage = aggregatorBean.getAggregatedMessages().get("id1");
|
||||
assertEquals("The aggregated message payload is not correct", "123456", aggregatedMessage
|
||||
.getPayload());
|
||||
}
|
||||
|
||||
|
||||
private static <T> Message<T> createMessage(T payload, Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel outputChannel) {
|
||||
return MessageBuilder.withPayload(payload)
|
||||
.setCorrelationId(correlationId)
|
||||
.setSequenceSize(sequenceSize)
|
||||
.setSequenceNumber(sequenceNumber)
|
||||
.setReplyChannel(outputChannel).build();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="pollableInput1">
|
||||
<queue />
|
||||
</channel>
|
||||
|
||||
<channel id="pollableInput2">
|
||||
<queue />
|
||||
</channel>
|
||||
|
||||
<channel id="output">
|
||||
<queue />
|
||||
</channel>
|
||||
|
||||
<channel id="replyOutput">
|
||||
<queue />
|
||||
</channel>
|
||||
|
||||
<chain input-channel="filterInput" output-channel="output">
|
||||
<filter ref="typeSelector" />
|
||||
<service-activator ref="testHandler" />
|
||||
</chain>
|
||||
|
||||
<chain input-channel="headerEnricherInput">
|
||||
<header-enricher>
|
||||
<reply-channel ref="replyOutput"/>
|
||||
<correlation-id value="ABC"/>
|
||||
<header name="testValue" value="XYZ" />
|
||||
<header name="testRef" ref="testHeaderValue" />
|
||||
</header-enricher>
|
||||
<service-activator ref="testHandler" />
|
||||
</chain>
|
||||
|
||||
<chain input-channel="pollableInput1" output-channel="output">
|
||||
<poller>
|
||||
<interval-trigger interval="10000" />
|
||||
</poller>
|
||||
<filter ref="typeSelector" />
|
||||
<service-activator ref="testHandler" />
|
||||
</chain>
|
||||
|
||||
<chain input-channel="pollableInput2" output-channel="output">
|
||||
<poller ref="topLevelPoller"/>
|
||||
<service-activator ref="testHandler" />
|
||||
</chain>
|
||||
|
||||
<poller id="topLevelPoller">
|
||||
<interval-trigger interval="5000" />
|
||||
</poller>
|
||||
|
||||
<chain input-channel="beanInput" output-channel="output">
|
||||
<beans:bean
|
||||
class="org.springframework.integration.config.ChainParserTests$StubHandler" />
|
||||
</chain>
|
||||
|
||||
<chain input-channel="aggregatorInput" output-channel="output">
|
||||
<aggregator ref="aggregatorBean" method="aggregate" />
|
||||
<chain>
|
||||
<filter ref="typeSelector" />
|
||||
<service-activator ref="testHandler" />
|
||||
</chain>
|
||||
</chain>
|
||||
|
||||
<chain input-channel="payloadTypeRouterInput">
|
||||
<payload-type-router>
|
||||
<mapping type="java.lang.String" channel="strings"/>
|
||||
<mapping type="java.lang.Number" channel="numbers"/>
|
||||
</payload-type-router>
|
||||
</chain>
|
||||
|
||||
<channel id="strings">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<channel id="numbers">
|
||||
<queue/>
|
||||
</channel>
|
||||
|
||||
<beans:bean id="aggregatorBean"
|
||||
class="org.springframework.integration.config.ChainParserTests$StubAggregator" />
|
||||
|
||||
<beans:bean id="testHeaderValue" class="java.lang.Integer">
|
||||
<beans:constructor-arg value="123" />
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="typeSelector"
|
||||
class="org.springframework.integration.selector.PayloadTypeSelector">
|
||||
<beans:constructor-arg value="java.lang.String" />
|
||||
</beans:bean>
|
||||
|
||||
<beans:bean id="testHandler"
|
||||
class="org.springframework.integration.config.TestHandler">
|
||||
<beans:constructor-arg value="1" />
|
||||
<beans:property name="replyMessageText" value="foo" />
|
||||
</beans:bean>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.hamcrest.Factory;
|
||||
import org.hamcrest.Matcher;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.handler.AbstractReplyProducingMessageHandler;
|
||||
import org.springframework.integration.message.MessageBuilder;
|
||||
import org.springframework.integration.message.MessageMatcher;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Iwein Fuld
|
||||
*/
|
||||
@ContextConfiguration
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class ChainParserTests {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("filterInput")
|
||||
private MessageChannel filterInput;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("pollableInput1")
|
||||
private MessageChannel pollableInput1;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("pollableInput2")
|
||||
private MessageChannel pollableInput2;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("headerEnricherInput")
|
||||
private MessageChannel headerEnricherInput;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("output")
|
||||
private PollableChannel output;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("replyOutput")
|
||||
private PollableChannel replyOutput;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("beanInput")
|
||||
private MessageChannel beanInput;
|
||||
|
||||
@Autowired
|
||||
@Qualifier("aggregatorInput")
|
||||
private MessageChannel aggregatorInput;
|
||||
|
||||
@Autowired
|
||||
private MessageChannel payloadTypeRouterInput;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel strings;
|
||||
|
||||
@Autowired
|
||||
private PollableChannel numbers;
|
||||
|
||||
public static Message<?> successMessage = MessageBuilder.withPayload("success").build();
|
||||
|
||||
@Factory
|
||||
public static Matcher<Message<?>> sameExceptImmutableHeaders(Message<?> expected) {
|
||||
return new MessageMatcher(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainWithAcceptingFilter() {
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
this.filterInput.send(message);
|
||||
Message<?> reply = this.output.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("foo", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainWithRejectingFilter() {
|
||||
Message<?> message = MessageBuilder.withPayload(123).build();
|
||||
this.filterInput.send(message);
|
||||
Message<?> reply = this.output.receive(0);
|
||||
assertNull(reply);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainWithHeaderEnricher() {
|
||||
Message<?> message = MessageBuilder.withPayload(123).build();
|
||||
this.headerEnricherInput.send(message);
|
||||
Message<?> reply = this.replyOutput.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("foo", reply.getPayload());
|
||||
assertEquals("ABC", reply.getHeaders().getCorrelationId());
|
||||
assertEquals("XYZ", reply.getHeaders().get("testValue"));
|
||||
assertEquals(123, reply.getHeaders().get("testRef"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainWithPollableInput() {
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
this.pollableInput1.send(message);
|
||||
Message<?> reply = this.output.receive(3000);
|
||||
assertNotNull(reply);
|
||||
assertEquals("foo", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainWithPollerReference() {
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
this.pollableInput2.send(message);
|
||||
Message<?> reply = this.output.receive(3000);
|
||||
assertNotNull(reply);
|
||||
assertEquals("foo", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainHandlerBean() throws Exception {
|
||||
Message<?> message = MessageBuilder.withPayload("test").build();
|
||||
this.beanInput.send(message);
|
||||
Message<?> reply = this.output.receive(3000);
|
||||
assertNotNull(reply);
|
||||
assertThat(reply, sameExceptImmutableHeaders(successMessage));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void chainNestingAndAggregation() throws Exception {
|
||||
Message<?> message = MessageBuilder.withPayload("test").setCorrelationId(1).setSequenceSize(1).build();
|
||||
this.aggregatorInput.send(message);
|
||||
Message reply = this.output.receive(3000);
|
||||
assertNotNull(reply);
|
||||
assertEquals("foo", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void chainWithPayloadTypeRouter() throws Exception {
|
||||
Message<?> message1 = MessageBuilder.withPayload("test").build();
|
||||
Message<?> message2 = MessageBuilder.withPayload(123).build();
|
||||
this.payloadTypeRouterInput.send(message1);
|
||||
this.payloadTypeRouterInput.send(message2);
|
||||
Message<?> reply1 = this.strings.receive(0);
|
||||
Message<?> reply2 = this.numbers.receive(0);
|
||||
assertNotNull(reply1);
|
||||
assertNotNull(reply2);
|
||||
assertEquals("test", reply1.getPayload());
|
||||
assertEquals(123, reply2.getPayload());
|
||||
}
|
||||
|
||||
public static class StubHandler extends AbstractReplyProducingMessageHandler {
|
||||
@Override
|
||||
protected Object handleRequestMessage(Message<?> requestMessage) {
|
||||
return successMessage;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class StubAggregator {
|
||||
public String aggregate(List<String> strings) {
|
||||
return StringUtils.collectionToCommaDelimitedString(strings);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="queueChannel">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<outbound-channel-adapter id="outboundWithImplicitChannel" ref="consumer"/>
|
||||
|
||||
<outbound-channel-adapter id="methodInvokingConsumer" ref="testBean" method="store"/>
|
||||
|
||||
<inbound-channel-adapter id="methodInvokingSource" ref="testBean" method="getMessage" channel="queueChannel" auto-startup="false">
|
||||
<poller max-messages-per-poll="1">
|
||||
<interval-trigger interval="10000"/>
|
||||
</poller>
|
||||
</inbound-channel-adapter>
|
||||
|
||||
<beans:bean id="consumer" class="org.springframework.integration.config.TestConsumer"/>
|
||||
|
||||
<beans:bean id="testBean" class="org.springframework.integration.config.TestBean"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="queueChannel">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<inbound-channel-adapter id="methodInvokingSource" method="getMessage" channel="queueChannel" auto-startup="false">
|
||||
<poller max-messages-per-poll="1">
|
||||
<interval-trigger interval="10000"/>
|
||||
</poller>
|
||||
<beans:bean class="org.springframework.integration.config.ChannelAdapterParserTests$SampleBean"/>
|
||||
</inbound-channel-adapter>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,211 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.BeanFactoryChannelResolver;
|
||||
import org.springframework.integration.channel.ChannelResolutionException;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.endpoint.EventDrivenConsumer;
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
*/
|
||||
public class ChannelAdapterParserTests {
|
||||
|
||||
private AbstractApplicationContext applicationContext;
|
||||
private AbstractApplicationContext applicationContextInner;
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
this.applicationContext = new ClassPathXmlApplicationContext(
|
||||
"ChannelAdapterParserTests-context.xml", this.getClass());
|
||||
this.applicationContextInner = new ClassPathXmlApplicationContext(
|
||||
"ChannelAdapterParserTests-inner-context.xml", this.getClass());
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
this.applicationContext.close();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void methodInvokingSourceStoppedByApplicationContext() {
|
||||
String beanName = "methodInvokingSource";
|
||||
PollableChannel channel = (PollableChannel) this.applicationContext.getBean("queueChannel");
|
||||
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
|
||||
testBean.store("source test");
|
||||
Object adapter = this.applicationContext.getBean(beanName);
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof SourcePollingChannelAdapter);
|
||||
this.applicationContext.start();
|
||||
Message<?> message = channel.receive(1000);
|
||||
assertNotNull(message);
|
||||
assertEquals("source test", testBean.getMessage());
|
||||
this.applicationContext.stop();
|
||||
message = channel.receive(100);
|
||||
assertNull(message);
|
||||
}
|
||||
@Test
|
||||
public void methodInvokingSourceStoppedByApplicationContextInner() {
|
||||
String beanName = "methodInvokingSource";
|
||||
PollableChannel channel = (PollableChannel) this.applicationContextInner.getBean("queueChannel");
|
||||
// TestBean testBean = (TestBean) this.applicationContextInner.getBean("testBean");
|
||||
// testBean.store("source test");
|
||||
Object adapter = this.applicationContextInner.getBean(beanName);
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof SourcePollingChannelAdapter);
|
||||
this.applicationContextInner.start();
|
||||
Message<?> message = channel.receive(1000);
|
||||
assertNotNull(message);
|
||||
//assertEquals("source test", testBean.getMessage());
|
||||
this.applicationContextInner.stop();
|
||||
message = channel.receive(100);
|
||||
assertNull(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void targetOnly() {
|
||||
String beanName = "outboundWithImplicitChannel";
|
||||
Object channel = this.applicationContext.getBean(beanName);
|
||||
assertTrue(channel instanceof DirectChannel);
|
||||
BeanFactoryChannelResolver channelResolver = new BeanFactoryChannelResolver(this.applicationContext);
|
||||
assertNotNull(channelResolver.resolveChannelName(beanName));
|
||||
Object adapter = this.applicationContext.getBean(beanName + ".adapter");
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof EventDrivenConsumer);
|
||||
TestConsumer consumer = (TestConsumer) this.applicationContext.getBean("consumer");
|
||||
assertNull(consumer.getLastMessage());
|
||||
Message<?> message = new StringMessage("test");
|
||||
assertTrue(((MessageChannel) channel).send(message));
|
||||
assertNotNull(consumer.getLastMessage());
|
||||
assertEquals(message, consumer.getLastMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvokingConsumer() {
|
||||
String beanName = "methodInvokingConsumer";
|
||||
Object channel = this.applicationContext.getBean(beanName);
|
||||
assertTrue(channel instanceof DirectChannel);
|
||||
BeanFactoryChannelResolver channelResolver = new BeanFactoryChannelResolver(this.applicationContext);
|
||||
assertNotNull(channelResolver.resolveChannelName(beanName));
|
||||
Object adapter = this.applicationContext.getBean(beanName + ".adapter");
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof EventDrivenConsumer);
|
||||
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
|
||||
assertNull(testBean.getMessage());
|
||||
Message<?> message = new StringMessage("consumer test");
|
||||
assertTrue(((MessageChannel) channel).send(message));
|
||||
assertNotNull(testBean.getMessage());
|
||||
assertEquals("consumer test", testBean.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvokingSource() {
|
||||
String beanName = "methodInvokingSource";
|
||||
PollableChannel channel = (PollableChannel) this.applicationContext.getBean("queueChannel");
|
||||
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
|
||||
testBean.store("source test");
|
||||
Object adapter = this.applicationContext.getBean(beanName);
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof SourcePollingChannelAdapter);
|
||||
((SourcePollingChannelAdapter) adapter).start();
|
||||
Message<?> message = channel.receive(100);
|
||||
assertNotNull(message);
|
||||
assertEquals("source test", testBean.getMessage());
|
||||
((SourcePollingChannelAdapter) adapter).stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvokingSourceNotStarted() {
|
||||
String beanName = "methodInvokingSource";
|
||||
PollableChannel channel = (PollableChannel) this.applicationContext.getBean("queueChannel");
|
||||
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
|
||||
testBean.store("source test");
|
||||
Object adapter = this.applicationContext.getBean(beanName);
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof SourcePollingChannelAdapter);
|
||||
Message<?> message = channel.receive(100);
|
||||
assertNull(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvokingSourceStopped() {
|
||||
String beanName = "methodInvokingSource";
|
||||
PollableChannel channel = (PollableChannel) this.applicationContext.getBean("queueChannel");
|
||||
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
|
||||
testBean.store("source test");
|
||||
Object adapter = this.applicationContext.getBean(beanName);
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof SourcePollingChannelAdapter);
|
||||
((SourcePollingChannelAdapter) adapter).start();
|
||||
Message<?> message = channel.receive(1000);
|
||||
assertNotNull(message);
|
||||
assertEquals("source test", testBean.getMessage());
|
||||
((SourcePollingChannelAdapter) adapter).stop();
|
||||
message = channel.receive(100);
|
||||
assertNull(message);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void methodInvokingSourceStartedByApplicationContext() {
|
||||
String beanName = "methodInvokingSource";
|
||||
PollableChannel channel = (PollableChannel) this.applicationContext.getBean("queueChannel");
|
||||
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
|
||||
testBean.store("source test");
|
||||
Object adapter = this.applicationContext.getBean(beanName);
|
||||
assertNotNull(adapter);
|
||||
assertTrue(adapter instanceof SourcePollingChannelAdapter);
|
||||
this.applicationContext.start();
|
||||
Message<?> message = channel.receive(1000);
|
||||
assertNotNull(message);
|
||||
assertEquals("source test", testBean.getMessage());
|
||||
this.applicationContext.stop();
|
||||
}
|
||||
|
||||
@Test(expected = ChannelResolutionException.class)
|
||||
public void methodInvokingSourceAdapterIsNotChannel() {
|
||||
BeanFactoryChannelResolver channelResolver = new BeanFactoryChannelResolver(this.applicationContext);
|
||||
channelResolver.resolveChannelName("methodInvokingSource");
|
||||
}
|
||||
|
||||
public static class SampleBean{
|
||||
private String message = "hello";
|
||||
|
||||
String getMessage() {
|
||||
return message;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class CorrelationStrategyInvalidConfigurationTests {
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testCorrelationStrategyWithVoidReturningMethods() throws Exception {
|
||||
new ClassPathXmlApplicationContext("correlationStrategyWithVoidMethods.xml", CorrelationStrategyInvalidConfigurationTests.class);
|
||||
}
|
||||
|
||||
public static class VoidReturningCorrelationStrategy {
|
||||
|
||||
public void invalidCorrelationMethod(String string) {
|
||||
//do nothing
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.GenericMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class EndpointParserTests {
|
||||
|
||||
@Test
|
||||
public void testSimpleEndpoint() throws InterruptedException {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"simpleEndpointTests.xml", this.getClass());
|
||||
context.start();
|
||||
MessageChannel channel = (MessageChannel) context.getBean("testChannel");
|
||||
TestHandler handler = (TestHandler) context.getBean("testHandler");
|
||||
assertNull(handler.getMessageString());
|
||||
channel.send(new GenericMessage<String>("test"));
|
||||
handler.getLatch().await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("test", handler.getMessageString());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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;
|
||||
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.message.MessageHandlingException;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class ExceptionThrowingTestBean {
|
||||
|
||||
public void handle(Message<?> message) {
|
||||
throw new MessageHandlingException(message, "intentional test failure");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<channel id="adapterOutput">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<channel id="implementationOutput">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<channel id="discardOutput">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<channel id="discardAndExceptionOutput">
|
||||
<queue capacity="1"/>
|
||||
</channel>
|
||||
|
||||
<filter ref="selectorBean" method="hasText" input-channel="adapterInput" output-channel="adapterOutput"/>
|
||||
|
||||
<beans:bean id="selectorBean"
|
||||
class="org.springframework.integration.config.FilterParserTests$TestSelectorBean"/>
|
||||
|
||||
<filter ref="selectorImpl" input-channel="implementationInput" output-channel="implementationOutput"/>
|
||||
|
||||
<filter ref="selectorImpl" input-channel="exceptionInput" output-channel="implementationOutput" throw-exception-on-rejection="true"/>
|
||||
|
||||
<beans:bean id="selectorImpl"
|
||||
class="org.springframework.integration.config.FilterParserTests$TestSelectorImpl"/>
|
||||
|
||||
<filter ref="selectorBean"
|
||||
method="hasText"
|
||||
input-channel="discardInput"
|
||||
output-channel="adapterOutput"
|
||||
discard-channel="discardOutput"/>
|
||||
|
||||
<filter ref="selectorBean"
|
||||
method="hasText"
|
||||
input-channel="discardAndExceptionInput"
|
||||
output-channel="adapterOutput"
|
||||
discard-channel="discardAndExceptionOutput"
|
||||
throw-exception-on-rejection="true"/>
|
||||
|
||||
</beans:beans>
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.integration.channel.PollableChannel;
|
||||
import org.springframework.integration.core.Message;
|
||||
import org.springframework.integration.core.MessageChannel;
|
||||
import org.springframework.integration.message.MessageRejectedException;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.integration.selector.MessageSelector;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration
|
||||
public class FilterParserTests {
|
||||
|
||||
@Autowired @Qualifier("adapterInput")
|
||||
MessageChannel adapterInput;
|
||||
|
||||
@Autowired @Qualifier("adapterOutput")
|
||||
PollableChannel adapterOutput;
|
||||
|
||||
@Autowired @Qualifier("implementationInput")
|
||||
MessageChannel implementationInput;
|
||||
|
||||
@Autowired @Qualifier("implementationOutput")
|
||||
PollableChannel implementationOutput;
|
||||
|
||||
@Autowired @Qualifier("exceptionInput")
|
||||
MessageChannel exceptionInput;
|
||||
|
||||
@Autowired @Qualifier("discardInput")
|
||||
MessageChannel discardInput;
|
||||
|
||||
@Autowired @Qualifier("discardOutput")
|
||||
PollableChannel discardOutput;
|
||||
|
||||
@Autowired @Qualifier("discardAndExceptionInput")
|
||||
MessageChannel discardAndExceptionInput;
|
||||
|
||||
@Autowired @Qualifier("discardAndExceptionOutput")
|
||||
PollableChannel discardAndExceptionOutput;
|
||||
|
||||
|
||||
@Test
|
||||
public void filterWithSelectorAdapterAccepts() {
|
||||
adapterInput.send(new StringMessage("test"));
|
||||
Message<?> reply = adapterOutput.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterWithSelectorAdapterRejects() {
|
||||
adapterInput.send(new StringMessage(""));
|
||||
Message<?> reply = adapterOutput.receive(0);
|
||||
assertNull(reply);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterWithSelectorImplementationAccepts() {
|
||||
implementationInput.send(new StringMessage("test"));
|
||||
Message<?> reply = implementationOutput.receive(0);
|
||||
assertNotNull(reply);
|
||||
assertEquals("test", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterWithSelectorImplementationRejects() {
|
||||
implementationInput.send(new StringMessage(""));
|
||||
Message<?> reply = implementationOutput.receive(0);
|
||||
assertNull(reply);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void exceptionThrowingFilterAccepts() {
|
||||
exceptionInput.send(new StringMessage("test"));
|
||||
Message<?> reply = implementationOutput.receive(0);
|
||||
assertNotNull(reply);
|
||||
}
|
||||
|
||||
@Test(expected = MessageRejectedException.class)
|
||||
public void exceptionThrowingFilterRejects() {
|
||||
exceptionInput.send(new StringMessage(""));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void filterWithDiscardChannel() {
|
||||
discardInput.send(new StringMessage(""));
|
||||
Message<?> discard = discardOutput.receive(0);
|
||||
assertNotNull(discard);
|
||||
assertEquals("", discard.getPayload());
|
||||
assertNull(adapterOutput.receive(0));
|
||||
}
|
||||
|
||||
@Test(expected = MessageRejectedException.class)
|
||||
public void filterWithDiscardChannelAndException() throws Exception {
|
||||
Exception exception = null;
|
||||
try {
|
||||
discardAndExceptionInput.send(new StringMessage(""));
|
||||
}
|
||||
catch (Exception e) {
|
||||
exception = e;
|
||||
}
|
||||
Message<?> discard = discardAndExceptionOutput.receive(0);
|
||||
assertNotNull(discard);
|
||||
assertEquals("", discard.getPayload());
|
||||
assertNull(adapterOutput.receive(0));
|
||||
throw exception;
|
||||
}
|
||||
|
||||
|
||||
public static class TestSelectorBean {
|
||||
|
||||
public boolean hasText(String s) {
|
||||
return StringUtils.hasText(s);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static class TestSelectorImpl implements MessageSelector {
|
||||
|
||||
public boolean accept(Message<?> message) {
|
||||
if (message != null && message.getPayload() instanceof String) {
|
||||
return StringUtils.hasText((String) message.getPayload());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2002-2008 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;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class MaxValueReleaseStrategy {
|
||||
|
||||
private long maxValue;
|
||||
|
||||
|
||||
public MaxValueReleaseStrategy(long maxValue){
|
||||
this.maxValue = maxValue;
|
||||
}
|
||||
|
||||
public boolean checkCompleteness(List<Long> numbers) {
|
||||
int sum = 0;
|
||||
for (long number: numbers) {
|
||||
sum += number;
|
||||
}
|
||||
return sum >= maxValue;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2002-2009 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.event.SimpleApplicationEventMulticaster;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.SpringVersion;
|
||||
import org.springframework.core.task.SyncTaskExecutor;
|
||||
import org.springframework.integration.channel.BeanFactoryChannelResolver;
|
||||
import org.springframework.integration.context.IntegrationContextUtils;
|
||||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
* @author Marius Bogoevici
|
||||
*/
|
||||
public class MessageBusParserTests {
|
||||
|
||||
@Test
|
||||
public void testErrorChannelReference() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithErrorChannel.xml", this.getClass());
|
||||
BeanFactoryChannelResolver resolver = new BeanFactoryChannelResolver(context);
|
||||
assertEquals(context.getBean("errorChannel"), resolver.resolveChannelName("errorChannel"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultErrorChannel() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithDefaults.xml", this.getClass());
|
||||
BeanFactoryChannelResolver resolver = new BeanFactoryChannelResolver(context);
|
||||
assertEquals(context.getBean("errorChannel"), resolver.resolveChannelName("errorChannel"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMulticasterIsSyncByDefault() {
|
||||
ApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithDefaults.xml", this.getClass());
|
||||
SimpleApplicationEventMulticaster multicaster = (SimpleApplicationEventMulticaster)
|
||||
context.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(multicaster);
|
||||
Object taskExecutor = accessor.getPropertyValue("taskExecutor");
|
||||
if (SpringVersion.getVersion().startsWith("2")) {
|
||||
assertEquals(SyncTaskExecutor.class, taskExecutor.getClass());
|
||||
}
|
||||
else {
|
||||
assertNull(taskExecutor);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncMulticasterExplicitlySetToFalse() throws Exception {
|
||||
AbstractApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithoutAsyncEventMulticaster.xml", this.getClass());
|
||||
context.refresh();
|
||||
SimpleApplicationEventMulticaster multicaster = (SimpleApplicationEventMulticaster)
|
||||
context.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(multicaster);
|
||||
Object taskExecutor = accessor.getPropertyValue("taskExecutor");
|
||||
if (SpringVersion.getVersion().startsWith("2")) {
|
||||
assertEquals(SyncTaskExecutor.class, taskExecutor.getClass());
|
||||
}
|
||||
else {
|
||||
assertNull(taskExecutor);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAsyncMulticaster() throws Exception {
|
||||
AbstractApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithAsyncEventMulticaster.xml", this.getClass());
|
||||
context.refresh();
|
||||
SimpleApplicationEventMulticaster multicaster = (SimpleApplicationEventMulticaster)
|
||||
context.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(multicaster);
|
||||
Object taskExecutor = accessor.getPropertyValue("taskExecutor");
|
||||
assertEquals(ThreadPoolTaskExecutor.class, taskExecutor.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitlyDefinedTaskSchedulerHasCorrectType() {
|
||||
AbstractApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithTaskScheduler.xml", this.getClass());
|
||||
TaskScheduler scheduler = (TaskScheduler) context.getBean("taskScheduler");
|
||||
assertEquals(StubTaskScheduler.class, scheduler.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExplicitlyDefinedTaskSchedulerMatchesUtilLookup() {
|
||||
AbstractApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"messageBusWithTaskScheduler.xml", this.getClass());
|
||||
TaskScheduler scheduler = (TaskScheduler) context.getBean("taskScheduler");
|
||||
assertEquals(scheduler, IntegrationContextUtils.getTaskScheduler(context));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2002-2010 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;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.integration.channel.PublishSubscribeChannel;
|
||||
import org.springframework.integration.dispatcher.BroadcastingDispatcher;
|
||||
import org.springframework.integration.util.ErrorHandlingTaskExecutor;
|
||||
import org.springframework.util.ErrorHandler;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class PublishSubscribeChannelParserTests {
|
||||
|
||||
@Test
|
||||
public void defaultChannel() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("defaultChannel");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
|
||||
accessor.getPropertyValue("dispatcher");
|
||||
DirectFieldAccessor dispatcherAccessor = new DirectFieldAccessor(dispatcher);
|
||||
assertNull(dispatcherAccessor.getPropertyValue("executor"));
|
||||
assertFalse((Boolean) dispatcherAccessor.getPropertyValue("ignoreFailures"));
|
||||
assertFalse((Boolean) dispatcherAccessor.getPropertyValue("applySequence"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreFailures() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("channelWithIgnoreFailures");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
|
||||
accessor.getPropertyValue("dispatcher");
|
||||
assertTrue((Boolean) new DirectFieldAccessor(dispatcher).getPropertyValue("ignoreFailures"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applySequenceEnabled() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("channelWithApplySequenceEnabled");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
|
||||
accessor.getPropertyValue("dispatcher");
|
||||
assertTrue((Boolean) new DirectFieldAccessor(dispatcher).getPropertyValue("applySequence"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelWithTaskExecutor() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("channelWithTaskExecutor");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
|
||||
accessor.getPropertyValue("dispatcher");
|
||||
DirectFieldAccessor dispatcherAccessor = new DirectFieldAccessor(dispatcher);
|
||||
Executor executor = (Executor) dispatcherAccessor.getPropertyValue("executor");
|
||||
assertNotNull(executor);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executor.getClass());
|
||||
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
|
||||
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
|
||||
assertEquals(context.getBean("pool"), innerExecutor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void ignoreFailuresWithTaskExecutor() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("channelWithIgnoreFailuresAndTaskExecutor");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
|
||||
accessor.getPropertyValue("dispatcher");
|
||||
DirectFieldAccessor dispatcherAccessor = new DirectFieldAccessor(dispatcher);
|
||||
assertTrue((Boolean) dispatcherAccessor.getPropertyValue("ignoreFailures"));
|
||||
Executor executor = (Executor) dispatcherAccessor.getPropertyValue("executor");
|
||||
assertNotNull(executor);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executor.getClass());
|
||||
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
|
||||
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
|
||||
assertEquals(context.getBean("pool"), innerExecutor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void applySequenceEnabledWithTaskExecutor() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("channelWithApplySequenceEnabledAndTaskExecutor");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
BroadcastingDispatcher dispatcher = (BroadcastingDispatcher)
|
||||
accessor.getPropertyValue("dispatcher");
|
||||
DirectFieldAccessor dispatcherAccessor = new DirectFieldAccessor(dispatcher);
|
||||
assertTrue((Boolean) dispatcherAccessor.getPropertyValue("applySequence"));
|
||||
Executor executor = (Executor) dispatcherAccessor.getPropertyValue("executor");
|
||||
assertNotNull(executor);
|
||||
assertEquals(ErrorHandlingTaskExecutor.class, executor.getClass());
|
||||
DirectFieldAccessor executorAccessor = new DirectFieldAccessor(executor);
|
||||
Executor innerExecutor = (Executor) executorAccessor.getPropertyValue("executor");
|
||||
assertEquals(context.getBean("pool"), innerExecutor);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void channelWithErrorHandler() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
|
||||
"publishSubscribeChannelParserTests.xml", this.getClass());
|
||||
PublishSubscribeChannel channel = (PublishSubscribeChannel)
|
||||
context.getBean("channelWithErrorHandler");
|
||||
DirectFieldAccessor accessor = new DirectFieldAccessor(channel);
|
||||
ErrorHandler errorHandler = (ErrorHandler) accessor.getPropertyValue("errorHandler");
|
||||
assertNotNull(errorHandler);
|
||||
assertEquals(context.getBean("testErrorHandler"), errorHandler);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans:beans xmlns="http://www.springframework.org/schema/integration"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xmlns:beans="http://www.springframework.org/schema/beans"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans
|
||||
http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/integration
|
||||
http://www.springframework.org/schema/integration/spring-integration.xsd">
|
||||
|
||||
<aggregator id="aggregator" ref="adderBean" method="add" release-strategy="testReleaseStrategy"
|
||||
input-channel="input-channel" output-channel="replyChannel">
|
||||
</aggregator>
|
||||
|
||||
<channel id="inputChannel"/>
|
||||
<channel id="replyChannel"/>
|
||||
|
||||
<beans:bean id="adderBean" class="org.springframework.integration.config.Adder"/>
|
||||
|
||||
<beans:bean id="ReleaseStrategyBean" class="org.springframework.integration.config.TestReleaseStrategy"/>
|
||||
|
||||
</beans:beans>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user