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:
Chris Beams
2010-05-25 13:21:25 +00:00
parent b97b2fb090
commit c08a7a657e
1484 changed files with 18 additions and 23 deletions

View File

@@ -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();
}
}
}

View File

@@ -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>

View File

@@ -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"));
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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();
}
}

View File

@@ -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();
}
}

View File

@@ -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));
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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();
}
}

View File

@@ -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")));
}
}

View File

@@ -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")));
}
}

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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;
}
}

View File

@@ -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>

View File

@@ -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();
}
}
}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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";
}
}
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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) {
}
}

View File

@@ -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";
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -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>

View File

@@ -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");
}
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}
}
}
}

View File

@@ -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");
}
}
}

View File

@@ -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();
}
}
}

View File

@@ -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);
}
}

View File

@@ -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"));
}
}

View File

@@ -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());
}
}

View File

@@ -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>

View File

@@ -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*/}
}
}
}

View File

@@ -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);
}
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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));
}
}

View File

@@ -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>

View File

@@ -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());
}
}

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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);
}
}

View File

@@ -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>

View File

@@ -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 &lt;queue/> element under
* &lt;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));
}
}

View File

@@ -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>

View File

@@ -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);
}
}

View File

@@ -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());
}
}

View File

@@ -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);
}
}

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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());
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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();
}
}
}

View File

@@ -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>

View File

@@ -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();
}
}

View File

@@ -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>

View File

@@ -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);
}
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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());
}
}

View File

@@ -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");
}
}

View File

@@ -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>

View File

@@ -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;
}
}
}

View File

@@ -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;
}
}

View File

@@ -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));
}
}

View File

@@ -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);
}
}

View File

@@ -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