Refactored existing Message-consuming endpoints to only implement MessageConsumer (not MessageEndpoint). Now, either a PollingConsumerEndpoint or SubscribingConsumerEndpoint delegates to the MessageConsumer thereby separating the Lifecycle responsibilities and configuration settings (trigger, transactions, etc) since they are different for polling vs. subscribing and not relevant for simply consuming Messages. Essentially all MessageConsumers are now "event-driven" since a "polling consumer" is actually handled by the PollingConsumerEndpoint class. The next refactoring step involves renaming several components to clarify this endpoint vs. consumer distinction.

This commit is contained in:
Mark Fisher
2008-10-06 17:24:46 +00:00
parent 14cd44d272
commit 27e288be08
54 changed files with 591 additions and 682 deletions

View File

@@ -27,26 +27,29 @@ import java.util.concurrent.TimeUnit;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.channel.BlockingChannel;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.scheduling.IntervalTrigger;
import org.springframework.integration.scheduling.TaskScheduler;
import org.springframework.integration.scheduling.TaskSchedulerAware;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
/**
* Base class for {@link MessageBarrier}-based MessageHandlers.
* A {@link MessageEndpoint} implementation that waits for a group of
* Base class for {@link MessageBarrier}-based Message Consumers.
* A {@link MessageConsumer} implementation that waits for a group of
* {@link Message Messages} to arrive and processes them together.
* Uses a {@link MessageBarr ier} to store messages and to decide how
* Uses a {@link MessageBarrier} to store messages and to decide how
* the messages should be released.
* <p>
* Each {@link Message} that is received by this endpoint will be associated with
* Each {@link Message} that is received by this consumer will be associated with
* a group based upon the '<code>correlationId</code>' property of its
* header. If no such property is available, a {@link MessageHandlingException}
* will be thrown.
@@ -60,7 +63,7 @@ import org.springframework.util.ObjectUtils;
* @author Mark Fisher
* @author Marius Bogoevici
*/
public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHandlingEndpoint implements TaskSchedulerAware {
public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHandlingEndpoint implements TaskSchedulerAware, InitializingBean {
public final static long DEFAULT_SEND_TIMEOUT = 1000;
@@ -91,8 +94,11 @@ public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHand
private volatile boolean initialized;
private TaskScheduler taskScheduler;
private ScheduledFuture<?> reaperFutureTask;
/**
* Specify a channel for sending Messages that arrive after their aggregation
* group has either completed or timed-out.
@@ -141,26 +147,32 @@ public abstract class AbstractMessageBarrierEndpoint extends AbstractMessageHand
this.timeout = timeout;
}
/**
* Initialize this endpoint.
*/
@Override
protected void initialize() throws Exception {
super.initialize();
public void setTaskScheduler(TaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
public void afterPropertiesSet() {
this.trackedCorrelationIds = new ArrayBlockingQueue<Object>(this.trackedCorrelationIdCapacity);
this.initialized = true;
}
@Override
protected void onStart() {
super.onStart();
this.reaperFutureTask = this.getTaskScheduler().schedule(new ReaperTask(), new IntervalTrigger(reaperInterval, TimeUnit.MILLISECONDS));
public boolean isRunning() {
return this.reaperFutureTask != null;
}
@Override
protected void onStop() {
super.onStop();
this.reaperFutureTask.cancel(true);
public void start() {
if (this.isRunning()) {
return;
}
Assert.state(this.taskScheduler != null, "TaskScheduler must not be null");
this.reaperFutureTask = this.taskScheduler.schedule(
new ReaperTask(), new IntervalTrigger(this.reaperInterval, TimeUnit.MILLISECONDS));
}
public void stop() {
if (this.isRunning()) {
this.reaperFutureTask.cancel(true);
}
}
@Override

View File

@@ -18,13 +18,11 @@ package org.springframework.integration.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.endpoint.config.ConsumerEndpointFactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
@@ -40,8 +38,6 @@ public abstract class AbstractEndpointParser extends AbstractSingleBeanDefinitio
protected static final String METHOD_ATTRIBUTE = "method";
protected static final String INPUT_CHANNEL_ATTRIBUTE = "input-channel";
protected static final String OUTPUT_CHANNEL_ATTRIBUTE = "output-channel";
private static final String POLLER_ELEMENT = "poller";
@@ -51,20 +47,9 @@ public abstract class AbstractEndpointParser extends AbstractSingleBeanDefinitio
private static final String ERROR_HANDLER_ATTRIBUTE = "error-handler";
/**
* Subclasses may override this method to determine whether the endpoint
* type should create an adapter. If so, the "ref" attribute will be
* required, and the "method" attribute will typically be used as well.
*
* <p>The default is <em>true</em>.
*/
protected boolean shouldCreateAdapter(Element element) {
return true;
}
@Override
protected final Class<?> getBeanClass(Element element) {
return this.getEndpointClass();
return ConsumerEndpointFactoryBean.class;
}
@Override
@@ -77,22 +62,42 @@ public abstract class AbstractEndpointParser extends AbstractSingleBeanDefinitio
return true;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
if (this.shouldCreateAdapter(element)) {
String ref = element.getAttribute(REF_ATTRIBUTE);
Assert.hasText(ref, "The '" + REF_ATTRIBUTE + "' attribute is required.");
if (StringUtils.hasText(element.getAttribute(METHOD_ATTRIBUTE))) {
String method = element.getAttribute(METHOD_ATTRIBUTE);
String adapterBeanName = this.parseAdapter(ref, method, element, parserContext);
builder.addConstructorArgReference(adapterBeanName);
}
else {
builder.addConstructorArgReference(ref);
}
/**
* Parse the MessageConsumer.
*/
protected abstract BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext);
protected String getInputChannelAttributeName() {
return "input-channel";
}
protected String parseAdapter(Element element, ParserContext parserContext, Class<?> adapterClass) {
String ref = element.getAttribute(REF_ATTRIBUTE);
Assert.hasText(ref, "The '" + REF_ATTRIBUTE + "' attribute is required.");
if (StringUtils.hasText(element.getAttribute(METHOD_ATTRIBUTE))) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(adapterClass);
String method = element.getAttribute(METHOD_ATTRIBUTE);
builder.addConstructorArgReference(ref);
builder.addConstructorArgValue(method);
return BeanDefinitionReaderUtils.registerWithGeneratedName(
builder.getBeanDefinition(), parserContext.getRegistry());
}
String inputChannel = element.getAttribute(INPUT_CHANNEL_ATTRIBUTE);
Assert.hasText(inputChannel, "the '" + INPUT_CHANNEL_ATTRIBUTE + "' attribute is required");
return ref;
}
@Override
protected final void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
BeanDefinitionBuilder consumerBuilder = this.parseConsumer(element, parserContext);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(consumerBuilder, element, OUTPUT_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(consumerBuilder, element, SELECTOR_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(consumerBuilder, element, ERROR_HANDLER_ATTRIBUTE);
String consumerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
consumerBuilder.getBeanDefinition(), parserContext.getRegistry());
builder.addConstructorArgReference(consumerBeanName);
String inputChannelAttributeName = this.getInputChannelAttributeName();
String inputChannelName = element.getAttribute(inputChannelAttributeName);
Assert.hasText(inputChannelName, "the '" + inputChannelAttributeName + "' attribute is required");
builder.addPropertyValue("inputChannelName", inputChannelName);
Element pollerElement = DomUtils.getChildElementByTagName(element, POLLER_ELEMENT);
if (pollerElement != null) {
IntegrationNamespaceUtils.configureTrigger(pollerElement, builder);
@@ -102,41 +107,13 @@ public abstract class AbstractEndpointParser extends AbstractSingleBeanDefinitio
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, pollerElement, "task-executor");
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, INPUT_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, OUTPUT_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, SELECTOR_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, ERROR_HANDLER_ATTRIBUTE);
this.postProcess(element, parserContext, builder);
}
private String parseAdapter(String ref, String method, Element element, ParserContext parserContext) {
Class<?> adapterClass = this.getMethodInvokingAdapterClass();
Assert.state(adapterClass != null,
"Parser needs to create an adapter but 'getMethodInvokingAdapterClass()' returned null.");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(adapterClass);
builder.addConstructorArgReference(ref);
builder.addConstructorArgValue(method);
String adapterBeanName = BeanDefinitionReaderUtils.generateBeanName(
builder.getBeanDefinition(), parserContext.getRegistry());
BeanDefinitionHolder holder = new BeanDefinitionHolder(builder.getBeanDefinition(), adapterBeanName);
parserContext.registerBeanComponent(new BeanComponentDefinition(holder));
return adapterBeanName;
}
/**
* Subclasses may implement this method to provide additional configuration.
*/
protected void postProcess(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
}
/**
* Subclasses must override this if the adapted object is created from
* the "ref" and "method" attribute values.
*/
protected Class<?> getMethodInvokingAdapterClass() {
return null;
}
protected abstract Class<? extends MessageEndpoint> getEndpointClass();
}

View File

@@ -22,7 +22,7 @@ import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.endpoint.OutboundChannelAdapter;
import org.springframework.integration.endpoint.config.ConsumerEndpointFactoryBean;
import org.springframework.util.Assert;
import org.springframework.util.xml.DomUtils;
@@ -36,20 +36,18 @@ public abstract class AbstractOutboundChannelAdapterParser extends AbstractChann
@Override
protected AbstractBeanDefinition doParse(Element element, ParserContext parserContext, String channelName) {
Element pollerElement = DomUtils.getChildElementByTagName(element, "poller");
BeanDefinitionBuilder adapterBuilder = null;
adapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(OutboundChannelAdapter.class);
String consumerBeanName = this.parseAndRegisterConsumer(element, parserContext);
adapterBuilder.addConstructorArgReference(consumerBeanName);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ConsumerEndpointFactoryBean.class);
builder.addConstructorArgReference(this.parseAndRegisterConsumer(element, parserContext));
if (pollerElement != null) {
Assert.hasText(channelName, "outbound channel adapter with a 'poller' requires a 'channel' to poll");
IntegrationNamespaceUtils.configureTrigger(pollerElement, adapterBuilder);
IntegrationNamespaceUtils.configureTrigger(pollerElement, builder);
Element txElement = DomUtils.getChildElementByTagName(pollerElement, "transactional");
if (txElement != null) {
IntegrationNamespaceUtils.configureTransactionAttributes(txElement, adapterBuilder);
IntegrationNamespaceUtils.configureTransactionAttributes(txElement, builder);
}
}
adapterBuilder.addPropertyReference("inputChannel", channelName);
return adapterBuilder.getBeanDefinition();
builder.addPropertyValue("inputChannelName", channelName);
return builder.getBeanDefinition();
}
/**

View File

@@ -22,9 +22,8 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.aggregator.AggregatorEndpoint;
import org.springframework.integration.aggregator.MethodInvokingAggregator;
import org.springframework.integration.aggregator.CompletionStrategyAdapter;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.aggregator.MethodInvokingAggregator;
import org.springframework.util.StringUtils;
/**
@@ -36,40 +35,35 @@ import org.springframework.util.StringUtils;
*/
public class AggregatorParser extends AbstractEndpointParser {
public static final String COMPLETION_STRATEGY_REF_ATTRIBUTE = "completion-strategy";
private static final String COMPLETION_STRATEGY_REF_ATTRIBUTE = "completion-strategy";
public static final String COMPLETION_STRATEGY_METHOD_ATTRIBUTE = "completion-strategy-method";
private static final String COMPLETION_STRATEGY_METHOD_ATTRIBUTE = "completion-strategy-method";
public static final String DISCARD_CHANNEL_ATTRIBUTE = "discard-channel";
private static final String DISCARD_CHANNEL_ATTRIBUTE = "discard-channel";
public static final String SEND_TIMEOUT_ATTRIBUTE = "send-timeout";
private static final String SEND_TIMEOUT_ATTRIBUTE = "send-timeout";
public static final String SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE = "send-partial-result-on-timeout";
private static final String SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE = "send-partial-result-on-timeout";
public static final String REAPER_INTERVAL_ATTRIBUTE = "reaper-interval";
private static final String REAPER_INTERVAL_ATTRIBUTE = "reaper-interval";
public static final String TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE = "tracked-correlation-id-capacity";
private static final String TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE = "tracked-correlation-id-capacity";
public static final String TIMEOUT_ATTRIBUTE = "timeout";
private static final String TIMEOUT_ATTRIBUTE = "timeout";
private static final String COMPLETION_STRATEGY_PROPERTY = "completionStrategy";
public static final String AGGREGATOR_ELEMENT = "aggregator";
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return AggregatorEndpoint.class;
}
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MethodInvokingAggregator.class;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, parserContext, builder);
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(AggregatorEndpoint.class);
builder.addConstructorArgReference(this.parseAdapter(element, parserContext, MethodInvokingAggregator.class));
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, DISCARD_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, SEND_TIMEOUT_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, REAPER_INTERVAL_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, TIMEOUT_ATTRIBUTE);
final String completionStrategyRef = element.getAttribute(COMPLETION_STRATEGY_REF_ATTRIBUTE);
final String completionStrategyMethod = element.getAttribute(COMPLETION_STRATEGY_METHOD_ATTRIBUTE);
if (StringUtils.hasText(completionStrategyRef)) {
@@ -82,12 +76,7 @@ public class AggregatorParser extends AbstractEndpointParser {
builder.addPropertyReference(COMPLETION_STRATEGY_PROPERTY, completionStrategyRef);
}
}
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, DISCARD_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, SEND_TIMEOUT_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, REAPER_INTERVAL_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, TIMEOUT_ATTRIBUTE);
return builder;
}
private String createCompletionStrategyAdapter(String ref, String method, ParserContext parserContext) {

View File

@@ -16,7 +16,10 @@
package org.springframework.integration.config;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.filter.FilterEndpoint;
import org.springframework.integration.filter.MethodInvokingSelector;
@@ -28,13 +31,10 @@ import org.springframework.integration.filter.MethodInvokingSelector;
public class FilterParser extends AbstractEndpointParser {
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return FilterEndpoint.class;
}
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MethodInvokingSelector.class;
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(FilterEndpoint.class);
builder.addConstructorArgReference(this.parseAdapter(element, parserContext, MethodInvokingSelector.class));
return builder;
}
}

View File

@@ -19,7 +19,7 @@ package org.springframework.integration.config;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.aggregator.ResequencerEndpoint;
/**
@@ -27,33 +27,34 @@ import org.springframework.integration.aggregator.ResequencerEndpoint;
*
* @author Marius Bogoevici
*/
public class ResequencerParser extends AbstractSimpleBeanDefinitionParser {
public class ResequencerParser extends AbstractEndpointParser {
public static final String INPUT_CHANNEL_ATTRIBUTE = "input-channel";
private static final String DISCARD_CHANNEL_ATTRIBUTE = "discard-channel";
public static final String OUTPUT_CHANNEL_ATTRIBUTE = "output-channel";
private static final String SEND_TIMEOUT_ATTRIBUTE = "send-timeout";
public static final String DISCARD_CHANNEL_ATTRIBUTE = "discard-channel";
private static final String RELEASE_PARTIAL_SEQUENCES = "release-partial-sequences";
private static final String SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE = "send-partial-result-on-timeout";
private static final String REAPER_INTERVAL_ATTRIBUTE = "reaper-interval";
private static final String TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE = "tracked-correlation-id-capacity";
private static final String TIMEOUT_ATTRIBUTE = "timeout";
@Override
protected Class<?> getBeanClass(Element element) {
return ResequencerEndpoint.class;
}
@Override
protected boolean isEligibleAttribute(String attributeName) {
return !INPUT_CHANNEL_ATTRIBUTE.equals(attributeName)
&&!OUTPUT_CHANNEL_ATTRIBUTE.equals(attributeName)
&& !DISCARD_CHANNEL_ATTRIBUTE.equals(attributeName)
&& super.isEligibleAttribute(attributeName);
}
@Override
protected void postProcess(BeanDefinitionBuilder builder, Element element) {
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, INPUT_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, OUTPUT_CHANNEL_ATTRIBUTE);
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ResequencerEndpoint.class);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, DISCARD_CHANNEL_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, SEND_TIMEOUT_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, RELEASE_PARTIAL_SEQUENCES);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, SEND_PARTIAL_RESULT_ON_TIMEOUT_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, REAPER_INTERVAL_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, TRACKED_CORRELATION_ID_CAPACITY_ATTRIBUTE);
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, TIMEOUT_ATTRIBUTE);
return builder;
}
}

View File

@@ -20,7 +20,6 @@ import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.router.MethodInvokingChannelResolver;
import org.springframework.integration.router.RouterEndpoint;
@@ -32,18 +31,13 @@ import org.springframework.integration.router.RouterEndpoint;
public class RouterParser extends AbstractEndpointParser {
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return RouterEndpoint.class;
}
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MethodInvokingChannelResolver.class;
}
@Override
protected void postProcess(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
String adapterBeanName = this.parseAdapter(element, parserContext, MethodInvokingChannelResolver.class);
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(RouterEndpoint.class);
builder.addConstructorArgReference(adapterBeanName);
builder.addPropertyReference("channelRegistry", MessageBusParser.MESSAGE_BUS_BEAN_NAME);
IntegrationNamespaceUtils.setReferenceIfAttributeDefined(builder, element, "default-output-channel");
return builder;
}
}

View File

@@ -16,7 +16,10 @@
package org.springframework.integration.config;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.endpoint.ServiceActivatorEndpoint;
import org.springframework.integration.message.MessageMappingMethodInvoker;
@@ -28,13 +31,11 @@ import org.springframework.integration.message.MessageMappingMethodInvoker;
public class ServiceActivatorParser extends AbstractEndpointParser {
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return ServiceActivatorEndpoint.class;
}
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MessageMappingMethodInvoker.class;
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(ServiceActivatorEndpoint.class);
String constructorArg = this.parseAdapter(element, parserContext, MessageMappingMethodInvoker.class);
builder.addConstructorArgReference(constructorArg);
return builder;
}
}

View File

@@ -18,7 +18,8 @@ package org.springframework.integration.config;
import org.w3c.dom.Element;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.splitter.MethodInvokingSplitter;
import org.springframework.integration.splitter.SplitterEndpoint;
@@ -30,18 +31,13 @@ import org.springframework.integration.splitter.SplitterEndpoint;
public class SplitterParser extends AbstractEndpointParser {
@Override
protected boolean shouldCreateAdapter(Element element) {
return element.hasAttribute("ref");
}
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return SplitterEndpoint.class;
}
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MethodInvokingSplitter.class;
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(SplitterEndpoint.class);
if (element.hasAttribute("ref")) {
String adapterBeanName = this.parseAdapter(element, parserContext, MethodInvokingSplitter.class);
builder.addConstructorArgReference(adapterBeanName);
}
return builder;
}
}

View File

@@ -16,7 +16,10 @@
package org.springframework.integration.config;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.w3c.dom.Element;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.transformer.MethodInvokingTransformer;
import org.springframework.integration.transformer.TransformerEndpoint;
@@ -28,13 +31,10 @@ import org.springframework.integration.transformer.TransformerEndpoint;
public class TransformerParser extends AbstractEndpointParser {
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return TransformerEndpoint.class;
}
@Override
protected Class<?> getMethodInvokingAdapterClass() {
return MethodInvokingTransformer.class;
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TransformerEndpoint.class);
builder.addConstructorArgReference(this.parseAdapter(element, parserContext, MethodInvokingTransformer.class));
return builder;
}
}

View File

@@ -19,15 +19,21 @@ package org.springframework.integration.config.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.endpoint.AbstractMessageConsumingEndpoint;
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.scheduling.IntervalTrigger;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -58,55 +64,73 @@ public abstract class AbstractMethodAnnotationPostProcessor<T extends Annotation
}
public Object postProcess(Object bean, String beanName, Method method, T annotation) {
Object adapter = this.createMethodInvokingAdapter(bean, method, annotation);
if (adapter != null && this.shouldCreateEndpoint(annotation)) {
AbstractEndpoint endpoint = this.createEndpoint(bean, adapter);
if (endpoint != null) {
Poller pollerAnnotation = AnnotationUtils.findAnnotation(method, Poller.class);
this.configureEndpoint(endpoint, annotation, pollerAnnotation);
endpoint.afterPropertiesSet();
return endpoint;
}
MessageConsumer consumer = this.createConsumer(bean, method, annotation);
if (consumer instanceof ChannelRegistryAware) {
((ChannelRegistryAware) consumer).setChannelRegistry(this.getChannelRegistry());
}
return adapter;
Poller pollerAnnotation = AnnotationUtils.findAnnotation(method, Poller.class);
MessageEndpoint endpoint = this.createEndpoint(consumer, annotation, pollerAnnotation);
if (endpoint != null) {
if (endpoint instanceof InitializingBean) {
try {
((InitializingBean) endpoint).afterPropertiesSet();
}
catch (Exception e) {
throw new IllegalStateException(
"failed to initialize annotation-based consumer", e);
}
}
return endpoint;
}
return consumer;
}
protected boolean shouldCreateEndpoint(T annotation) {
return (StringUtils.hasText((String) AnnotationUtils.getValue(annotation, INPUT_CHANNEL_ATTRIBUTE)));
}
protected void configureEndpoint(AbstractEndpoint endpoint, T annotation, Poller pollerAnnotation) {
private MessageEndpoint createEndpoint(MessageConsumer consumer, T annotation, Poller pollerAnnotation) {
MessageEndpoint endpoint = null;
String inputChannelName = (String) AnnotationUtils.getValue(annotation, INPUT_CHANNEL_ATTRIBUTE);
if (StringUtils.hasText(inputChannelName)) {
MessageChannel inputChannel = this.messageBus.lookupChannel(inputChannelName);
Assert.notNull(inputChannel, "unable to resolve inputChannel '" + inputChannelName + "'");
if (endpoint instanceof AbstractMessageConsumingEndpoint) {
AbstractMessageConsumingEndpoint consumingEndpoint = (AbstractMessageConsumingEndpoint) endpoint;
if (pollerAnnotation != null) {
Assert.isInstanceOf(PollableChannel.class, inputChannel,
"The @Poller annotation should only be provided for a PollableChannel");
IntervalTrigger trigger = new IntervalTrigger(
pollerAnnotation.interval(), pollerAnnotation.timeUnit());
trigger.setInitialDelay(pollerAnnotation.initialDelay(), pollerAnnotation.timeUnit());
trigger.setFixedRate(pollerAnnotation.fixedRate());
consumingEndpoint.setTrigger(trigger);
consumingEndpoint.setMaxMessagesPerPoll(pollerAnnotation.maxMessagesPerPoll());
if (consumer instanceof AbstractMessageConsumingEndpoint) {
if (inputChannel instanceof PollableChannel) {
PollingConsumerEndpoint pollingEndpoint = new PollingConsumerEndpoint(
consumer, (PollableChannel) inputChannel);
if (pollerAnnotation != null) {
IntervalTrigger trigger = new IntervalTrigger(
pollerAnnotation.interval(), pollerAnnotation.timeUnit());
trigger.setInitialDelay(pollerAnnotation.initialDelay(), pollerAnnotation.timeUnit());
trigger.setFixedRate(pollerAnnotation.fixedRate());
pollingEndpoint.setTrigger(trigger);
pollingEndpoint.setMaxMessagesPerPoll(pollerAnnotation.maxMessagesPerPoll());
}
endpoint = pollingEndpoint;
}
else if (inputChannel instanceof SubscribableChannel) {
Assert.isTrue(pollerAnnotation == null,
"The @Poller annotation should only be provided for a PollableChannel");
endpoint = new SubscribingConsumerEndpoint(consumer, (SubscribableChannel) inputChannel);
}
else {
throw new IllegalArgumentException("unsupported channel type: ["
+ inputChannel.getClass() + "]");
}
consumingEndpoint.setInputChannel(inputChannel);
}
if (endpoint instanceof AbstractMessageHandlingEndpoint) {
if (consumer instanceof AbstractMessageHandlingEndpoint) {
String outputChannelName = (String) AnnotationUtils.getValue(annotation, OUTPUT_CHANNEL_ATTRIBUTE);
if (StringUtils.hasText(outputChannelName)) {
MessageChannel outputChannel = this.messageBus.lookupChannel(outputChannelName);
Assert.notNull(outputChannel, "unable to resolve outputChannel '" + outputChannelName + "'");
((AbstractMessageHandlingEndpoint) endpoint).setOutputChannel(outputChannel);
((AbstractMessageHandlingEndpoint) consumer).setOutputChannel(outputChannel);
}
}
}
return endpoint;
}
protected abstract Object createMethodInvokingAdapter(Object bean, Method method, T annotation);
protected abstract AbstractEndpoint createEndpoint(Object originalBean, Object adapter);
protected abstract MessageConsumer createConsumer(Object bean, Method method, T annotation);
}

View File

@@ -25,10 +25,9 @@ import org.springframework.integration.aggregator.CompletionStrategyAdapter;
import org.springframework.integration.aggregator.MethodInvokingAggregator;
import org.springframework.integration.annotation.Aggregator;
import org.springframework.integration.annotation.CompletionStrategy;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
@@ -46,44 +45,31 @@ public class AggregatorAnnotationPostProcessor extends AbstractMethodAnnotationP
@Override
protected Object createMethodInvokingAdapter(Object bean, Method method, Aggregator annotation) {
return new MethodInvokingAggregator(bean, method);
}
@Override
protected AbstractEndpoint createEndpoint(Object originalBean, Object adapter) {
if (adapter instanceof org.springframework.integration.aggregator.Aggregator) {
AggregatorEndpoint endpoint = new AggregatorEndpoint((org.springframework.integration.aggregator.Aggregator) adapter);
this.configureCompletionStrategy(originalBean, endpoint);
return endpoint;
}
return null;
}
@Override
protected void configureEndpoint(AbstractEndpoint endpoint, Aggregator annotation, Poller pollerAnnotation) {
super.configureEndpoint(endpoint, annotation, pollerAnnotation);
AggregatorEndpoint aggregatorEndpoint = (AggregatorEndpoint) endpoint;
protected MessageConsumer createConsumer(Object bean, Method method, Aggregator annotation) {
MethodInvokingAggregator adapter = new MethodInvokingAggregator(bean, method);
AggregatorEndpoint aggregator = new AggregatorEndpoint(adapter);
this.configureCompletionStrategy(bean, aggregator);
String discardChannelName = annotation.discardChannel();
if (StringUtils.hasText(discardChannelName)) {
MessageChannel discardChannel = this.getChannelRegistry().lookupChannel(discardChannelName);
Assert.notNull(discardChannel, "unable to resolve discardChannel '" + discardChannelName + "'");
aggregatorEndpoint.setDiscardChannel(discardChannel);
aggregator.setDiscardChannel(discardChannel);
}
aggregatorEndpoint.setSendTimeout(annotation.sendTimeout());
aggregatorEndpoint.setSendPartialResultOnTimeout(annotation.sendPartialResultsOnTimeout());
aggregatorEndpoint.setReaperInterval(annotation.reaperInterval());
aggregatorEndpoint.setTimeout(annotation.timeout());
aggregatorEndpoint.setTrackedCorrelationIdCapacity(annotation.trackedCorrelationIdCapacity());
aggregatorEndpoint.afterPropertiesSet();
aggregator.setSendTimeout(annotation.sendTimeout());
aggregator.setSendPartialResultOnTimeout(annotation.sendPartialResultsOnTimeout());
aggregator.setReaperInterval(annotation.reaperInterval());
aggregator.setTimeout(annotation.timeout());
aggregator.setTrackedCorrelationIdCapacity(annotation.trackedCorrelationIdCapacity());
aggregator.afterPropertiesSet();
return aggregator;
}
private void configureCompletionStrategy(final Object object, final AggregatorEndpoint handler) {
ReflectionUtils.doWithMethods(object.getClass(), new ReflectionUtils.MethodCallback() {
private void configureCompletionStrategy(final Object bean, final AggregatorEndpoint aggregator) {
ReflectionUtils.doWithMethods(bean.getClass(), new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException {
Annotation annotation = AnnotationUtils.getAnnotation(method, CompletionStrategy.class);
if (annotation != null) {
handler.setCompletionStrategy(new CompletionStrategyAdapter(object, method));
aggregator.setCompletionStrategy(new CompletionStrategyAdapter(bean, method));
}
}
});

View File

@@ -26,9 +26,11 @@ import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.endpoint.OutboundChannelAdapter;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.MethodInvokingConsumer;
import org.springframework.integration.message.MethodInvokingSource;
import org.springframework.integration.scheduling.IntervalTrigger;
@@ -102,16 +104,19 @@ public class ChannelAdapterAnnotationPostProcessor implements MethodAnnotationPo
return adapter;
}
private OutboundChannelAdapter createOutboundChannelAdapter(MethodInvokingConsumer consumer, MessageChannel channel, Poller pollerAnnotation) {
OutboundChannelAdapter adapter = new OutboundChannelAdapter(consumer);
adapter.setInputChannel(channel);
private MessageEndpoint createOutboundChannelAdapter(MethodInvokingConsumer consumer, MessageChannel channel, Poller pollerAnnotation) {
if (channel instanceof PollableChannel) {
Trigger trigger = (pollerAnnotation != null)
? this.createTrigger(pollerAnnotation)
: new IntervalTrigger(0);
adapter.setTrigger(trigger);
PollingConsumerEndpoint endpoint = new PollingConsumerEndpoint(consumer, (PollableChannel) channel);
endpoint.setTrigger(trigger);
return endpoint;
}
return adapter;
if (channel instanceof SubscribableChannel) {
return new SubscribingConsumerEndpoint(consumer, (SubscribableChannel) channel);
}
return null;
}
private Trigger createTrigger(Poller pollerAnnotation) {

View File

@@ -18,11 +18,10 @@ package org.springframework.integration.config.annotation;
import java.lang.reflect.Method;
import org.springframework.integration.annotation.Poller;
import org.springframework.integration.annotation.Router;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.router.MethodInvokingChannelResolver;
import org.springframework.integration.router.RouterEndpoint;
import org.springframework.util.Assert;
@@ -41,27 +40,16 @@ public class RouterAnnotationPostProcessor extends AbstractMethodAnnotationPostP
@Override
protected Object createMethodInvokingAdapter(Object bean, Method method, Router annotation) {
return new MethodInvokingChannelResolver(bean, method);
}
@Override
protected AbstractEndpoint createEndpoint(Object originalBean, Object adapter) {
if (adapter instanceof MethodInvokingChannelResolver) {
return new RouterEndpoint((MethodInvokingChannelResolver) adapter);
}
return null;
}
@Override
protected void configureEndpoint(AbstractEndpoint endpoint, Router annotation, Poller pollerAnnotation) {
super.configureEndpoint(endpoint, annotation, pollerAnnotation);
protected MessageConsumer createConsumer(Object bean, Method method, Router annotation) {
MethodInvokingChannelResolver resolver = new MethodInvokingChannelResolver(bean, method);
RouterEndpoint router = new RouterEndpoint(resolver);
String defaultOutputChannelName = annotation.defaultOutputChannel();
if (StringUtils.hasText(defaultOutputChannelName)) {
MessageChannel defaultOutputChannel = this.getChannelRegistry().lookupChannel(defaultOutputChannelName);
Assert.notNull(defaultOutputChannel, "unable to resolve defaultOutputChannel '" + defaultOutputChannelName + "'");
((RouterEndpoint) endpoint).setDefaultOutputChannel(defaultOutputChannel);
router.setDefaultOutputChannel(defaultOutputChannel);
}
return router;
}
}

View File

@@ -20,10 +20,9 @@ import java.lang.reflect.Method;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.ServiceActivatorEndpoint;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.message.MessageMappingMethodInvoker;
import org.springframework.integration.util.MethodInvoker;
/**
* Post-processor for Methods annotated with {@link ServiceActivator @ServiceActivator}.
@@ -38,16 +37,9 @@ public class ServiceActivatorAnnotationPostProcessor extends AbstractMethodAnnot
@Override
protected Object createMethodInvokingAdapter(Object bean, Method method, ServiceActivator annotation) {
return new MessageMappingMethodInvoker(bean, method);
}
@Override
protected AbstractEndpoint createEndpoint(Object originalBean, Object adapter) {
if (adapter instanceof MethodInvoker) {
return new ServiceActivatorEndpoint((MethodInvoker) adapter);
}
return null;
protected MessageConsumer createConsumer(Object bean, Method method, ServiceActivator annotation) {
MessageMappingMethodInvoker invoker = new MessageMappingMethodInvoker(bean, method);
return new ServiceActivatorEndpoint(invoker);
}
}

View File

@@ -20,7 +20,7 @@ import java.lang.reflect.Method;
import org.springframework.integration.annotation.Splitter;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.splitter.MethodInvokingSplitter;
import org.springframework.integration.splitter.SplitterEndpoint;
@@ -37,16 +37,9 @@ public class SplitterAnnotationPostProcessor extends AbstractMethodAnnotationPos
@Override
protected Object createMethodInvokingAdapter(Object bean, Method method, Splitter annotation) {
return new MethodInvokingSplitter(bean, method);
}
@Override
protected AbstractEndpoint createEndpoint(Object originalBean, Object adapter) {
if (adapter instanceof MethodInvokingSplitter) {
return new SplitterEndpoint((MethodInvokingSplitter) adapter);
}
return null;
protected MessageConsumer createConsumer(Object bean, Method method, Splitter annotation) {
MethodInvokingSplitter splitter = new MethodInvokingSplitter(bean, method);
return new SplitterEndpoint(splitter);
}
}

View File

@@ -20,7 +20,7 @@ import java.lang.reflect.Method;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.transformer.MethodInvokingTransformer;
import org.springframework.integration.transformer.TransformerEndpoint;
@@ -37,16 +37,9 @@ public class TransformerAnnotationPostProcessor extends AbstractMethodAnnotation
@Override
protected Object createMethodInvokingAdapter(Object bean, Method method, Transformer annotation) {
return new MethodInvokingTransformer(bean, method);
}
@Override
protected AbstractEndpoint createEndpoint(Object originalBean, Object adapter) {
if (adapter instanceof MethodInvokingTransformer) {
return new TransformerEndpoint((MethodInvokingTransformer) adapter);
}
return null;
protected MessageConsumer createConsumer(Object bean, Method method, Transformer annotation) {
MethodInvokingTransformer transformer = new MethodInvokingTransformer(bean, method);
return new TransformerEndpoint(transformer);
}
}

View File

@@ -16,65 +16,31 @@
package org.springframework.integration.endpoint;
import java.util.concurrent.ScheduledFuture;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.Lifecycle;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.scheduling.IntervalTrigger;
import org.springframework.integration.scheduling.Trigger;
import org.springframework.integration.util.ErrorHandler;
import org.springframework.util.Assert;
/**
* The base class for Message Endpoint implementations that consume Messages.
* Base class for MessageConsumer implementations.
*
* @author Mark Fisher
*/
public abstract class AbstractMessageConsumingEndpoint extends AbstractEndpoint implements MessageConsumer, Lifecycle {
public abstract class AbstractMessageConsumingEndpoint implements MessageConsumer {
private volatile MessageChannel inputChannel;
private volatile Trigger trigger = new IntervalTrigger(0);
private volatile ChannelPoller poller;
private volatile ScheduledFuture<?> pollerFuture;
private volatile TaskExecutor taskExecutor;
private volatile int maxMessagesPerPoll = -1;
protected final Log logger = LogFactory.getLog(this.getClass());
private volatile ErrorHandler errorHandler;
private volatile boolean initialized;
private volatile boolean running;
private final Object lifecycleMonitor = new Object();
public void setInputChannel(MessageChannel inputChannel) {
this.inputChannel = inputChannel;
}
public void setTrigger(Trigger trigger) {
this.trigger = trigger;
}
public void setTaskExecutor(TaskExecutor taskExecutor) {
this.taskExecutor = taskExecutor;
}
/**
* Provide an error handler for any Exceptions that occur
* upon invocation of this endpoint. If none is provided,
* upon invocation of this consumer. If none is provided,
* the Exception messages will be logged (at warn level),
* and the Exception rethrown.
*/
@@ -82,94 +48,11 @@ public abstract class AbstractMessageConsumingEndpoint extends AbstractEndpoint
this.errorHandler = errorHandler;
}
public void setMaxMessagesPerPoll(int maxMessagesPerPoll) {
this.maxMessagesPerPoll = maxMessagesPerPoll;
if (this.poller != null) {
this.poller.setMaxMessagesPerPoll(maxMessagesPerPoll);
}
}
public final boolean isRunning() {
return this.running;
}
@Override
protected void initialize() throws Exception {
synchronized (this.lifecycleMonitor) {
if (this.inputChannel instanceof PollableChannel && this.poller == null) {
this.poller = new ChannelPoller((PollableChannel) this.inputChannel, this.trigger);
this.poller.setMaxMessagesPerPoll(this.maxMessagesPerPoll);
this.configureTransactionSettingsForPoller(this.poller);
if (this.taskExecutor != null) {
this.poller.setTaskExecutor(this.taskExecutor);
}
this.poller.setConsumer(this);
}
this.initialized = true;
}
}
public final void start() {
synchronized (this.lifecycleMonitor) {
if (this.running) {
return;
}
if (!this.initialized) {
this.afterPropertiesSet();
}
Assert.notNull(this.inputChannel, "failed to start endpoint, inputChannel is required");
if (this.inputChannel instanceof SubscribableChannel) {
((SubscribableChannel) inputChannel).subscribe(this);
}
else if (this.inputChannel instanceof PollableChannel) {
Assert.notNull(this.getTaskScheduler(),
"failed to start endpoint, no taskScheduler available");
this.pollerFuture = this.getTaskScheduler().schedule(this.poller, this.poller.getTrigger());
}
onStart();
this.running = true;
}
}
public final void stop() {
synchronized (this.lifecycleMonitor) {
if (!this.running) {
return;
}
if (this.inputChannel instanceof SubscribableChannel) {
((SubscribableChannel) inputChannel).unsubscribe(this);
}
else if (this.pollerFuture != null) {
this.pollerFuture.cancel(true);
}
onStop();
this.running = false;
}
}
/**
* Subclasses might override this to supply their own start code (e.g. if they start threads
* on their own). This method will be called within the lifecycleMonitor.
*/
protected void onStart() {
}
/**
* Subclasses might override this to supply their own stop code (e.g. if they stop threads
* on their own).This method will be called within the lifecycleMonitor.
*
*/
protected void onStop() {
}
public final void onMessage(Message<?> message) {
if (message == null || message.getPayload() == null) {
throw new IllegalArgumentException("Message and its payload must not be null");
}
Assert.notNull(message == null, "Message must not be null");
Assert.notNull(message.getPayload(), "Message payload must not be null");
if (this.logger.isDebugEnabled()) {
this.logger.debug("endpoint '" + this + "' processing message: " + message);
this.logger.debug("consumer '" + this + "' processing message: " + message);
}
try {
this.onMessageInternal(message);
@@ -180,7 +63,7 @@ public abstract class AbstractMessageConsumingEndpoint extends AbstractEndpoint
}
else {
this.handleException(new MessageHandlingException(message,
"failure occurred in endpoint '" + this.toString() + "'", e));
"failure occurred in consumer '" + this.toString() + "'", e));
}
}
}
@@ -188,7 +71,7 @@ public abstract class AbstractMessageConsumingEndpoint extends AbstractEndpoint
protected void handleException(MessagingException exception) {
if (this.errorHandler == null) {
if (this.logger.isWarnEnabled()) {
this.logger.warn("exception occurred in endpoint '" + this + "'", exception);
this.logger.warn("exception occurred in consumer '" + this + "'", exception);
}
throw exception;
}

View File

@@ -22,6 +22,7 @@ import java.util.List;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.MessageChannelTemplate;
import org.springframework.integration.message.CompositeMessage;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageBuilder;
@@ -30,6 +31,7 @@ import org.springframework.integration.message.MessageHeaders;
import org.springframework.integration.message.MessageRejectedException;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.message.selector.MessageSelector;
import org.springframework.util.Assert;
/**
* @author Mark Fisher
@@ -44,6 +46,8 @@ public abstract class AbstractMessageHandlingEndpoint extends AbstractMessageCon
private volatile boolean requiresReply = false;
private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
public void setOutputChannel(MessageChannel outputChannel) {
this.outputChannel = outputChannel;
@@ -74,7 +78,7 @@ public abstract class AbstractMessageHandlingEndpoint extends AbstractMessageCon
Object result = this.handle(message);
if (result == null) {
if (this.requiresReply) {
throw new MessageHandlingException(message, "endpoint '" + this
throw new MessageHandlingException(message, "consumer '" + this
+ "' requires a reply, but no reply was received");
}
return;
@@ -105,7 +109,7 @@ public abstract class AbstractMessageHandlingEndpoint extends AbstractMessageCon
protected boolean supports(Message<?> message) {
if (this.selector != null && !this.selector.accept(message)) {
if (logger.isDebugEnabled()) {
logger.debug("selector for endpoint '" + this + "' rejected message: " + message);
logger.debug("selector for consumer '" + this + "' rejected message: " + message);
}
return false;
}
@@ -117,7 +121,7 @@ public abstract class AbstractMessageHandlingEndpoint extends AbstractMessageCon
}
private boolean sendReplyMessage(Message<?> replyMessage, MessageChannel replyChannel) {
return this.getChannelTemplate().send(replyMessage, replyChannel);
return this.channelTemplate.send(replyMessage, replyChannel);
}
private Message<?> buildReplyMessage(Object result, MessageHeaders requestHeaders) {
@@ -153,9 +157,9 @@ public abstract class AbstractMessageHandlingEndpoint extends AbstractMessageCon
replyChannel = (MessageChannel) returnAddress;
}
else if (returnAddress instanceof String) {
if (this.channelRegistry != null) {
replyChannel = this.channelRegistry.lookupChannel((String) returnAddress);
}
Assert.state(this.channelRegistry != null,
"ChannelRegistry is required for resolving a reply channel by name");
replyChannel = this.channelRegistry.lookupChannel((String) returnAddress);
}
else {
throw new MessagingException("expected a MessageChannel or String for 'returnAddress', but type is ["

View File

@@ -140,6 +140,9 @@ public abstract class AbstractPollingEndpoint implements MessageEndpoint, TaskSc
if (!this.initialized) {
this.afterPropertiesSet();
}
if (this.isRunning()) {
return;
}
Assert.state(this.taskScheduler != null,
"unable to start polling, no taskScheduler available");
this.runningTask = this.taskScheduler.schedule(new Poller(), this.trigger);
@@ -176,7 +179,7 @@ public abstract class AbstractPollingEndpoint implements MessageEndpoint, TaskSc
private void poll() {
int count = 0;
while (maxMessagesPerPoll < 0 || count < maxMessagesPerPoll) {
while (maxMessagesPerPoll <= 0 || count < maxMessagesPerPoll) {
if (!innerPoll()) {
break;
}

View File

@@ -31,7 +31,7 @@ import org.springframework.util.Assert;
/**
* @author Mark Fisher
*/
public class ServiceActivatorEndpoint extends AbstractMessageHandlingEndpoint {
public class ServiceActivatorEndpoint extends AbstractMessageHandlingEndpoint implements InitializingBean {
private final MethodResolver methodResolver = new DefaultMethodResolver(ServiceActivator.class);
@@ -56,9 +56,7 @@ public class ServiceActivatorEndpoint extends AbstractMessageHandlingEndpoint {
}
@Override
protected void initialize() throws Exception {
super.initialize();
public void afterPropertiesSet() throws Exception {
if (this.invoker instanceof InitializingBean) {
((InitializingBean) this.invoker).afterPropertiesSet();
}

View File

@@ -22,6 +22,8 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.task.TaskExecutor;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
@@ -39,7 +41,7 @@ import org.springframework.util.Assert;
/**
* @author Mark Fisher
*/
public class ConsumerEndpointFactoryBean implements FactoryBean, BeanFactoryAware, InitializingBean {
public class ConsumerEndpointFactoryBean implements FactoryBean, ChannelRegistryAware, BeanFactoryAware, InitializingBean {
private final MessageConsumer consumer;
@@ -76,6 +78,16 @@ public class ConsumerEndpointFactoryBean implements FactoryBean, BeanFactoryAwar
this.inputChannelName = inputChannelName;
}
public void setChannelRegistry(ChannelRegistry channelRegistry) {
if (this.consumer instanceof ChannelRegistryAware) {
((ChannelRegistryAware) this.consumer).setChannelRegistry(channelRegistry);
}
}
public void setTrigger(Trigger trigger) {
this.trigger = trigger;
}
public void setMaxMessagesPerPoll(int maxMessagesPerPoll) {
this.maxMessagesPerPoll = maxMessagesPerPoll;
}

View File

@@ -21,8 +21,14 @@ import org.springframework.integration.bus.MessageBusAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.MessageChannelTemplate;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.endpoint.MessagingGateway;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.util.Assert;
@@ -42,7 +48,7 @@ public abstract class AbstractMessagingGateway implements MessagingGateway, Mess
private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
private volatile ReplyMessageCorrelator replyMessageCorrelator;
private volatile MessageEndpoint replyMessageCorrelator;
private volatile MessageBus messageBus;
@@ -145,10 +151,23 @@ public abstract class AbstractMessagingGateway implements MessagingGateway, Mess
return;
}
Assert.state(this.messageBus != null, "No MessageBus available. Cannot register ReplyMessageCorrelator.");
ReplyMessageCorrelator correlator = new ReplyMessageCorrelator();
correlator.setBeanName("internal.correlator." + this);
correlator.setInputChannel(this.replyChannel);
correlator.afterPropertiesSet();
MessageEndpoint correlator = null;
MessageConsumer consumer = new AbstractMessageHandlingEndpoint() {
@Override
protected Object handle(Message<?> message) {
return message;
}
};
if (this.replyChannel instanceof SubscribableChannel) {
correlator = new SubscribingConsumerEndpoint(
consumer, (SubscribableChannel) this.replyChannel);
}
else if (this.replyChannel instanceof PollableChannel) {
PollingConsumerEndpoint endpoint = new PollingConsumerEndpoint(
consumer, (PollableChannel) this.replyChannel);
endpoint.afterPropertiesSet();
correlator = endpoint;
}
this.messageBus.registerEndpoint(correlator);
this.replyMessageCorrelator = correlator;
}

View File

@@ -21,6 +21,7 @@ import java.util.Collection;
import org.springframework.integration.channel.ChannelRegistry;
import org.springframework.integration.channel.ChannelRegistryAware;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.MessageChannelTemplate;
import org.springframework.integration.endpoint.AbstractMessageConsumingEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageDeliveryException;
@@ -37,6 +38,8 @@ public class RouterEndpoint extends AbstractMessageConsumingEndpoint implements
private volatile boolean resolutionRequired;
private final MessageChannelTemplate channelTemplate = new MessageChannelTemplate();
public RouterEndpoint(ChannelResolver channelResolver) {
Assert.notNull(channelResolver, "ChannelResolver must not be null");
@@ -59,7 +62,7 @@ public class RouterEndpoint extends AbstractMessageConsumingEndpoint implements
* default, there is no timeout, meaning the send will block indefinitely.
*/
public void setTimeout(long timeout) {
this.getChannelTemplate().setSendTimeout(timeout);
this.channelTemplate.setSendTimeout(timeout);
}
/**
@@ -79,7 +82,7 @@ public class RouterEndpoint extends AbstractMessageConsumingEndpoint implements
if (results != null) {
for (MessageChannel channel : results) {
if (channel != null) {
if (this.getChannelTemplate().send(message, channel)) {
if (this.channelTemplate.send(message, channel)) {
sent = true;
}
}
@@ -87,7 +90,7 @@ public class RouterEndpoint extends AbstractMessageConsumingEndpoint implements
}
if (!sent) {
if (this.defaultOutputChannel != null) {
sent = this.getChannelTemplate().send(message, this.defaultOutputChannel);
sent = this.channelTemplate.send(message, this.defaultOutputChannel);
}
else if (this.resolutionRequired) {
throw new MessageDeliveryException(message,

View File

@@ -22,7 +22,6 @@ import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.AbstractEndpointParser;
import org.springframework.integration.endpoint.MessageEndpoint;
import org.springframework.integration.transformer.Transformer;
import org.springframework.integration.transformer.TransformerEndpoint;
@@ -32,23 +31,15 @@ import org.springframework.integration.transformer.TransformerEndpoint;
public abstract class AbstractTransformerParser extends AbstractEndpointParser {
@Override
protected boolean shouldCreateAdapter(Element element) {
return false;
}
@Override
protected Class<? extends MessageEndpoint> getEndpointClass() {
return TransformerEndpoint.class;
}
@Override
protected void postProcess(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
protected BeanDefinitionBuilder parseConsumer(Element element, ParserContext parserContext) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(TransformerEndpoint.class);
BeanDefinitionBuilder transformerBuilder =
BeanDefinitionBuilder.genericBeanDefinition(this.getTransformerClass());
this.parseTransformer(element, parserContext, transformerBuilder);
String transformerBeanName = BeanDefinitionReaderUtils.registerWithGeneratedName(
transformerBuilder.getBeanDefinition(), parserContext.getRegistry());
builder.addConstructorArgReference(transformerBeanName);
return builder;
}
protected abstract Class<? extends Transformer> getTransformerClass();

View File

@@ -52,7 +52,7 @@ public class AggregatorEndpointTests {
this.aggregator = new AggregatorEndpoint(new TestAggregator());
this.aggregator.setTaskScheduler(this.taskScheduler);
this.taskScheduler.start();
this.aggregator.onStart();
this.aggregator.start();
}
@Test
@@ -325,7 +325,7 @@ public class AggregatorEndpointTests {
@After
public void stopTaskScheduler() {
this.taskScheduler.stop();
this.aggregator.onStop();
this.aggregator.stop();
}
}

View File

@@ -46,7 +46,7 @@ public class ResequencerEndpointTests {
this.taskScheduler = Schedulers.createDefaultTaskScheduler(10);
this.resequencer.setTaskScheduler(taskScheduler);
taskScheduler.start();
this.resequencer.onStart();
this.resequencer.start();
}
@Test
@@ -149,7 +149,7 @@ public class ResequencerEndpointTests {
@After
public void stopTaskScheduler() {
this.resequencer.onStop();
this.resequencer.stop();
this.taskScheduler.stop();
}
}

View File

@@ -36,7 +36,9 @@ import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.ErrorMessage;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.Message;
@@ -62,17 +64,18 @@ public class DefaultMessageBusTests {
Message<String> message = MessageBuilder.withPayload("test")
.setReturnAddress("targetChannel").build();
sourceChannel.send(message);
AbstractMessageHandlingEndpoint endpoint = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
return message;
}
};
endpoint.setBeanName("testEndpoint");
endpoint.setInputChannel(sourceChannel);
PollingConsumerEndpoint endpoint = new PollingConsumerEndpoint(consumer, sourceChannel);
endpoint.afterPropertiesSet();
context.getBeanFactory().registerSingleton("testEndpoint", endpoint);
context.refresh();
DefaultMessageBus bus = new DefaultMessageBus();
bus.setApplicationContext(context);
consumer.setChannelRegistry(bus);
bus.start();
Message<?> result = targetChannel.receive(3000);
assertEquals("test", result.getPayload());
@@ -116,12 +119,12 @@ public class DefaultMessageBusTests {
QueueChannel inputChannel = new QueueChannel();
QueueChannel outputChannel1 = new QueueChannel();
QueueChannel outputChannel2 = new QueueChannel();
AbstractMessageHandlingEndpoint endpoint1 = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer1 = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
return MessageBuilder.fromMessage(message).build();
}
};
AbstractMessageHandlingEndpoint endpoint2 = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer2 = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
return MessageBuilder.fromMessage(message).build();
}
@@ -132,12 +135,12 @@ public class DefaultMessageBusTests {
context.getBeanFactory().registerSingleton("input", inputChannel);
context.getBeanFactory().registerSingleton("output1", outputChannel1);
context.getBeanFactory().registerSingleton("output2", outputChannel2);
endpoint1.setBeanName("testEndpoint1");
endpoint1.setInputChannel(inputChannel);
endpoint1.setOutputChannel(outputChannel1);
endpoint2.setBeanName("testEndpoint2");
endpoint2.setInputChannel(inputChannel);
endpoint2.setOutputChannel(outputChannel2);
consumer1.setOutputChannel(outputChannel1);
consumer2.setOutputChannel(outputChannel2);
PollingConsumerEndpoint endpoint1 = new PollingConsumerEndpoint(consumer1, inputChannel);
endpoint1.afterPropertiesSet();
PollingConsumerEndpoint endpoint2 = new PollingConsumerEndpoint(consumer2, inputChannel);
endpoint2.afterPropertiesSet();
context.getBeanFactory().registerSingleton("testEndpoint1", endpoint1);
context.getBeanFactory().registerSingleton("testEndpoint2", endpoint2);
DefaultMessageBus bus = new DefaultMessageBus();
@@ -157,14 +160,14 @@ public class DefaultMessageBusTests {
QueueChannel outputChannel1 = new QueueChannel();
QueueChannel outputChannel2 = new QueueChannel();
final CountDownLatch latch = new CountDownLatch(2);
AbstractMessageHandlingEndpoint endpoint1 = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer1 = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
Message<?> reply = MessageBuilder.fromMessage(message).build();
latch.countDown();
return reply;
}
};
AbstractMessageHandlingEndpoint endpoint2 = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer2 = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
Message<?> reply = MessageBuilder.fromMessage(message).build();
latch.countDown();
@@ -177,12 +180,10 @@ public class DefaultMessageBusTests {
context.getBeanFactory().registerSingleton("input", inputChannel);
context.getBeanFactory().registerSingleton("output1", outputChannel1);
context.getBeanFactory().registerSingleton("output2", outputChannel2);
endpoint1.setBeanName("testEndpoint1");
endpoint1.setInputChannel(inputChannel);
endpoint1.setOutputChannel(outputChannel1);
endpoint2.setBeanName("testEndpoint2");
endpoint2.setInputChannel(inputChannel);
endpoint2.setOutputChannel(outputChannel2);
consumer1.setOutputChannel(outputChannel1);
consumer2.setOutputChannel(outputChannel2);
SubscribingConsumerEndpoint endpoint1 = new SubscribingConsumerEndpoint(consumer1, inputChannel);
SubscribingConsumerEndpoint endpoint2 = new SubscribingConsumerEndpoint(consumer2, inputChannel);
context.getBeanFactory().registerSingleton("testEndpoint1", endpoint1);
context.getBeanFactory().registerSingleton("testEndpoint2", endpoint2);
DefaultMessageBus bus = new DefaultMessageBus();
@@ -246,14 +247,14 @@ public class DefaultMessageBusTests {
errorChannel.setBeanName(ChannelRegistry.ERROR_CHANNEL_NAME);
context.getBeanFactory().registerSingleton(ChannelRegistry.ERROR_CHANNEL_NAME, errorChannel);
final CountDownLatch latch = new CountDownLatch(1);
AbstractMessageHandlingEndpoint endpoint = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
latch.countDown();
return null;
}
};
endpoint.setBeanName("testEndpoint");
endpoint.setInputChannel(errorChannel);
PollingConsumerEndpoint endpoint = new PollingConsumerEndpoint(consumer, errorChannel);
endpoint.afterPropertiesSet();
context.getBeanFactory().registerSingleton("testEndpoint", endpoint);
DefaultMessageBus bus = new DefaultMessageBus();
bus.setApplicationContext(context);

View File

@@ -31,11 +31,10 @@ import org.springframework.integration.channel.ThreadLocalChannel;
import org.springframework.integration.config.annotation.MessagingAnnotationPostProcessor;
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
import org.springframework.integration.endpoint.ServiceActivatorEndpoint;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageMappingMethodInvoker;
import org.springframework.integration.message.MessagingException;
import org.springframework.integration.message.StringMessage;
import org.springframework.integration.util.MethodInvoker;
/**
* @author Mark Fisher
@@ -61,11 +60,9 @@ public class DirectChannelSubscriptionTests {
@Test
public void testSendAndReceiveForRegisteredEndpoint() {
GenericApplicationContext context = new GenericApplicationContext();
MethodInvoker invoker = new MessageMappingMethodInvoker(new TestBean(), "handle");
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(invoker);
endpoint.setInputChannel(sourceChannel);
endpoint.setOutputChannel(targetChannel);
endpoint.setBeanName("testEndpoint");
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(new TestBean(), "handle");
serviceActivator.setOutputChannel(targetChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(serviceActivator, sourceChannel);
context.getBeanFactory().registerSingleton("testEndpoint", endpoint);
bus.setApplicationContext(context);
bus.start();
@@ -96,14 +93,13 @@ public class DirectChannelSubscriptionTests {
QueueChannel errorChannel = new QueueChannel();
errorChannel.setBeanName(ChannelRegistry.ERROR_CHANNEL_NAME);
bus.registerChannel(errorChannel);
AbstractMessageHandlingEndpoint endpoint = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
throw new RuntimeException("intentional test failure");
}
};
endpoint.setInputChannel(sourceChannel);
endpoint.setOutputChannel(targetChannel);
endpoint.setBeanName("testEndpoint");
consumer.setOutputChannel(targetChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(consumer, sourceChannel);
bus.registerEndpoint(endpoint);
bus.start();
this.sourceChannel.send(new StringMessage("foo"));

View File

@@ -10,9 +10,13 @@
<bean id="targetChannel" class="org.springframework.integration.channel.QueueChannel"/>
<bean id="endpoint" class="org.springframework.integration.endpoint.ServiceActivatorEndpoint">
<bean id="endpoint" class="org.springframework.integration.endpoint.PollingConsumerEndpoint">
<constructor-arg ref="serviceActivator"/>
<constructor-arg ref="sourceChannel"/>
</bean>
<bean id="serviceActivator" class="org.springframework.integration.endpoint.ServiceActivatorEndpoint">
<constructor-arg ref="handler"/>
<property name="inputChannel" ref="sourceChannel"/>
<property name="outputChannel" ref="targetChannel"/>
</bean>

View File

@@ -30,6 +30,7 @@ import org.junit.Test;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.integration.bus.DefaultMessageBus;
import org.springframework.integration.endpoint.AbstractMessageHandlingEndpoint;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.StringMessage;
@@ -46,13 +47,13 @@ public class MessageChannelTemplateTests {
public void setUp() {
this.requestChannel = new QueueChannel();
this.requestChannel.setBeanName("requestChannel");
AbstractMessageHandlingEndpoint endpoint = new AbstractMessageHandlingEndpoint() {
AbstractMessageHandlingEndpoint consumer = new AbstractMessageHandlingEndpoint() {
public Message<?> handle(Message<?> message) {
return new StringMessage(message.getPayload().toString().toUpperCase());
}
};
endpoint.setBeanName("testEndpoint");
endpoint.setInputChannel(requestChannel);
PollingConsumerEndpoint endpoint = new PollingConsumerEndpoint(consumer, requestChannel);
endpoint.afterPropertiesSet();
GenericApplicationContext context = new GenericApplicationContext();
context.getBeanFactory().registerSingleton("requestChannel", requestChannel);
context.getBeanFactory().registerSingleton("testEndpoint", endpoint);

View File

@@ -28,11 +28,11 @@ import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.aggregator.AggregatorEndpoint;
import org.springframework.integration.aggregator.CompletionStrategy;
import org.springframework.integration.aggregator.CompletionStrategyAdapter;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.util.MethodInvoker;
@@ -53,15 +53,14 @@ public class AggregatorParserTests {
@Test
public void testAggregation() {
AggregatorEndpoint endpoint =
(AggregatorEndpoint) context.getBean("aggregatorWithReference");
MessageChannel input = (MessageChannel) context.getBean("aggregatorWithReferenceInput");
TestAggregator aggregatorBean = (TestAggregator) 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) {
endpoint.onMessage(message);
input.send(message);
}
Assert.assertEquals("One and only one message must have been aggregated", 1, aggregatorBean
.getAggregatedMessages().size());
@@ -72,13 +71,14 @@ public class AggregatorParserTests {
@Test
public void testPropertyAssignment() throws Exception {
AggregatorEndpoint endpoint =
(AggregatorEndpoint) context.getBean("completelyDefinedAggregator");
SubscribingConsumerEndpoint endpoint =
(SubscribingConsumerEndpoint) context.getBean("completelyDefinedAggregator");
TestAggregator testAggregator = (TestAggregator) context.getBean("aggregatorBean");
CompletionStrategy completionStrategy = (CompletionStrategy) context.getBean("completionStrategy");
MessageChannel outputChannel = (MessageChannel) context.getBean("outputChannel");
MessageChannel discardChannel = (MessageChannel) context.getBean("discardChannel");
DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint);
DirectFieldAccessor accessor = new DirectFieldAccessor(
new DirectFieldAccessor(endpoint).getPropertyValue("consumer"));
Assert.assertEquals("The AggregatorEndpoint is not injected with the appropriate Aggregator instance",
testAggregator, accessor.getPropertyValue("aggregator"));
Assert.assertEquals(
@@ -105,13 +105,13 @@ public class AggregatorParserTests {
@Test
public void testSimpleJavaBeanAggregator() {
List<Message<?>> outboundMessages = new ArrayList<Message<?>>();
AggregatorEndpoint addingAggregator =
(AggregatorEndpoint) context.getBean("aggregatorWithReferenceAndMethod");
MessageChannel input =
(MessageChannel) context.getBean("aggregatorWithReferenceAndMethodInput");
outboundMessages.add(createMessage(1l, "id1", 3, 1, null));
outboundMessages.add(createMessage(2l, "id1", 3, 3, null));
outboundMessages.add(createMessage(3l, "id1", 3, 2, null));
for (Message<?> message : outboundMessages) {
addingAggregator.onMessage(message);
input.send(message);
}
PollableChannel outputChannel = (PollableChannel) context.getBean("outputChannel");
Message<?> response = outputChannel.receive();
@@ -130,23 +130,24 @@ public class AggregatorParserTests {
}
@Test
public void testAggregatorWithPojoCompletionStrategy(){
AggregatorEndpoint aggregatorWithPojoCompletionStrategy =
(AggregatorEndpoint) context.getBean("aggregatorWithPojoCompletionStrategy");
CompletionStrategy completionStrategy = (CompletionStrategy)
new DirectFieldAccessor(aggregatorWithPojoCompletionStrategy).getPropertyValue("completionStrategy");
public void testAggregatorWithPojoCompletionStrategy() {
MessageChannel input = (MessageChannel) context.getBean("aggregatorWithPojoCompletionStrategyInput");
SubscribingConsumerEndpoint endpoint =
(SubscribingConsumerEndpoint) context.getBean("aggregatorWithPojoCompletionStrategy");
CompletionStrategy completionStrategy = (CompletionStrategy) new DirectFieldAccessor(
new DirectFieldAccessor(endpoint).getPropertyValue("consumer")).getPropertyValue("completionStrategy");
Assert.assertTrue(completionStrategy instanceof CompletionStrategyAdapter);
DirectFieldAccessor completionStrategyAccessor = new DirectFieldAccessor(completionStrategy);
MethodInvoker invoker = (MethodInvoker) completionStrategyAccessor.getPropertyValue("invoker");
Assert.assertTrue(new DirectFieldAccessor(invoker).getPropertyValue("object") instanceof MaxValueCompletionStrategy);
Assert.assertTrue(((Method)completionStrategyAccessor.getPropertyValue("method")).getName().equals("checkCompleteness"));
aggregatorWithPojoCompletionStrategy.onMessage(createMessage(1l, "id1", 0 , 0, null));
aggregatorWithPojoCompletionStrategy.onMessage(createMessage(2l, "id1", 0 , 0, null));
aggregatorWithPojoCompletionStrategy.onMessage(createMessage(3l, "id1", 0 , 0, null));
input.send(createMessage(1l, "id1", 0 , 0, null));
input.send(createMessage(2l, "id1", 0 , 0, null));
input.send(createMessage(3l, "id1", 0 , 0, null));
PollableChannel outputChannel = (PollableChannel) context.getBean("outputChannel");
Message<?> reply = outputChannel.receive(0);
Assert.assertNull(reply);
aggregatorWithPojoCompletionStrategy.onMessage(createMessage(5l, "id1", 0 , 0, null));
input.send(createMessage(5l, "id1", 0 , 0, null));
reply = outputChannel.receive(0);
Assert.assertNotNull(reply);
Assert.assertEquals(11l, reply.getPayload());

View File

@@ -28,7 +28,7 @@ import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.endpoint.SourcePollingChannelAdapter;
import org.springframework.integration.endpoint.OutboundChannelAdapter;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.StringMessage;
import org.springframework.test.context.ContextConfiguration;
@@ -50,7 +50,7 @@ public class ChannelAdapterParserTests extends AbstractJUnit4SpringContextTests
assertNotNull(bus.lookupChannel(beanName));
Object adapter = this.applicationContext.getBean(beanName + ".adapter");
assertNotNull(adapter);
assertTrue(adapter instanceof OutboundChannelAdapter);
assertTrue(adapter instanceof SubscribingConsumerEndpoint);
TestConsumer consumer = (TestConsumer) this.applicationContext.getBean("consumer");
assertNull(consumer.getLastMessage());
Message<?> message = new StringMessage("test");
@@ -70,7 +70,7 @@ public class ChannelAdapterParserTests extends AbstractJUnit4SpringContextTests
assertNotNull(bus.lookupChannel(beanName));
Object adapter = this.applicationContext.getBean(beanName + ".adapter");
assertNotNull(adapter);
assertTrue(adapter instanceof OutboundChannelAdapter);
assertTrue(adapter instanceof SubscribingConsumerEndpoint);
TestBean testBean = (TestBean) this.applicationContext.getBean("testBean");
assertNull(testBean.getMessage());
Message<?> message = new StringMessage("consumer test");

View File

@@ -30,7 +30,6 @@ import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.message.MessageRejectedException;
import org.springframework.integration.message.StringMessage;
@@ -56,11 +55,11 @@ public class EndpointParserTests {
public void testEndpointWithSelectorAccepts() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"endpointWithSelector.xml", this.getClass());
MessageConsumer endpoint = (MessageConsumer) context.getBean("endpoint");
MessageChannel inputChannel = (MessageChannel) context.getBean("testChannel");
QueueChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload("test")
.setReturnAddress(replyChannel).build();
endpoint.onMessage(message);
inputChannel.send(message);
Message<?> reply = replyChannel.receive(500);
assertNotNull(reply);
assertEquals("foo", reply.getPayload());
@@ -70,11 +69,11 @@ public class EndpointParserTests {
public void testEndpointWithSelectorRejects() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"endpointWithSelector.xml", this.getClass());
MessageConsumer endpoint = (MessageConsumer) context.getBean("endpoint");
MessageChannel inputChannel = (MessageChannel) context.getBean("testChannel");
MessageChannel replyChannel = new QueueChannel();
Message<?> message = MessageBuilder.withPayload(123)
.setReturnAddress(replyChannel).build();
endpoint.onMessage(message);
inputChannel.send(message);
}
@Test

View File

@@ -26,9 +26,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.ResequencerEndpoint;
import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageBuilder;
@@ -70,8 +70,8 @@ public class ResequencerParserTests {
@Test
public void testDefaultResequencerProperties() {
ResequencerEndpoint endpoint = (ResequencerEndpoint) context.getBean("defaultResequencer");
DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint);
SubscribingConsumerEndpoint endpoint = (SubscribingConsumerEndpoint) context.getBean("defaultResequencer");
DirectFieldAccessor accessor = new DirectFieldAccessor(new DirectFieldAccessor(endpoint).getPropertyValue("consumer"));
Assert.assertNull(accessor.getPropertyValue("outputChannel"));
Assert.assertNull(accessor.getPropertyValue("discardChannel"));
Assert.assertEquals("The ResequencerEndpoint is not set with the appropriate timeout value",
@@ -92,10 +92,10 @@ public class ResequencerParserTests {
@Test
public void testPropertyAssignment() throws Exception {
ResequencerEndpoint endpoint = (ResequencerEndpoint) context.getBean("completelyDefinedResequencer");
SubscribingConsumerEndpoint endpoint = (SubscribingConsumerEndpoint) context.getBean("completelyDefinedResequencer");
MessageChannel outputChannel = (MessageChannel) context.getBean("outputChannel");
MessageChannel discardChannel = (MessageChannel) context.getBean("discardChannel");
DirectFieldAccessor accessor = new DirectFieldAccessor(endpoint);
DirectFieldAccessor accessor = new DirectFieldAccessor(new DirectFieldAccessor(endpoint).getPropertyValue("consumer"));
Assert.assertEquals("The ResequencerEndpoint is not injected with the appropriate output channel",
outputChannel, accessor.getPropertyValue("outputChannel"));
Assert.assertEquals("The ResequencerEndpoint is not injected with the appropriate discard channel",

View File

@@ -9,7 +9,6 @@
<message-bus/>
<channel id="inputChannel"/>
<channel id="outputChannel">
<queue capacity="5"/>
</channel>
@@ -17,10 +16,12 @@
<queue capacity="5"/>
</channel>
<aggregator id="aggregatorWithReference" ref="aggregatorBean" input-channel="inputChannel"/>
<channel id="aggregatorWithReferenceInput"/>
<aggregator id="aggregatorWithReference" ref="aggregatorBean" input-channel="aggregatorWithReferenceInput"/>
<channel id="completelyDefinedAggregatorInput"/>
<aggregator id="completelyDefinedAggregator"
input-channel="inputChannel"
input-channel="completelyDefinedAggregatorInput"
output-channel="outputChannel"
discard-channel="discardChannel"
ref="aggregatorBean"
@@ -31,14 +32,16 @@
tracked-correlation-id-capacity="99"
timeout="42"/>
<channel id="aggregatorWithReferenceAndMethodInput"/>
<aggregator id="aggregatorWithReferenceAndMethod"
ref="adderBean"
method="add"
input-channel="inputChannel"
input-channel="aggregatorWithReferenceAndMethodInput"
output-channel="outputChannel"/>
<channel id="aggregatorWithPojoCompletionStrategyInput"/>
<aggregator id="aggregatorWithPojoCompletionStrategy"
input-channel="inputChannel"
input-channel="aggregatorWithPojoCompletionStrategyInput"
output-channel="outputChannel"
ref="adderBean"
method="add"

View File

@@ -29,6 +29,7 @@ import org.springframework.integration.aggregator.CompletionStrategyAdapter;
import org.springframework.integration.aggregator.SequenceSizeCompletionStrategy;
import org.springframework.integration.bus.MessageBus;
import org.springframework.integration.config.MessageBusParser;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
/**
* @author Marius Bogoevici
@@ -90,8 +91,9 @@ public class AggregatorAnnotationTests {
@SuppressWarnings("unchecked")
private DirectFieldAccessor getDirectFieldAccessorForAggregatingHandler(ApplicationContext context, final String endpointName) {
AggregatorEndpoint endpoint = (AggregatorEndpoint) context.getBean(endpointName + ".aggregatingMethod.aggregator");
return new DirectFieldAccessor(endpoint);
SubscribingConsumerEndpoint endpoint = (SubscribingConsumerEndpoint) context.getBean(
endpointName + ".aggregatingMethod.aggregator");
return new DirectFieldAccessor(new DirectFieldAccessor(endpoint).getPropertyValue("consumer"));
}
private MessageBus getMessageBus(ApplicationContext context) {

View File

@@ -45,8 +45,7 @@ import org.springframework.integration.channel.MessageChannel;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.MessageBusParser;
import org.springframework.integration.endpoint.ChannelPoller;
import org.springframework.integration.endpoint.ServiceActivatorEndpoint;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.MessageConsumer;
import org.springframework.integration.message.StringMessage;
@@ -329,14 +328,11 @@ public class MessagingAnnotationPostProcessorTests {
MessagingAnnotationPostProcessor postProcessor = new MessagingAnnotationPostProcessor(messageBus);
postProcessor.setBeanFactory(context.getBeanFactory());
postProcessor.afterPropertiesSet();
AnnotatedEndpointWithPolledAnnotation endpoint = new AnnotatedEndpointWithPolledAnnotation();
postProcessor.postProcessAfterInitialization(endpoint, "testBean");
ServiceActivatorEndpoint processedEndpoint =
(ServiceActivatorEndpoint) context.getBean("testBean.prependFoo.serviceActivator");
processedEndpoint.afterPropertiesSet();
DirectFieldAccessor accessor = new DirectFieldAccessor(processedEndpoint);
ChannelPoller poller = (ChannelPoller) accessor.getPropertyValue("poller");
Trigger trigger = (Trigger) new DirectFieldAccessor(poller).getPropertyValue("trigger");
AnnotatedEndpointWithPolledAnnotation bean = new AnnotatedEndpointWithPolledAnnotation();
postProcessor.postProcessAfterInitialization(bean, "testBean");
PollingConsumerEndpoint endpoint =
(PollingConsumerEndpoint) context.getBean("testBean.prependFoo.serviceActivator");
Trigger trigger = (Trigger) new DirectFieldAccessor(endpoint).getPropertyValue("trigger");
assertEquals(IntervalTrigger.class, trigger.getClass());
DirectFieldAccessor triggerAccessor = new DirectFieldAccessor(trigger);
assertEquals(new Long(123000), triggerAccessor.getPropertyValue("interval"));

View File

@@ -9,9 +9,7 @@
<message-bus/>
<channel id="testChannel">
<queue capacity="50"/>
</channel>
<channel id="testChannel"/>
<service-activator id="endpoint" input-channel="testChannel"
ref="testHandler" selector="typeSelector">

View File

@@ -43,9 +43,9 @@ public class CorrelationIdTests {
.setCorrelationId(correlationId).build();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel(1);
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(new TestBean(), "upperCase");
endpoint.setInputChannel(inputChannel);
endpoint.setOutputChannel(outputChannel);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(new TestBean(), "upperCase");
serviceActivator.setOutputChannel(outputChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(serviceActivator, inputChannel);
endpoint.start();
assertTrue(inputChannel.send(message));
Message<?> reply = outputChannel.receive(0);
@@ -57,9 +57,9 @@ public class CorrelationIdTests {
Message<String> message = MessageBuilder.withPayload("test").build();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel(1);
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(new TestBean(), "upperCase");
endpoint.setInputChannel(inputChannel);
endpoint.setOutputChannel(outputChannel);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(new TestBean(), "upperCase");
serviceActivator.setOutputChannel(outputChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(serviceActivator, inputChannel);
endpoint.start();
assertTrue(inputChannel.send(message));
Message<?> reply = outputChannel.receive(0);
@@ -72,9 +72,9 @@ public class CorrelationIdTests {
.setCorrelationId("correlationId").build();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel(1);
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(new TestBean(), "upperCase");
endpoint.setInputChannel(inputChannel);
endpoint.setOutputChannel(outputChannel);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(new TestBean(), "upperCase");
serviceActivator.setOutputChannel(outputChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(serviceActivator, inputChannel);
endpoint.start();
assertTrue(inputChannel.send(message));
Message<?> reply = outputChannel.receive(0);
@@ -89,9 +89,9 @@ public class CorrelationIdTests {
.setCorrelationId(correlationId).build();
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel(1);
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(new TestBean(), "createMessage");
endpoint.setInputChannel(inputChannel);
endpoint.setOutputChannel(outputChannel);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(new TestBean(), "createMessage");
serviceActivator.setOutputChannel(outputChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(serviceActivator, inputChannel);
endpoint.start();
assertTrue(inputChannel.send(message));
Message<?> reply = outputChannel.receive(0);
@@ -103,9 +103,9 @@ public class CorrelationIdTests {
Message<?> message = new StringMessage("test");
DirectChannel inputChannel = new DirectChannel();
QueueChannel outputChannel = new QueueChannel(1);
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(new TestBean(), "createMessage");
endpoint.setInputChannel(inputChannel);
endpoint.setOutputChannel(outputChannel);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(new TestBean(), "createMessage");
serviceActivator.setOutputChannel(outputChannel);
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(serviceActivator, inputChannel);
endpoint.start();
assertTrue(inputChannel.send(message));
Message<?> reply = outputChannel.receive(0);

View File

@@ -33,11 +33,10 @@ public class ServiceActivatorMethodResolutionTests {
@Test
public void singleAnnotationMatches() {
SingleAnnotationTestBean testBean = new SingleAnnotationTestBean();
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(testBean);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(testBean);
QueueChannel outputChannel = new QueueChannel();
endpoint.setOutputChannel(outputChannel);
endpoint.afterPropertiesSet();
endpoint.onMessage(new StringMessage("foo"));
serviceActivator.setOutputChannel(outputChannel);
serviceActivator.onMessage(new StringMessage("foo"));
Message<?> result = outputChannel.receive(0);
assertEquals("FOO", result.getPayload());
}
@@ -51,11 +50,10 @@ public class ServiceActivatorMethodResolutionTests {
@Test
public void singlePublicMethodMatches() {
SinglePublicMethodTestBean testBean = new SinglePublicMethodTestBean();
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(testBean);
ServiceActivatorEndpoint serviceActivator = new ServiceActivatorEndpoint(testBean);
QueueChannel outputChannel = new QueueChannel();
endpoint.setOutputChannel(outputChannel);
endpoint.afterPropertiesSet();
endpoint.onMessage(new StringMessage("foo"));
serviceActivator.setOutputChannel(outputChannel);
serviceActivator.onMessage(new StringMessage("foo"));
Message<?> result = outputChannel.receive(0);
assertEquals("FOO", result.getPayload());
}

View File

@@ -25,6 +25,7 @@ import org.junit.Test;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.SubscribingConsumerEndpoint;
import org.springframework.integration.filter.FilterEndpoint;
import org.springframework.integration.message.Message;
import org.springframework.integration.message.StringMessage;
@@ -65,9 +66,9 @@ public class FilterEndpointTests {
return true;
}
});
filter.setInputChannel(inputChannel);
filter.setOutputChannel(outputChannel);
filter.start();
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(filter, inputChannel);
endpoint.start();
Message<?> message = new StringMessage("test");
assertTrue(inputChannel.send(message));
Message<?> reply = outputChannel.receive(0);
@@ -84,9 +85,9 @@ public class FilterEndpointTests {
return false;
}
});
filter.setInputChannel(inputChannel);
filter.setOutputChannel(outputChannel);
filter.start();
SubscribingConsumerEndpoint endpoint = new SubscribingConsumerEndpoint(filter, inputChannel);
endpoint.start();
Message<?> message = new StringMessage("test");
assertTrue(inputChannel.send(message));
assertNull(outputChannel.receive(0));

View File

@@ -29,6 +29,7 @@ import org.junit.Test;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.integration.bus.DefaultMessageBus;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.endpoint.PollingConsumerEndpoint;
import org.springframework.integration.endpoint.ServiceActivatorEndpoint;
/**
@@ -82,9 +83,8 @@ public class MethodInvokingConsumerTests {
Message<String> message = new GenericMessage<String>("testing");
channel.send(message);
assertNull(queue.poll());
ServiceActivatorEndpoint endpoint = new ServiceActivatorEndpoint(consumer);
endpoint.setBeanName("testEndpoint");
endpoint.setInputChannel(channel);
ServiceActivatorEndpoint serivceActivator = new ServiceActivatorEndpoint(consumer);
PollingConsumerEndpoint endpoint = new PollingConsumerEndpoint(serivceActivator, channel);
context.getBeanFactory().registerSingleton("testEndpoint", endpoint);
DefaultMessageBus bus = new DefaultMessageBus();
bus.setApplicationContext(context);

View File

@@ -14,12 +14,15 @@
<channel id="inMethodInvoking" />
<channel id="out" />
<splitter ref="splitterBean" input-channel="inMethodInvoking"
<splitter ref="splitterBeanXmlConfig" input-channel="inMethodInvoking"
method="split" output-channel="out" />
<splitter input-channel="inDefault" output-channel="out" />
<beans:bean id="splitterBean"
<beans:bean id="splitterBeanXmlConfig"
class="org.springframework.integration.splitter.SplitterIntegrationTests$TestSplitter" />
<beans:bean id="splitterBeanAnnotationConfig"
class="org.springframework.integration.splitter.SplitterIntegrationTests$TestSplitter" />
<beans:bean