Merge remote-tracking branch 'upstream/master' into 4.0.0-WIP
Conflicts: spring-integration-core/src/test/java/org/springframework/integration/aggregator/AggregatorTests.java spring-integration-core/src/test/java/org/springframework/integration/aggregator/ConcurrentAggregatorTests.java spring-integration-core/src/test/java/org/springframework/integration/aggregator/CorrelatingMessageHandlerTests.java spring-integration-core/src/test/java/org/springframework/integration/gateway/GatewayInterfaceTests.java spring-integration-redis/src/test/java/org/springframework/integration/redis/channel/SubscribableRedisChannelTests.java spring-integration-redis/src/test/java/org/springframework/integration/redis/config/RedisInboundChannelAdapterParserTests.java spring-integration-redis/src/test/java/org/springframework/integration/redis/store/DelayerHandlerRescheduleIntegrationTests.java spring-integration-redis/src/test/java/org/springframework/integration/redis/store/RedisMessageGroupStoreTests.java spring-integration-redis/src/test/java/org/springframework/integration/redis/store/RedisMessageStoreTests.java Resolved
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2010 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -27,6 +27,7 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.ManagedMap;
|
||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
|
||||
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
@@ -34,9 +35,10 @@ import org.springframework.util.xml.DomUtils;
|
||||
|
||||
/**
|
||||
* Parser for the <gateway/> element.
|
||||
*
|
||||
*
|
||||
* @author Mark Fisher
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
*/
|
||||
public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@@ -51,9 +53,10 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected String getBeanClassName(Element element) {
|
||||
return IntegrationNamespaceUtils.BASE_PACKAGE + ".gateway.GatewayProxyFactoryBean";
|
||||
return GatewayProxyFactoryBean.class.getName();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean shouldGenerateIdAsFallback() {
|
||||
return true;
|
||||
}
|
||||
@@ -62,6 +65,7 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
protected boolean isEligibleAttribute(String attributeName) {
|
||||
return !ObjectUtils.containsElement(referenceAttributes, attributeName)
|
||||
&& !ObjectUtils.containsElement(innerAttributes, attributeName)
|
||||
&& !("default-payload-expression".equals(attributeName))
|
||||
&& super.isEligibleAttribute(attributeName);
|
||||
}
|
||||
|
||||
@@ -79,7 +83,7 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "request-channel", "defaultRequestChannel");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "reply-channel", "defaultReplyChannel");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "request-timeout", "defaultRequestTimeout");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "defaultReplyTimeout");
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "reply-timeout", "defaultReplyTimeout");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "error-channel");
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "async-executor");
|
||||
}
|
||||
@@ -88,6 +92,18 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
for (String attributeName : referenceAttributes) {
|
||||
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, attributeName);
|
||||
}
|
||||
|
||||
List<Element> invocationHeaders = DomUtils.getChildElementsByTagName(element, "default-header");
|
||||
if (!CollectionUtils.isEmpty(invocationHeaders)
|
||||
|| StringUtils.hasText(element.getAttribute("default-payload-expression"))) {
|
||||
BeanDefinitionBuilder methodMetadataBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
"org.springframework.integration.gateway.GatewayMethodMetadata");
|
||||
this.setMethodInvocationHeaders(methodMetadataBuilder, invocationHeaders);
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(methodMetadataBuilder, element,
|
||||
"default-payload-expression", "payloadExpression");
|
||||
builder.addPropertyValue("globalMethodMetadata", methodMetadataBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
List<Element> elements = DomUtils.getChildElementsByTagName(element, "method");
|
||||
ManagedMap<String, BeanDefinition> methodMetadataMap = null;
|
||||
if (elements != null && elements.size() > 0) {
|
||||
@@ -102,7 +118,7 @@ public class GatewayParser extends AbstractSimpleBeanDefinitionParser {
|
||||
methodMetadataBuilder.addPropertyValue("requestTimeout", methodElement.getAttribute("request-timeout"));
|
||||
methodMetadataBuilder.addPropertyValue("replyTimeout", methodElement.getAttribute("reply-timeout"));
|
||||
IntegrationNamespaceUtils.setValueIfAttributeDefined(methodMetadataBuilder, methodElement, "payload-expression");
|
||||
List<Element> invocationHeaders = DomUtils.getChildElementsByTagName(methodElement, "header");
|
||||
invocationHeaders = DomUtils.getChildElementsByTagName(methodElement, "header");
|
||||
if (!CollectionUtils.isEmpty(invocationHeaders)) {
|
||||
this.setMethodInvocationHeaders(methodMetadataBuilder, invocationHeaders);
|
||||
}
|
||||
|
||||
@@ -68,6 +68,7 @@ import org.springframework.util.StringUtils;
|
||||
* @author Mark Fisher
|
||||
* @author Iwein Fuld
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gary Russell
|
||||
* @since 2.0
|
||||
*/
|
||||
class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]>, BeanFactoryAware {
|
||||
@@ -80,6 +81,8 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
|
||||
private final Map<String, Expression> headerExpressions;
|
||||
|
||||
private final Map<String, Expression> globalHeaderExpressions;
|
||||
|
||||
private final List<MethodParameter> parameterList;
|
||||
|
||||
private volatile Expression payloadExpression;
|
||||
@@ -96,9 +99,15 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
}
|
||||
|
||||
public GatewayMethodInboundMessageMapper(Method method, Map<String, Expression> headerExpressions) {
|
||||
this(method, headerExpressions, null);
|
||||
}
|
||||
|
||||
public GatewayMethodInboundMessageMapper(Method method, Map<String, Expression> headerExpressions,
|
||||
Map<String, Expression> globalHeaderExpressions) {
|
||||
Assert.notNull(method, "method must not be null");
|
||||
this.method = method;
|
||||
this.headerExpressions = headerExpressions;
|
||||
this.globalHeaderExpressions = globalHeaderExpressions;
|
||||
this.parameterList = getMethodParameterList(method);
|
||||
this.payloadExpression = parsePayloadExpression(method);
|
||||
}
|
||||
@@ -194,23 +203,38 @@ class GatewayMethodInboundMessageMapper implements InboundMessageMapper<Object[]
|
||||
? MessageBuilder.fromMessage((Message<?>) messageOrPayload)
|
||||
: MessageBuilder.withPayload(messageOrPayload);
|
||||
builder.copyHeadersIfAbsent(headers);
|
||||
// Explicit headers in XML override any @Header annotations...
|
||||
if (!CollectionUtils.isEmpty(this.headerExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = new HashMap<String, Object>();
|
||||
for (Map.Entry<String, Expression> entry : this.headerExpressions.entrySet()) {
|
||||
Object value = entry.getValue().getValue(methodInvocationEvaluationContext);
|
||||
if (value != null) {
|
||||
evaluatedHeaders.put(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
Map<String, Object> evaluatedHeaders = evaluateHeaders(methodInvocationEvaluationContext, this.headerExpressions);
|
||||
builder.copyHeaders(evaluatedHeaders);
|
||||
}
|
||||
// ...whereas global (default) headers do not...
|
||||
if (!CollectionUtils.isEmpty(this.globalHeaderExpressions)) {
|
||||
Map<String, Object> evaluatedHeaders = evaluateHeaders(methodInvocationEvaluationContext, this.globalHeaderExpressions);
|
||||
builder.copyHeadersIfAbsent(evaluatedHeaders);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private Map<String, Object> evaluateHeaders(EvaluationContext methodInvocationEvaluationContext, Map<String, Expression> headerExpressions) {
|
||||
Map<String, Object> evaluatedHeaders = new HashMap<String, Object>();
|
||||
for (Map.Entry<String, Expression> entry : headerExpressions.entrySet()) {
|
||||
Object value = entry.getValue().getValue(methodInvocationEvaluationContext);
|
||||
if (value != null) {
|
||||
evaluatedHeaders.put(entry.getKey(), value);
|
||||
}
|
||||
}
|
||||
return evaluatedHeaders;
|
||||
}
|
||||
|
||||
private StandardEvaluationContext createMethodInvocationEvaluationContext(Object[] arguments) {
|
||||
StandardEvaluationContext context = ExpressionUtils.createStandardEvaluationContext(this.beanFactory);
|
||||
context.setVariable("args", arguments);
|
||||
|
||||
// TODO deprecated in 3.0/4.0 - retained for backwards compatibility
|
||||
context.setVariable("method", this.method.getName());
|
||||
|
||||
context.setVariable("gatewayMethod", this.method);
|
||||
return context;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -28,6 +28,7 @@ import java.util.concurrent.Future;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.SimpleTypeConverter;
|
||||
@@ -100,8 +101,9 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
|
||||
private final Object initializationMonitor = new Object();
|
||||
|
||||
private Map<String, GatewayMethodMetadata> methodMetadataMap;
|
||||
private volatile Map<String, GatewayMethodMetadata> methodMetadataMap;
|
||||
|
||||
private volatile GatewayMethodMetadata globalMethodMetadata;
|
||||
|
||||
/**
|
||||
* Create a Factory whose service interface type can be configured by setter injection.
|
||||
@@ -204,6 +206,10 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
this.methodMetadataMap = methodMetadataMap;
|
||||
}
|
||||
|
||||
public void setGlobalMethodMetadata(GatewayMethodMetadata globalMethodMetadata) {
|
||||
this.globalMethodMetadata = globalMethodMetadata;
|
||||
}
|
||||
|
||||
public void setBeanClassLoader(ClassLoader beanClassLoader) {
|
||||
this.beanClassLoader = beanClassLoader;
|
||||
}
|
||||
@@ -339,7 +345,8 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
MessageChannel replyChannel = this.defaultReplyChannel;
|
||||
Long requestTimeout = this.defaultRequestTimeout;
|
||||
Long replyTimeout = this.defaultReplyTimeout;
|
||||
String payloadExpression = null;
|
||||
String payloadExpression = this.globalMethodMetadata != null ? this.globalMethodMetadata.getPayloadExpression()
|
||||
: null;
|
||||
Map<String, Expression> headerExpressions = null;
|
||||
if (gatewayAnnotation != null) {
|
||||
String requestChannelName = gatewayAnnotation.requestChannel();
|
||||
@@ -387,7 +394,8 @@ public class GatewayProxyFactoryBean extends AbstractEndpoint implements Trackab
|
||||
}
|
||||
}
|
||||
}
|
||||
GatewayMethodInboundMessageMapper messageMapper = new GatewayMethodInboundMessageMapper(method, headerExpressions);
|
||||
GatewayMethodInboundMessageMapper messageMapper = new GatewayMethodInboundMessageMapper(method, headerExpressions,
|
||||
this.globalMethodMetadata != null ? this.globalMethodMetadata.getHeaderExpressions() : null);
|
||||
if (StringUtils.hasText(payloadExpression)) {
|
||||
messageMapper.setPayloadExpression(payloadExpression);
|
||||
}
|
||||
|
||||
@@ -515,7 +515,17 @@
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:sequence minOccurs="0" maxOccurs="1">
|
||||
<xsd:element name="default-header" minOccurs="0" maxOccurs="unbounded" type="headerSubElementType">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Provides a mechanism to enrich the message with custom message headers. These default headers are created for
|
||||
all methods on the service-interface (unless overridden by a specific method element).
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="method" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
@@ -530,7 +540,7 @@
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Provides mechanism to enrich content of the message with custom message headers. When this method is going to be invoked
|
||||
Provides a mechanism to enrich the message with custom message headers. When this method is invoked,
|
||||
the generated message will be enriched with these headers.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
@@ -621,6 +631,17 @@
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="default-payload-expression" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
An expression that will be used to generate the payload for all methods in the service interface
|
||||
unless explicitly overriden by a method declaration. Variables include #args, #methodName, #methodString
|
||||
and #methodObject; a bean resolver is also available, enabling expressions like "@someBean(#args)".
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="default-request-channel" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 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
|
||||
@@ -19,21 +19,18 @@ 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.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -44,7 +41,7 @@ public class AggregatorTests {
|
||||
|
||||
private AggregatingMessageHandler aggregator;
|
||||
|
||||
private SimpleMessageStore store = new SimpleMessageStore(50);
|
||||
private final SimpleMessageStore store = new SimpleMessageStore(50);
|
||||
|
||||
|
||||
@Before
|
||||
@@ -59,12 +56,12 @@ public class AggregatorTests {
|
||||
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);
|
||||
|
||||
Message<?> reply = replyChannel.receive(10000);
|
||||
assertNotNull(reply);
|
||||
assertEquals(reply.getPayload(), 105);
|
||||
}
|
||||
@@ -77,7 +74,7 @@ public class AggregatorTests {
|
||||
Message<?> message = createMessage(3, "ABC", 2, 1, replyChannel, null);
|
||||
this.aggregator.handleMessage(message);
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
Message<?> reply = replyChannel.receive(1000);
|
||||
assertNull("No message should have been sent normally", reply);
|
||||
Message<?> discardedMessage = discardChannel.receive(1000);
|
||||
assertNotNull("A message should have been discarded", discardedMessage);
|
||||
@@ -93,7 +90,7 @@ public class AggregatorTests {
|
||||
this.aggregator.handleMessage(message1);
|
||||
this.aggregator.handleMessage(message2);
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> reply = replyChannel.receive(0);
|
||||
Message<?> reply = replyChannel.receive(1000);
|
||||
assertNotNull("A reply message should have been received", reply);
|
||||
assertEquals(15, reply.getPayload());
|
||||
}
|
||||
@@ -115,11 +112,11 @@ public class AggregatorTests {
|
||||
aggregator.handleMessage(message4);
|
||||
aggregator.handleMessage(message2);
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply1 = (Message<Integer>) replyChannel1.receive(500);
|
||||
Message<Integer> reply1 = (Message<Integer>) replyChannel1.receive(1000);
|
||||
assertNotNull(reply1);
|
||||
assertThat(reply1.getPayload(), is(105));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply2 = (Message<Integer>) replyChannel2.receive(500);
|
||||
Message<Integer> reply2 = (Message<Integer>) replyChannel2.receive(1000);
|
||||
assertNotNull(reply2);
|
||||
assertThat(reply2.getPayload(), is(2431));
|
||||
}
|
||||
@@ -133,14 +130,14 @@ public class AggregatorTests {
|
||||
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
assertEquals(1, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 2, 1, 1, replyChannel, null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
assertEquals(3, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 3, 1, 1, replyChannel, null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
assertEquals(4, replyChannel.receive(1000).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());
|
||||
assertEquals(2, discardChannel.receive(1000).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -152,15 +149,15 @@ public class AggregatorTests {
|
||||
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
assertEquals(1, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(2, 2, 1, 1, replyChannel, null));
|
||||
assertEquals(2, replyChannel.receive(100).getPayload());
|
||||
assertEquals(2, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 3, 1, 1, replyChannel, null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
assertEquals(3, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 4, 1, 1, replyChannel, null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
assertEquals(4, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(5, 1, 1, 1, replyChannel, null));
|
||||
assertEquals(5, replyChannel.receive(100).getPayload());
|
||||
assertEquals(5, replyChannel.receive(1000).getPayload());
|
||||
assertNull(discardChannel.receive(0));
|
||||
}
|
||||
|
||||
@@ -177,15 +174,13 @@ public class AggregatorTests {
|
||||
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);
|
||||
|
||||
Message<?> reply = replyChannel.receive(10000);
|
||||
assertNotNull("A message should be aggregated", reply);
|
||||
assertThat(((Integer) reply.getPayload()), is(105));
|
||||
}
|
||||
@@ -197,18 +192,19 @@ public class AggregatorTests {
|
||||
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);
|
||||
|
||||
Message<?> reply = replyChannel.receive(10000);
|
||||
assertNotNull("A message should be aggregated", reply);
|
||||
assertThat(((Integer) reply.getPayload()), is(105));
|
||||
}
|
||||
|
||||
|
||||
private static Message<?> createMessage(Object payload, Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel replyChannel, String predefinedId) {
|
||||
MessageBuilder<Object> builder = MessageBuilder.withPayload(payload).setCorrelationId(correlationId)
|
||||
@@ -231,10 +227,4 @@ public class AggregatorTests {
|
||||
}
|
||||
|
||||
|
||||
private class NullReturningMessageProcessor implements MessageGroupProcessor {
|
||||
public Object processMessageGroup(MessageGroup group) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
* Copyright 2002-2013 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.
|
||||
@@ -16,31 +16,32 @@
|
||||
|
||||
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 static org.junit.Assert.assertTrue;
|
||||
|
||||
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.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
import org.springframework.integration.store.SimpleMessageStore;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
|
||||
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 org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessageHeaders;
|
||||
|
||||
/**
|
||||
* @author Mark Fisher
|
||||
@@ -53,7 +54,7 @@ public class ConcurrentAggregatorTests {
|
||||
|
||||
private AggregatingMessageHandler aggregator;
|
||||
|
||||
private MessageGroupStore store = new SimpleMessageStore();
|
||||
private final MessageGroupStore store = new SimpleMessageStore();
|
||||
|
||||
|
||||
@Before
|
||||
@@ -76,7 +77,9 @@ public class ConcurrentAggregatorTests {
|
||||
message2, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message3, latch));
|
||||
latch.await(10000, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
assertThat(latch.getCount(), is(0l));
|
||||
Message<?> reply = replyChannel.receive(2000);
|
||||
assertNotNull(reply);
|
||||
@@ -101,7 +104,7 @@ public class ConcurrentAggregatorTests {
|
||||
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);
|
||||
Message<?> reply = replyChannel.receive(1000);
|
||||
assertNotNull(reply);
|
||||
assertEquals("123456789", reply.getPayload());
|
||||
}
|
||||
@@ -117,13 +120,15 @@ public class ConcurrentAggregatorTests {
|
||||
AggregatorTestTask task = new AggregatorTestTask(this.aggregator,
|
||||
message, latch);
|
||||
this.taskExecutor.execute(task);
|
||||
latch.await(200, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
assertEquals("Task should have completed within timeout", 0, latch
|
||||
.getCount());
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
Message<?> reply = replyChannel.receive(1000);
|
||||
assertNull("No message should have been sent normally", reply);
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> discardedMessage = discardChannel.receive(100);
|
||||
Message<?> discardedMessage = discardChannel.receive(1000);
|
||||
assertNotNull("A message should have been discarded", discardedMessage);
|
||||
assertEquals(message, discardedMessage);
|
||||
}
|
||||
@@ -142,11 +147,13 @@ public class ConcurrentAggregatorTests {
|
||||
message2, latch);
|
||||
this.taskExecutor.execute(task1);
|
||||
this.taskExecutor.execute(task2);
|
||||
latch.await(300, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
assertEquals("handlers should have been invoked within time limit", 0,
|
||||
latch.getCount());
|
||||
this.store.expireMessageGroups(-10000);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
Message<?> reply = replyChannel.receive(1000);
|
||||
assertNotNull("A reply message should have been received", reply);
|
||||
assertEquals(15, reply.getPayload());
|
||||
assertNull(task1.getException());
|
||||
@@ -179,13 +186,15 @@ public class ConcurrentAggregatorTests {
|
||||
message3, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message4, latch));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply1 = (Message<Integer>) replyChannel1.receive(500);
|
||||
Message<Integer> reply1 = (Message<Integer>) replyChannel1.receive(1000);
|
||||
assertNotNull(reply1);
|
||||
assertThat(reply1.getPayload(), is(105));
|
||||
@SuppressWarnings("unchecked")
|
||||
Message<Integer> reply2 = (Message<Integer>) replyChannel2.receive(500);
|
||||
Message<Integer> reply2 = (Message<Integer>) replyChannel2.receive(1000);
|
||||
assertNotNull(reply2);
|
||||
assertThat(reply2.getPayload(), is(2431));
|
||||
}
|
||||
@@ -201,17 +210,17 @@ public class ConcurrentAggregatorTests {
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
assertEquals(1, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 2, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
assertEquals(3, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 3, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
assertEquals(4, replyChannel.receive(1000).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());
|
||||
assertEquals(2, discardChannel.receive(1000).getPayload());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -225,19 +234,19 @@ public class ConcurrentAggregatorTests {
|
||||
this.aggregator.setDiscardChannel(discardChannel);
|
||||
this.aggregator.handleMessage(createMessage(1, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(1, replyChannel.receive(100).getPayload());
|
||||
assertEquals(1, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(2, 2, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(2, replyChannel.receive(100).getPayload());
|
||||
assertEquals(2, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(3, 3, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(3, replyChannel.receive(100).getPayload());
|
||||
assertEquals(3, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(4, 4, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(4, replyChannel.receive(100).getPayload());
|
||||
assertEquals(4, replyChannel.receive(1000).getPayload());
|
||||
this.aggregator.handleMessage(createMessage(5, 1, 1, 1, replyChannel,
|
||||
null));
|
||||
assertEquals(5, replyChannel.receive(100).getPayload());
|
||||
assertEquals(5, replyChannel.receive(1000).getPayload());
|
||||
assertNull(discardChannel.receive(0));
|
||||
}
|
||||
|
||||
@@ -266,12 +275,15 @@ public class ConcurrentAggregatorTests {
|
||||
message3, latch));
|
||||
this.taskExecutor.execute(new AggregatorTestTask(this.aggregator,
|
||||
message4, latch));
|
||||
latch.await(1000, TimeUnit.MILLISECONDS);
|
||||
Message<?> reply = replyChannel.receive(100);
|
||||
|
||||
assertTrue(latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
Message<?> reply = replyChannel.receive(1000);
|
||||
assertNotNull("A message should be aggregated", reply);
|
||||
assertThat(((Integer) reply.getPayload()), is(105));
|
||||
}
|
||||
|
||||
|
||||
private static Message<?> createMessage(Object payload,
|
||||
Object correlationId, int sequenceSize, int sequenceNumber,
|
||||
MessageChannel replyChannel, String predefinedId) {
|
||||
@@ -288,13 +300,13 @@ public class ConcurrentAggregatorTests {
|
||||
|
||||
private static class AggregatorTestTask implements Runnable {
|
||||
|
||||
private MessageHandler aggregator;
|
||||
private final MessageHandler aggregator;
|
||||
|
||||
private Message<?> message;
|
||||
private final Message<?> message;
|
||||
|
||||
private Exception exception;
|
||||
|
||||
private CountDownLatch latch;
|
||||
private final CountDownLatch latch;
|
||||
|
||||
AggregatorTestTask(MessageHandler aggregator, Message<?> message,
|
||||
CountDownLatch latch) {
|
||||
|
||||
@@ -17,18 +17,20 @@
|
||||
package org.springframework.integration.aggregator;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
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 static org.mockito.Mockito.any;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -36,6 +38,7 @@ import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.internal.stubbing.answers.ThrowsException;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import org.springframework.integration.MessageHandlingException;
|
||||
import org.springframework.integration.store.MessageGroup;
|
||||
import org.springframework.integration.store.MessageGroupStore;
|
||||
@@ -57,7 +60,7 @@ public class CorrelatingMessageHandlerTests {
|
||||
@Mock
|
||||
private CorrelationStrategy correlationStrategy;
|
||||
|
||||
private ReleaseStrategy ReleaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
private final ReleaseStrategy ReleaseStrategy = new SequenceSizeReleaseStrategy();
|
||||
|
||||
@Mock
|
||||
private MessageGroupProcessor processor;
|
||||
@@ -65,7 +68,7 @@ public class CorrelatingMessageHandlerTests {
|
||||
@Mock
|
||||
private MessageChannel outputChannel;
|
||||
|
||||
private MessageGroupStore store = new SimpleMessageStore();
|
||||
private final MessageGroupStore store = new SimpleMessageStore();
|
||||
|
||||
|
||||
@Before
|
||||
@@ -152,10 +155,9 @@ public class CorrelatingMessageHandlerTests {
|
||||
}
|
||||
});
|
||||
|
||||
Thread.sleep(20);
|
||||
assertEquals(0, store.expireMessageGroups(10000));
|
||||
assertTrue(bothMessagesHandled.await(10, TimeUnit.SECONDS));
|
||||
|
||||
bothMessagesHandled.await();
|
||||
assertEquals(0, store.expireMessageGroups(10000));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2013 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
|
||||
@@ -12,6 +12,9 @@
|
||||
*/
|
||||
package org.springframework.integration.aggregator.scenarios;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -24,9 +27,6 @@ import org.springframework.messaging.MessageChannel;
|
||||
import org.springframework.integration.channel.QueueChannel;
|
||||
import org.springframework.integration.support.MessageBuilder;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
*
|
||||
@@ -79,11 +79,11 @@ public class AggregatorWithCustomReleaseStrategyTests {
|
||||
|
||||
assertTrue("Sends failed to complete", latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
Message<?> message = resultChannel.receive(10);
|
||||
Message<?> message = resultChannel.receive(1000);
|
||||
int counter = 0;
|
||||
while(message != null){
|
||||
counter++;
|
||||
message = resultChannel.receive(10);
|
||||
message = resultChannel.receive(1000);
|
||||
}
|
||||
assertEquals(600, counter);
|
||||
}
|
||||
@@ -119,10 +119,10 @@ public class AggregatorWithCustomReleaseStrategyTests {
|
||||
|
||||
assertTrue("Sends failed to complete", latch.await(10, TimeUnit.SECONDS));
|
||||
|
||||
Message<?> message = resultChannel.receive(10);
|
||||
Message<?> message = resultChannel.receive(1000);
|
||||
int counter = 0;
|
||||
while(message != null && ++counter < 7200){
|
||||
message = resultChannel.receive(10);
|
||||
message = resultChannel.receive(1000);
|
||||
}
|
||||
assertEquals(7200, counter);
|
||||
}
|
||||
|
||||
@@ -5,10 +5,17 @@
|
||||
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">
|
||||
|
||||
<int:gateway id="sampleGateway"
|
||||
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests.Bar"
|
||||
default-request-channel="requestChannelBaz"/>
|
||||
|
||||
<int:gateway id="sampleGateway"
|
||||
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests.Bar"
|
||||
default-request-channel="requestChannelBaz">
|
||||
<int:default-header name="name" expression="#gatewayMethod.name"/>
|
||||
<int:default-header name="string" expression="#gatewayMethod.toString()"/>
|
||||
<int:default-header name="object" expression="#gatewayMethod"/>
|
||||
<int:method name="baz">
|
||||
<int:header name="name" value="overrideGlobal"/>
|
||||
</int:method>
|
||||
</int:gateway>
|
||||
|
||||
<int:channel id="requestChannelFoo"/>
|
||||
<int:channel id="requestChannelBar"/>
|
||||
<int:channel id="requestChannelBaz"/>
|
||||
|
||||
@@ -16,43 +16,90 @@
|
||||
|
||||
package org.springframework.integration.gateway;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.integration.annotation.Gateway;
|
||||
import org.springframework.integration.annotation.Header;
|
||||
import org.springframework.integration.channel.DirectChannel;
|
||||
import org.springframework.messaging.Message;
|
||||
import org.springframework.messaging.MessageHandler;
|
||||
import org.springframework.messaging.MessagingException;
|
||||
|
||||
/**
|
||||
* @author Oleg Zhurakousky
|
||||
* @author Gunnar Hillert
|
||||
* @author Gary Russell
|
||||
*/
|
||||
public class GatewayInterfaceTests {
|
||||
|
||||
@Test
|
||||
public void testWithServiceSuperclassAnnotatedMethod(){
|
||||
public void testWithServiceSuperclassAnnotatedMethod() throws Exception {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
final Method fooMethod = Foo.class.getMethod("foo", String.class);
|
||||
final AtomicBoolean called = new AtomicBoolean();
|
||||
MessageHandler handler = new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat((String) message.getHeaders().get("name"), equalTo("foo"));
|
||||
assertThat(
|
||||
(String) message.getHeaders().get("string"),
|
||||
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Foo.foo(java.lang.String)"));
|
||||
assertThat((Method) message.getHeaders().get("object"), equalTo(fooMethod));
|
||||
assertThat((String) message.getPayload(), equalTo("hello"));
|
||||
called.set(true);
|
||||
}
|
||||
};
|
||||
channel.subscribe(handler);
|
||||
Bar bar = ac.getBean(Bar.class);
|
||||
bar.foo("hello");
|
||||
verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
|
||||
assertTrue(called.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceAnnotatedMethod(){
|
||||
public void testWithServiceSuperclassAnnotatedMethodOverridePE() throws Exception {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests2-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
|
||||
final Method fooMethod = Foo.class.getMethod("foo", String.class);
|
||||
final AtomicBoolean called = new AtomicBoolean();
|
||||
MessageHandler handler = new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat((String) message.getHeaders().get("name"), equalTo("foo"));
|
||||
assertThat(
|
||||
(String) message.getHeaders().get("string"),
|
||||
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Foo.foo(java.lang.String)"));
|
||||
assertThat((Method) message.getHeaders().get("object"), equalTo(fooMethod));
|
||||
assertThat((String) message.getPayload(), equalTo("foo"));
|
||||
called.set(true);
|
||||
}
|
||||
};
|
||||
channel.subscribe(handler);
|
||||
Bar bar = ac.getBean(Bar.class);
|
||||
bar.foo("hello");
|
||||
assertTrue(called.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceAnnotatedMethod() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBar", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -63,18 +110,57 @@ public class GatewayInterfaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceSuperclassUnAnnotatedMethod(){
|
||||
public void testWithServiceSuperclassUnAnnotatedMethod() throws Exception {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
final Method bazMethod = Foo.class.getMethod("baz", String.class);
|
||||
final AtomicBoolean called = new AtomicBoolean();
|
||||
MessageHandler handler = new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat((String) message.getHeaders().get("name"), equalTo("overrideGlobal"));
|
||||
assertThat(
|
||||
(String) message.getHeaders().get("string"),
|
||||
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Foo.baz(java.lang.String)"));
|
||||
assertThat((Method) message.getHeaders().get("object"), equalTo(bazMethod));
|
||||
assertThat((String) message.getPayload(), equalTo("hello"));
|
||||
called.set(true);
|
||||
}
|
||||
};
|
||||
channel.subscribe(handler);
|
||||
Bar bar = ac.getBean(Bar.class);
|
||||
bar.baz("hello");
|
||||
verify(handler, times(1)).handleMessage(Mockito.any(Message.class));
|
||||
assertTrue(called.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceCastAsSuperclassAnnotatedMethod(){
|
||||
public void testWithServiceUnAnnotatedMethodGlobalHeaderDoesntOverride() throws Exception {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
final Method quxMethod = Bar.class.getMethod("qux", String.class, String.class);
|
||||
final AtomicBoolean called = new AtomicBoolean();
|
||||
MessageHandler handler = new MessageHandler() {
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message<?> message) throws MessagingException {
|
||||
assertThat((String) message.getHeaders().get("name"), equalTo("arg1"));
|
||||
assertThat(
|
||||
(String) message.getHeaders().get("string"),
|
||||
equalTo("public abstract void org.springframework.integration.gateway.GatewayInterfaceTests$Bar.qux(java.lang.String,java.lang.String)"));
|
||||
assertThat((Method) message.getHeaders().get("object"), equalTo(quxMethod));
|
||||
assertThat((String) message.getPayload(), equalTo("hello"));
|
||||
called.set(true);
|
||||
}
|
||||
};
|
||||
channel.subscribe(handler);
|
||||
Bar bar = ac.getBean(Bar.class);
|
||||
bar.qux("hello", "arg1");
|
||||
assertTrue(called.get());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceCastAsSuperclassAnnotatedMethod() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelFoo", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -85,7 +171,7 @@ public class GatewayInterfaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceCastAsSuperclassUnAnnotatedMethod(){
|
||||
public void testWithServiceCastAsSuperclassUnAnnotatedMethod() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -96,7 +182,7 @@ public class GatewayInterfaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceHashcode() throws Exception{
|
||||
public void testWithServiceHashcode() throws Exception {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -107,7 +193,7 @@ public class GatewayInterfaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceToString(){
|
||||
public void testWithServiceToString() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -118,7 +204,7 @@ public class GatewayInterfaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceEquals() throws Exception{
|
||||
public void testWithServiceEquals() throws Exception {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -137,7 +223,7 @@ public class GatewayInterfaceTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithServiceGetClass(){
|
||||
public void testWithServiceGetClass() {
|
||||
ApplicationContext ac = new ClassPathXmlApplicationContext("GatewayInterfaceTests-context.xml", this.getClass());
|
||||
DirectChannel channel = ac.getBean("requestChannelBaz", DirectChannel.class);
|
||||
MessageHandler handler = mock(MessageHandler.class);
|
||||
@@ -160,9 +246,11 @@ public class GatewayInterfaceTests {
|
||||
public void baz(String payload);
|
||||
}
|
||||
|
||||
public static interface Bar extends Foo{
|
||||
public static interface Bar extends Foo {
|
||||
@Gateway(requestChannel="requestChannelBar")
|
||||
public void bar(String payload);
|
||||
|
||||
public void qux(String payload, @Header("name") String nameHeader);
|
||||
}
|
||||
|
||||
public static class NotAnInterface {
|
||||
|
||||
@@ -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"
|
||||
xmlns:int="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">
|
||||
|
||||
<int:gateway id="sampleGateway"
|
||||
service-interface="org.springframework.integration.gateway.GatewayInterfaceTests.Bar"
|
||||
default-request-channel="requestChannelBaz" default-payload-expression="'foo'">
|
||||
<int:default-header name="name" expression="#gatewayMethod.name"/>
|
||||
<int:default-header name="string" expression="#gatewayMethod.toString()"/>
|
||||
<int:default-header name="object" expression="#gatewayMethod"/>
|
||||
<int:method name="baz">
|
||||
<int:header name="name" value="overrideGlobal"/>
|
||||
</int:method>
|
||||
</int:gateway>
|
||||
|
||||
<int:channel id="requestChannelFoo"/>
|
||||
<int:channel id="requestChannelBar"/>
|
||||
<int:channel id="requestChannelBaz"/>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user