INT-818: EL-based aggregator

* adapted some code from patch to new idioms
* added namespace support
* tidied up *Adapter -> MethodInvoking* for consistency
This commit is contained in:
David Syer
2010-07-29 08:56:20 +00:00
parent a5c14782fb
commit d92a1245d3
28 changed files with 728 additions and 165 deletions

View File

@@ -39,32 +39,32 @@ public class CorrelationStrategyAdapterTests {
@Test
public void testMethodName() {
CorrelationStrategyAdapter adapter = new CorrelationStrategyAdapter(new SimpleMessageCorrelator(), "getKey");
MethodInvokingCorrelationStrategy adapter = new MethodInvokingCorrelationStrategy(new SimpleMessageCorrelator(), "getKey");
assertEquals("b", adapter.getCorrelationKey(message));
}
@Test
public void testCorrelationStrategyAdapterObjectMethod() {
CorrelationStrategyAdapter adapter = new CorrelationStrategyAdapter(new SimpleMessageCorrelator(),
MethodInvokingCorrelationStrategy adapter = new MethodInvokingCorrelationStrategy(new SimpleMessageCorrelator(),
ReflectionUtils.findMethod(SimpleMessageCorrelator.class, "getKey", Message.class));
assertEquals("b", adapter.getCorrelationKey(message));
}
@Test
public void testCorrelationStrategyAdapterPojoMethod() {
CorrelationStrategyAdapter adapter = new CorrelationStrategyAdapter(new SimplePojoCorrelator(), "getKey");
MethodInvokingCorrelationStrategy adapter = new MethodInvokingCorrelationStrategy(new SimplePojoCorrelator(), "getKey");
assertEquals("foo", adapter.getCorrelationKey(message));
}
@Test
public void testHeaderPojoMethod() {
CorrelationStrategyAdapter adapter = new CorrelationStrategyAdapter(new SimpleHeaderCorrelator(), "getKey");
MethodInvokingCorrelationStrategy adapter = new MethodInvokingCorrelationStrategy(new SimpleHeaderCorrelator(), "getKey");
assertEquals("b", adapter.getCorrelationKey(message));
}
@Test
public void testHeadersPojoMethod() {
CorrelationStrategyAdapter adapter = new CorrelationStrategyAdapter(new MultiHeaderCorrelator(),
MethodInvokingCorrelationStrategy adapter = new MethodInvokingCorrelationStrategy(new MultiHeaderCorrelator(),
ReflectionUtils.findMethod(MultiHeaderCorrelator.class, "getKey", String.class, String.class));
assertEquals("bd", adapter.getCorrelationKey(message));
}

View File

@@ -0,0 +1,34 @@
package org.springframework.integration.aggregator;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Test;
import org.springframework.integration.core.GenericMessage;
/**
* @author Alex Peters
*
*/
public class ExpressionEvaluatingCorrelationStrategyTests {
private ExpressionEvaluatingCorrelationStrategy strategy;
@Test(expected = IllegalArgumentException.class)
public void testCreateInstanceWithEmptyExpressionFails() throws Exception {
strategy = new ExpressionEvaluatingCorrelationStrategy("");
}
@Test(expected = IllegalArgumentException.class)
public void testCreateInstanceWithNullExpressionFails() throws Exception {
strategy = new ExpressionEvaluatingCorrelationStrategy(null);
}
@Test
public void testCorrelationKeyWithMethodInvokingExpression() throws Exception {
strategy = new ExpressionEvaluatingCorrelationStrategy("payload.substring(0,1)");
Object correlationKey = strategy.getCorrelationKey(new GenericMessage<String>("bla"));
assertThat(correlationKey, is(String.class));
assertThat((String) correlationKey, is("b"));
}
}

View File

@@ -0,0 +1,143 @@
package org.springframework.integration.aggregator;
import static org.junit.matchers.JUnitMatchers.hasItems;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeMatcher;
import org.hamcrest.core.IsEqual;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Matchers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.integration.Message;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.store.MessageGroup;
/**
* @author Alex Peters
*
*/
@RunWith(MockitoJUnitRunner.class)
public class ExpressionEvaluatingMessageGroupProcessorTests {
private ExpressionEvaluatingMessageGroupProcessor processor;
private MessagingTemplate template = new MessagingTemplate();
@Mock
private MessageChannel outputChannel;
@Mock
private MessageGroup group;
List<Message<?>> messages = new ArrayList<Message<?>>();
@Before
@SuppressWarnings("unchecked")
public void setup() {
messages.clear();
for (int i = 0; i < 5; i++) {
messages.add(new GenericMessage(i + 1));
}
}
@Test
public void testProcessAndSendWithSizeExpressionEvaluated() throws Exception {
when(group.getUnmarked()).thenReturn(messages);
processor = new ExpressionEvaluatingMessageGroupProcessor("#root.size()");
processor.processAndSend(group, template, outputChannel);
verify(outputChannel).send(messageWithPayload(5));
}
@Test
public void testProcessAndSendWithProjectionExpressionEvaluated() throws Exception {
when(group.getUnmarked()).thenReturn(messages);
processor = new ExpressionEvaluatingMessageGroupProcessor("![payload]");
processor.processAndSend(group, template, outputChannel);
verify(outputChannel).send(messageWithPayload(hasItems(1, 2, 3, 4, 5)));
}
@Test
public void testProcessAndSendWithFilterAndProjectionExpressionEvaluated() throws Exception {
when(group.getUnmarked()).thenReturn(messages);
processor = new ExpressionEvaluatingMessageGroupProcessor("?[payload>2].![payload]");
processor.processAndSend(group, template, outputChannel);
verify(outputChannel).send(messageWithPayload(hasItems(3, 4, 5)));
}
@Test
public void testProcessAndSendWithFilterAndProjectionAndMethodInvokingExpressionEvaluated() throws Exception {
when(group.getUnmarked()).thenReturn(messages);
processor = new ExpressionEvaluatingMessageGroupProcessor(String.format("T(%s).sum(?[payload>2].![payload])",
getClass().getName()));
processor.processAndSend(group, template, outputChannel);
verify(outputChannel).send(messageWithPayload(3 + 4 + 5));
}
private Message<?> messageWithPayload(Matcher<?> matcher) {
return Matchers.argThat(PayloadMatcher.hasPayload(matcher));
}
private Message<?> messageWithPayload(int i) {
return Matchers.argThat(PayloadMatcher.hasPayload(IsEqual.equalTo(i)));
}
/*
* sample static method invoked by SpEL
*/
public static Integer sum(Collection<Integer> values) {
int result = 0;
for (Integer value : values) {
result += value;
}
return result;
}
private static class PayloadMatcher extends TypeSafeMatcher<Message<?>> {
private final Matcher<?> matcher;
/**
* @param matcher
*/
PayloadMatcher(Matcher<?> matcher) {
super();
this.matcher = matcher;
}
/**
* {@inheritDoc}
*/
@Override
public boolean matchesSafely(Message<?> message) {
return matcher.matches(message.getPayload());
}
/**
* {@inheritDoc}
*/
//@Override
public void describeTo(Description description) {
description.appendText("a Message with payload: ").appendDescriptionOf(matcher);
}
@Factory
public static <T> Matcher<Message<?>> hasPayload(Matcher<T> payloadMatcher) {
return new PayloadMatcher(payloadMatcher);
}
}
}

View File

@@ -0,0 +1,48 @@
package org.springframework.integration.aggregator;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import org.junit.Before;
import org.junit.Test;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.store.SimpleMessageGroup;
/**
* @author Alex Peters
* @author Dave Syer
*
*/
public class ExpressionEvaluatingReleaseStrategyTests {
private ExpressionEvaluatingReleaseStrategy strategy;
private SimpleMessageGroup messages = new SimpleMessageGroup("foo");
@Before
@SuppressWarnings("unchecked")
public void setup() {
for (int i = 0; i < 5; i++) {
messages.add(new GenericMessage(i + 1));
}
}
@Test
public void testCompletedWithSizeSpelEvaluated() throws Exception {
strategy = new ExpressionEvaluatingReleaseStrategy("#root.size()==5");
assertThat(strategy.canRelease(messages), is(true));
}
@Test
public void testCompletedWithFilterSpelEvaluated() throws Exception {
strategy = new ExpressionEvaluatingReleaseStrategy("!?[payload==5].empty");
assertThat(strategy.canRelease(messages), is(true));
}
@Test
public void testCompletedWithFilterSpelReturnsNotCompleted() throws Exception {
strategy = new ExpressionEvaluatingReleaseStrategy("!?[payload==6].empty");
assertThat(strategy.canRelease(messages), is(false));
}
}

View File

@@ -42,21 +42,21 @@ public class ReleaseStrategyAdapterTests {
@Test
public void testTrueConvertedProperly() {
ReleaseStrategyAdapter adapter = new ReleaseStrategyAdapter(new AlwaysTrueReleaseStrategy(),
MethodInvokingReleaseStrategy adapter = new MethodInvokingReleaseStrategy(new AlwaysTrueReleaseStrategy(),
"checkCompleteness");
Assert.assertTrue(adapter.canRelease(createListOfMessages(0)));
}
@Test
public void testFalseConvertedProperly() {
ReleaseStrategyAdapter adapter = new ReleaseStrategyAdapter(new AlwaysFalseReleaseStrategy(),
MethodInvokingReleaseStrategy adapter = new MethodInvokingReleaseStrategy(new AlwaysFalseReleaseStrategy(),
"checkCompleteness");
Assert.assertTrue(!adapter.canRelease(createListOfMessages(0)));
}
@Test
public void testAdapterWithNonParameterizedMessageListBasedMethod() {
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy,
ReleaseStrategy adapter = new MethodInvokingReleaseStrategy(simpleReleaseStrategy,
"checkCompletenessOnNonParameterizedListOfMessages");
MessageGroup messages = createListOfMessages(3);
Assert.assertTrue(adapter.canRelease(messages));
@@ -64,7 +64,7 @@ public class ReleaseStrategyAdapterTests {
@Test
public void testAdapterWithWildcardParametrizedMessageBasedMethod() {
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy,
ReleaseStrategy adapter = new MethodInvokingReleaseStrategy(simpleReleaseStrategy,
"checkCompletenessOnListOfMessagesParametrizedWithWildcard");
MessageGroup messages = createListOfMessages(3);
Assert.assertTrue(adapter.canRelease(messages));
@@ -72,7 +72,7 @@ public class ReleaseStrategyAdapterTests {
@Test
public void testAdapterWithTypeParametrizedMessageBasedMethod() {
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy,
ReleaseStrategy adapter = new MethodInvokingReleaseStrategy(simpleReleaseStrategy,
"checkCompletenessOnListOfMessagesParametrizedWithString");
MessageGroup messages = createListOfMessages(3);
Assert.assertTrue(adapter.canRelease(messages));
@@ -80,69 +80,69 @@ public class ReleaseStrategyAdapterTests {
@Test
public void testAdapterWithPojoBasedMethod() {
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy, "checkCompletenessOnListOfStrings");
ReleaseStrategy adapter = new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "checkCompletenessOnListOfStrings");
MessageGroup messages = createListOfMessages(3);
Assert.assertTrue(adapter.canRelease(messages));
}
@Test
public void testAdapterWithPojoBasedMethodReturningObject() {
ReleaseStrategy adapter = new ReleaseStrategyAdapter(simpleReleaseStrategy, "checkCompletenessOnListOfStrings");
ReleaseStrategy adapter = new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "checkCompletenessOnListOfStrings");
MessageGroup messages = createListOfMessages(3);
Assert.assertTrue(adapter.canRelease(messages));
}
@Test(expected = IllegalArgumentException.class)
public void testAdapterWithWrongMethodName() {
new ReleaseStrategyAdapter(simpleReleaseStrategy, "methodThatDoesNotExist");
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "methodThatDoesNotExist");
}
@Test(expected = IllegalArgumentException.class)
public void testInvalidParameterTypeUsingMethodName() {
new ReleaseStrategyAdapter(simpleReleaseStrategy, "invalidParameterType");
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "invalidParameterType");
}
@Test(expected = IllegalArgumentException.class)
public void testTooManyParametersUsingMethodName() {
new ReleaseStrategyAdapter(simpleReleaseStrategy, "tooManyParameters");
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "tooManyParameters");
}
@Test(expected = IllegalArgumentException.class)
public void testNotEnoughParametersUsingMethodName() {
new ReleaseStrategyAdapter(simpleReleaseStrategy, "notEnoughParameters");
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "notEnoughParameters");
}
@Test(expected = IllegalArgumentException.class)
public void testListSubclassParameterUsingMethodName() {
new ReleaseStrategyAdapter(simpleReleaseStrategy, "ListSubclassParameter");
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "ListSubclassParameter");
}
@Test(expected = IllegalArgumentException.class)
public void testWrongReturnType() throws SecurityException, NoSuchMethodError {
new ReleaseStrategyAdapter(simpleReleaseStrategy, "wrongReturnType");
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, "wrongReturnType");
}
@Test(expected = IllegalArgumentException.class)
public void testTooManyParametersUsingMethodObject() throws SecurityException, NoSuchMethodException {
new ReleaseStrategyAdapter(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod(
new MethodInvokingReleaseStrategy(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(
new MethodInvokingReleaseStrategy(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod(
"notEnoughParameters", new Class[] {}));
}
@Test(expected = IllegalArgumentException.class)
public void testListSubclassParameterUsingMethodObject() throws SecurityException, NoSuchMethodException {
new ReleaseStrategyAdapter(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod(
new MethodInvokingReleaseStrategy(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 MethodInvokingReleaseStrategy(simpleReleaseStrategy, simpleReleaseStrategy.getClass().getMethod("wrongReturnType",
new Class[] { List.class }));
}

View File

@@ -54,7 +54,7 @@ public class DefaultMessageAggregatorIntegrationTests {
@SuppressWarnings("unchecked")
@Test(timeout = 1000)
public void aggregate() throws Exception {
public void testAggregation() throws Exception {
for (int i = 0; i < 5; i++) {
Map<String, Object> headers = stubHeaders(i, 5, 1);
input.send(new GenericMessage<Integer>(i, headers));

View File

@@ -23,6 +23,7 @@ import static org.junit.Assert.assertThat;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Assert;
import org.junit.Before;
@@ -32,14 +33,19 @@ import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageDeliveryException;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.MessageRejectedException;
import org.springframework.integration.aggregator.CorrelatingMessageHandler;
import org.springframework.integration.aggregator.CorrelationStrategy;
import org.springframework.integration.aggregator.MessageListMethodAdapter;
import org.springframework.integration.aggregator.ReleaseStrategy;
import org.springframework.integration.aggregator.ReleaseStrategyAdapter;
import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.integration.util.MethodInvoker;
@@ -51,57 +57,75 @@ import org.springframework.integration.util.MethodInvoker;
*/
public class AggregatorParserTests {
private ApplicationContext context;
private ApplicationContext context;
@Before
public void setUp() {
this.context = new ClassPathXmlApplicationContext("aggregatorParserTests.xml", this.getClass());
}
@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 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 testAggregationByExpression() {
MessageChannel input = (MessageChannel) context.getBean("aggregatorWithExpressionsInput");
SubscribableChannel outputChannel = (SubscribableChannel) context.getBean("aggregatorWithExpressionsOutput");
final AtomicReference<Message<?>> aggregatedMessage = new AtomicReference<Message<?>>();
outputChannel.subscribe(new MessageHandler() {
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException,
MessageDeliveryException {
aggregatedMessage.set(message);
}
});
List<Message<?>> outboundMessages = new ArrayList<Message<?>>();
outboundMessages.add(MessageBuilder.withPayload("123").setHeader("foo", "1").build());
outboundMessages.add(MessageBuilder.withPayload("456").setHeader("foo", "1").build());
outboundMessages.add(MessageBuilder.withPayload("789").setHeader("foo", "1").build());
for (Message<?> message : outboundMessages) {
input.send(message);
}
assertEquals("The aggregated message payload is not correct", "[123]", aggregatedMessage.get().getPayload().toString());
}
@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"));
@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, "messagingTemplate.sendTimeout"));
Assert.assertEquals("The AggregatorEndpoint is not set with the appropriate timeout value", 86420000l,
TestUtils.getPropertyValue(consumer, "messagingTemplate.sendTimeout"));
Assert.assertEquals(
"The AggregatorEndpoint is not configured with the appropriate 'send partial results on timeout' flag",
true, accessor.getPropertyValue("sendPartialResultOnExpiry"));
@@ -110,8 +134,7 @@ public class AggregatorParserTests {
@Test
public void testSimpleJavaBeanAggregator() {
List<Message<?>> outboundMessages = new ArrayList<Message<?>>();
MessageChannel input =
(MessageChannel) context.getBean("aggregatorWithReferenceAndMethodInput");
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));
@@ -123,54 +146,51 @@ public class AggregatorParserTests {
Assert.assertEquals(6l, response.getPayload());
}
@Test(expected=BeanCreationException.class)
@Test(expected = BeanCreationException.class)
public void testMissingMethodOnAggregator() {
context = new ClassPathXmlApplicationContext("invalidMethodNameAggregator.xml", this.getClass());
context = new ClassPathXmlApplicationContext("invalidMethodNameAggregator.xml", this.getClass());
}
@Test(expected=BeanCreationException.class)
@Test(expected = BeanCreationException.class)
public void testDuplicateReleaseStrategyDefinition() {
context = new ClassPathXmlApplicationContext(
"ReleaseStrategyMethodWithMissingReference.xml", this.getClass());
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(new DirectFieldAccessor(releaseStrategy).getPropertyValue("adapter"));
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
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 MethodInvokingReleaseStrategy);
DirectFieldAccessor releaseStrategyAccessor = new DirectFieldAccessor(new DirectFieldAccessor(releaseStrategy)
.getPropertyValue("adapter"));
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());
}
@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();
}
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

@@ -30,8 +30,8 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.aggregator.CorrelatingMessageHandler;
import org.springframework.integration.aggregator.CorrelationStrategy;
import org.springframework.integration.aggregator.CorrelationStrategyAdapter;
import org.springframework.integration.aggregator.ReleaseStrategyAdapter;
import org.springframework.integration.aggregator.MethodInvokingCorrelationStrategy;
import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.aggregator.ResequencingMessageGroupProcessor;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.core.MessageBuilder;
@@ -130,8 +130,8 @@ public class ResequencerParserTests {
CorrelatingMessageHandler.class);
Object correlationStrategy = getPropertyValue(resequencer, "correlationStrategy");
assertEquals("The ResequencerEndpoint is not configured with a CorrelationStrategy adapter",
CorrelationStrategyAdapter.class, correlationStrategy.getClass());
CorrelationStrategyAdapter adapter = (CorrelationStrategyAdapter) correlationStrategy;
MethodInvokingCorrelationStrategy.class, correlationStrategy.getClass());
MethodInvokingCorrelationStrategy adapter = (MethodInvokingCorrelationStrategy) correlationStrategy;
assertEquals("foo", adapter.getCorrelationKey(MessageBuilder.withPayload("not important").build()));
}
@@ -153,7 +153,7 @@ public class ResequencerParserTests {
CorrelatingMessageHandler handler = TestUtils.getPropertyValue(endpoint, "handler",
CorrelatingMessageHandler.class);
Object releaseStrategy = getPropertyValue(handler, "releaseStrategy");
assertEquals("The Resequencer is not configured with an adapter", ReleaseStrategyAdapter.class, releaseStrategy
assertEquals("The Resequencer is not configured with an adapter", MethodInvokingReleaseStrategy.class, releaseStrategy
.getClass());
}

View File

@@ -29,6 +29,15 @@
send-timeout="86420000"
send-partial-result-on-expiry="true"/>
<channel id="aggregatorWithExpressionsInput"/>
<channel id="aggregatorWithExpressionsOutput"/>
<aggregator id="aggregatorWithExpressions"
input-channel="aggregatorWithExpressionsInput"
output-channel="aggregatorWithExpressionsOutput"
expression="?[payload.startsWith('1')].![payload]"
release-strategy-expression="#root.size()>2"
correlation-strategy-expression="headers['foo']"/>
<channel id="aggregatorWithReferenceAndMethodInput"/>
<aggregator id="aggregatorWithReferenceAndMethod"
ref="adderBean"

View File

@@ -30,9 +30,9 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.aggregator.ReleaseStrategyAdapter;
import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy;
import org.springframework.integration.aggregator.CorrelatingMessageHandler;
import org.springframework.integration.aggregator.CorrelationStrategyAdapter;
import org.springframework.integration.aggregator.MethodInvokingCorrelationStrategy;
import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.context.BeanFactoryChannelResolver;
@@ -83,8 +83,8 @@ public class AggregatorAnnotationTests {
final String endpointName = "endpointWithDefaultAnnotationAndCustomReleaseStrategy";
MessageHandler aggregator = this.getAggregator(context, endpointName);
Object ReleaseStrategy = getPropertyValue(aggregator, "releaseStrategy");
Assert.assertTrue(ReleaseStrategy instanceof ReleaseStrategyAdapter);
ReleaseStrategyAdapter releaseStrategyAdapter = (ReleaseStrategyAdapter) ReleaseStrategy;
Assert.assertTrue(ReleaseStrategy instanceof MethodInvokingReleaseStrategy);
MethodInvokingReleaseStrategy releaseStrategyAdapter = (MethodInvokingReleaseStrategy) ReleaseStrategy;
DirectFieldAccessor invokerAccessor = new DirectFieldAccessor(new DirectFieldAccessor(new DirectFieldAccessor(
releaseStrategyAdapter).getPropertyValue("adapter")).getPropertyValue("invoker"));
Object targetObject = invokerAccessor.getPropertyValue("object");
@@ -100,8 +100,8 @@ public class AggregatorAnnotationTests {
final String endpointName = "endpointWithCorrelationStrategy";
MessageHandler aggregator = this.getAggregator(context, endpointName);
Object correlationStrategy = getPropertyValue(aggregator, "correlationStrategy");
Assert.assertTrue(correlationStrategy instanceof CorrelationStrategyAdapter);
CorrelationStrategyAdapter ReleaseStrategyAdapter = (CorrelationStrategyAdapter) correlationStrategy;
Assert.assertTrue(correlationStrategy instanceof MethodInvokingCorrelationStrategy);
MethodInvokingCorrelationStrategy ReleaseStrategyAdapter = (MethodInvokingCorrelationStrategy) correlationStrategy;
DirectFieldAccessor processorAccessor = new DirectFieldAccessor(new DirectFieldAccessor(ReleaseStrategyAdapter)
.getPropertyValue("processor"));
Object targetObject = processorAccessor.getPropertyValue("targetObject");