Added Aggregator, AggregatingMessageHandler, RoutingBarrier, RoutingBarrierCompletionStrategy, and related classes.
This commit is contained in:
@@ -173,7 +173,7 @@ public class DefaultMessageEndpointTests {
|
||||
endpoint.start();
|
||||
endpoint.handle(new StringMessage(1, "test"));
|
||||
endpoint.stop();
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have been invoked within allotted time", 0, latch.getCount());
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull(reply);
|
||||
@@ -199,7 +199,7 @@ public class DefaultMessageEndpointTests {
|
||||
endpoint.start();
|
||||
endpoint.handle(new StringMessage(1, "test"));
|
||||
endpoint.stop();
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have been invoked within allotted time", 0, latch.getCount());
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
assertNull(reply);
|
||||
@@ -224,7 +224,7 @@ public class DefaultMessageEndpointTests {
|
||||
endpoint.start();
|
||||
endpoint.handle(new StringMessage(1, "test"));
|
||||
endpoint.stop();
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have been invoked within allotted time", 0, latch.getCount());
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
assertNull(reply);
|
||||
@@ -250,7 +250,7 @@ public class DefaultMessageEndpointTests {
|
||||
message.getHeader().setReplyChannelName("replyChannel");
|
||||
endpoint.handle(message);
|
||||
endpoint.stop();
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have been invoked within allotted time", 0, latch.getCount());
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull(reply);
|
||||
@@ -277,7 +277,7 @@ public class DefaultMessageEndpointTests {
|
||||
endpoint.start();
|
||||
endpoint.handle(new StringMessage(1, "test"));
|
||||
endpoint.stop();
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have been invoked within allotted time", 0, latch.getCount());
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull(reply);
|
||||
@@ -305,7 +305,7 @@ public class DefaultMessageEndpointTests {
|
||||
message.getHeader().setReplyChannelName("replyChannel");
|
||||
endpoint.handle(message);
|
||||
endpoint.stop();
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
assertEquals("handler should have been invoked within allotted time", 0, latch.getCount());
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull(reply);
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
/*
|
||||
* 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.router;
|
||||
|
||||
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.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.channel.MessageChannel;
|
||||
import org.springframework.integration.channel.SimpleChannel;
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class AggregatingMessageHandlerTests {
|
||||
|
||||
private final ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
|
||||
|
||||
|
||||
public AggregatingMessageHandlerTests() {
|
||||
this.executor.setMaxPoolSize(10);
|
||||
this.executor.setQueueCapacity(0);
|
||||
this.executor.afterPropertiesSet();
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void testCompleteGroupWithinTimeout() throws InterruptedException {
|
||||
AggregatingMessageHandler aggregator = new AggregatingMessageHandler(new TestAggregator());
|
||||
SimpleChannel replyChannel = new SimpleChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 3, 1, replyChannel);
|
||||
Message<?> message2 = createMessage("456", "ABC", 3, 2, replyChannel);
|
||||
Message<?> message3 = createMessage("789", "ABC", 3, 3, replyChannel);
|
||||
CountDownLatch latch = new CountDownLatch(3);
|
||||
executor.execute(new AggregatorTestTask(aggregator, message1, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message2, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message3, latch));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull(reply);
|
||||
assertEquals("123456789", reply.getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldFailOnTimeoutByDefault() throws InterruptedException {
|
||||
AggregatingMessageHandler aggregator = new AggregatingMessageHandler(new TestAggregator());
|
||||
aggregator.setTimeout(10);
|
||||
SimpleChannel replyChannel = new SimpleChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 2, 1, replyChannel);
|
||||
CountDownLatch latch = new CountDownLatch(1);
|
||||
AggregatorTestTask task = new AggregatorTestTask(aggregator, message1, latch);
|
||||
executor.execute(task);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
assertNull(reply);
|
||||
assertNotNull(task.getException());
|
||||
assertEquals(MessageHandlingException.class, task.getException().getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testShouldFailOnTimeoutFalse() throws InterruptedException {
|
||||
AggregatingMessageHandler aggregator = new AggregatingMessageHandler(new TestAggregator());
|
||||
aggregator.setTimeout(10);
|
||||
aggregator.setShouldFailOnTimeout(false);
|
||||
SimpleChannel replyChannel = new SimpleChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 3, 1, replyChannel);
|
||||
Message<?> message2 = createMessage("456", "ABC", 3, 2, replyChannel);
|
||||
CountDownLatch latch = new CountDownLatch(2);
|
||||
AggregatorTestTask task1 = new AggregatorTestTask(aggregator, message1, latch);
|
||||
AggregatorTestTask task2 = new AggregatorTestTask(aggregator, message2, latch);
|
||||
executor.execute(task1);
|
||||
executor.execute(task2);
|
||||
latch.await(500, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
assertNotNull(reply);
|
||||
assertEquals("123456", reply.getPayload());
|
||||
assertNull(task1.getException());
|
||||
assertNull(task2.getException());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMultipleGroupsSimultaneously() throws InterruptedException {
|
||||
AggregatingMessageHandler aggregator = new AggregatingMessageHandler(new TestAggregator());
|
||||
SimpleChannel replyChannel1 = new SimpleChannel();
|
||||
SimpleChannel replyChannel2 = new SimpleChannel();
|
||||
Message<?> message1 = createMessage("123", "ABC", 3, 1, replyChannel1);
|
||||
Message<?> message2 = createMessage("456", "ABC", 3, 2, replyChannel1);
|
||||
Message<?> message3 = createMessage("789", "ABC", 3, 3, replyChannel1);
|
||||
Message<?> message4 = createMessage("abc", "XYZ", 3, 1, replyChannel2);
|
||||
Message<?> message5 = createMessage("def", "XYZ", 3, 2, replyChannel2);
|
||||
Message<?> message6 = createMessage("ghi", "XYZ", 3, 3, replyChannel2);
|
||||
CountDownLatch latch = new CountDownLatch(6);
|
||||
executor.execute(new AggregatorTestTask(aggregator, message1, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message6, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message2, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message5, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message3, latch));
|
||||
executor.execute(new AggregatorTestTask(aggregator, message4, latch));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply1 = replyChannel1.receive(500);
|
||||
assertNotNull(reply1);
|
||||
assertEquals("123456789", reply1.getPayload());
|
||||
Message<?> reply2 = replyChannel2.receive(500);
|
||||
assertNotNull(reply2);
|
||||
assertEquals("abcdefghi", reply2.getPayload());
|
||||
}
|
||||
|
||||
|
||||
private static Message<?> createMessage(String payload, Object correlationId,
|
||||
int sequenceSize, int sequenceNumber, MessageChannel replyChannel) {
|
||||
StringMessage message = new StringMessage(payload);
|
||||
message.getHeader().setCorrelationId(correlationId);
|
||||
message.getHeader().setSequenceSize(sequenceSize);
|
||||
message.getHeader().setSequenceNumber(sequenceNumber);
|
||||
message.getHeader().setReplyChannel(replyChannel);
|
||||
return message;
|
||||
}
|
||||
|
||||
|
||||
private static class TestAggregator implements Aggregator {
|
||||
|
||||
public Message<?> aggregate(List<Message<?>> messages) {
|
||||
List<Message<?>> sortableList = new ArrayList<Message<?>>(messages);
|
||||
Collections.sort(sortableList, new MessageSequenceComparator());
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
for (Message<?> message : sortableList) {
|
||||
buffer.append(message.getPayload().toString());
|
||||
}
|
||||
return new StringMessage(buffer.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static class AggregatorTestTask implements Runnable {
|
||||
|
||||
private AggregatingMessageHandler aggregator;
|
||||
|
||||
private Message<?> message;
|
||||
|
||||
private Exception exception;
|
||||
|
||||
private CountDownLatch latch;
|
||||
|
||||
|
||||
AggregatorTestTask(AggregatingMessageHandler aggregator, Message<?> message, CountDownLatch latch) {
|
||||
this.aggregator = aggregator;
|
||||
this.message = message;
|
||||
this.latch = latch;
|
||||
}
|
||||
|
||||
public Exception getException() {
|
||||
return this.exception;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
Message<?> result = this.aggregator.handle(message);
|
||||
if (result != null) {
|
||||
message.getHeader().getReplyChannel().send(result);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
this.exception = e;
|
||||
}
|
||||
finally {
|
||||
this.latch.countDown();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.router;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class MessageSequenceComparatorTests {
|
||||
|
||||
@Test
|
||||
public void testLessThan() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
message1.getHeader().setSequenceNumber(1);
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
message2.getHeader().setSequenceNumber(2);
|
||||
assertEquals(-1, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqual() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
message1.getHeader().setSequenceNumber(3);
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
message2.getHeader().setSequenceNumber(3);
|
||||
assertEquals(0, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGreaterThan() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
message1.getHeader().setSequenceNumber(5);
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
message2.getHeader().setSequenceNumber(3);
|
||||
assertEquals(1, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEqualWithDefaultValues() {
|
||||
MessageSequenceComparator comparator = new MessageSequenceComparator();
|
||||
StringMessage message1 = new StringMessage("test1");
|
||||
StringMessage message2 = new StringMessage("test2");
|
||||
assertEquals(0, comparator.compare(message1, message2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* 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.router;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class RoutingBarrierTests {
|
||||
|
||||
@Test
|
||||
public void testBasicCompletionCheck() {
|
||||
RoutingBarrier barrier = new RoutingBarrier(new TwoMessageCompletionStrategy());
|
||||
barrier.addMessage(new StringMessage("test1"));
|
||||
assertFalse(barrier.isComplete());
|
||||
barrier.addMessage(new StringMessage("test2"));
|
||||
assertTrue(barrier.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageRetrieval() {
|
||||
RoutingBarrier barrier = new RoutingBarrier(new TwoMessageCompletionStrategy());
|
||||
barrier.addMessage(new StringMessage("test1"));
|
||||
assertEquals(1, barrier.getMessages().size());
|
||||
barrier.addMessage(new StringMessage("test2"));
|
||||
assertEquals(2, barrier.getMessages().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWaitForCompletionTimesOut() {
|
||||
RoutingBarrier barrier = new RoutingBarrier(new TwoMessageCompletionStrategy());
|
||||
barrier.addMessage(new StringMessage("test1"));
|
||||
assertFalse(barrier.isComplete());
|
||||
assertFalse(barrier.waitForCompletion(10));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWaitForCompletionReturnsTrueImmediately() {
|
||||
RoutingBarrier barrier = new RoutingBarrier(new TwoMessageCompletionStrategy());
|
||||
barrier.addMessage(new StringMessage("test1"));
|
||||
assertFalse(barrier.isComplete());
|
||||
barrier.addMessage(new StringMessage("test2"));
|
||||
assertTrue(barrier.waitForCompletion(0));
|
||||
assertTrue(barrier.isComplete());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyMessageList() {
|
||||
RoutingBarrier barrier = new RoutingBarrier(new TwoMessageCompletionStrategy());
|
||||
assertFalse(barrier.isComplete());
|
||||
assertFalse(barrier.waitForCompletion(0));
|
||||
assertEquals(0, barrier.getMessages().size());
|
||||
}
|
||||
|
||||
|
||||
private static class TwoMessageCompletionStrategy implements RoutingBarrierCompletionStrategy {
|
||||
|
||||
public boolean isComplete(List<Message<?>> messages) {
|
||||
return (messages.size() == 2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.router;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.integration.message.Message;
|
||||
import org.springframework.integration.message.StringMessage;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
*/
|
||||
public class SequenceSizeCompletionStrategyTests {
|
||||
|
||||
@Test
|
||||
public void testIncompleteList() {
|
||||
Message<?> message = new StringMessage("test1");
|
||||
message.getHeader().setSequenceSize(2);
|
||||
List<Message<?>> messages = new ArrayList<Message<?>>();
|
||||
messages.add(message);
|
||||
SequenceSizeCompletionStrategy completionStrategy = new SequenceSizeCompletionStrategy();
|
||||
assertFalse(completionStrategy.isComplete(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCompleteList() {
|
||||
Message<?> message1 = new StringMessage("test1");
|
||||
message1.getHeader().setSequenceSize(2);
|
||||
Message<?> message2 = new StringMessage("test2");
|
||||
message2.getHeader().setSequenceSize(2);
|
||||
List<Message<?>> messages = new ArrayList<Message<?>>();
|
||||
messages.add(message1);
|
||||
messages.add(message2);
|
||||
SequenceSizeCompletionStrategy completionStrategy = new SequenceSizeCompletionStrategy();
|
||||
assertTrue(completionStrategy.isComplete(messages));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEmptyList() {
|
||||
SequenceSizeCompletionStrategy completionStrategy = new SequenceSizeCompletionStrategy();
|
||||
assertFalse(completionStrategy.isComplete(new ArrayList<Message<?>>()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNullList() {
|
||||
SequenceSizeCompletionStrategy completionStrategy = new SequenceSizeCompletionStrategy();
|
||||
assertFalse(completionStrategy.isComplete(null));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user