INT-1500: add apply-sequence flag to splitter.

This commit is contained in:
Iwein Fuld
2010-10-17 20:00:08 +02:00
parent 466b3b4cd6
commit d0a00c68fd
6 changed files with 65 additions and 8 deletions

View File

@@ -29,6 +29,7 @@ import org.springframework.util.StringUtils;
* Factory bean for creating a Message Splitter.
*
* @author Mark Fisher
* @author Iwein Fuld
*/
public class SplitterFactoryBean extends AbstractMessageHandlerFactoryBean {
@@ -36,6 +37,8 @@ public class SplitterFactoryBean extends AbstractMessageHandlerFactoryBean {
private volatile boolean requiresReply;
private volatile boolean applySequence = true;
public void setSendTimeout(Long sendTimeout) {
this.sendTimeout = sendTimeout;
@@ -49,6 +52,10 @@ public class SplitterFactoryBean extends AbstractMessageHandlerFactoryBean {
this.requiresReply = requiresReply;
}
public void setApplySequence(boolean applySequence) {
this.applySequence = applySequence;
}
@Override
MessageHandler createMethodInvokingHandler(Object targetObject, String targetMethodName) {
Assert.notNull(targetObject, "targetObject must not be null");
@@ -89,6 +96,7 @@ public class SplitterFactoryBean extends AbstractMessageHandlerFactoryBean {
splitter.setSendTimeout(sendTimeout);
}
splitter.setRequiresReply(requiresReply);
splitter.setApplySequence(applySequence);
return splitter;
}

View File

@@ -16,10 +16,15 @@
package org.springframework.integration.config.xml;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
/**
* Parser for the <splitter/> element.
*
* @author Mark Fisher
* @author Iwein Fuld
*/
public class SplitterParser extends AbstractDelegatingConsumerEndpointParser {
@@ -33,4 +38,8 @@ public class SplitterParser extends AbstractDelegatingConsumerEndpointParser {
return true;
}
@Override
void postProcess(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
IntegrationNamespaceUtils.setValueIfAttributeDefined(builder, element, "apply-sequence");
}
}

View File

@@ -35,6 +35,15 @@ import org.springframework.util.ObjectUtils;
*/
public abstract class AbstractMessageSplitter extends AbstractReplyProducingMessageHandler {
private boolean applySequence = true;
/**
* Set the applySequence flag to the specified value. Defaults to true.
*/
public void setApplySequence(boolean applySequence) {
this.applySequence = applySequence;
}
@Override
@SuppressWarnings("unchecked")
protected final Object handleRequestMessage(Message<?> message) {
@@ -80,7 +89,9 @@ public abstract class AbstractMessageSplitter extends AbstractReplyProducingMess
builder = MessageBuilder.withPayload(item);
builder.copyHeaders(headers);
}
builder.pushSequenceDetails(correlationId, sequenceNumber, sequenceSize);
if (this.applySequence) {
builder.pushSequenceDetails(correlationId, sequenceNumber, sequenceSize);
}
return builder;
}

View File

@@ -2118,6 +2118,15 @@ Name of the header whose value to use.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="apply-sequence" type="xsd:boolean" use="optional">
<xsd:annotation>
<xsd:documentation>
Set this flag to false to prevent adding sequence related headers in this splitter. This
can be convenient in cases where the set sequence numbers conflict with downstream custom
aggregations.
</xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:extension>
</xsd:complexContent>
</xsd:complexType>

View File

@@ -16,25 +16,24 @@
package org.springframework.integration.router.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import java.util.Collections;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.Message;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageHandlingException;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.core.PollableChannel;
import org.springframework.integration.endpoint.EventDrivenConsumer;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.support.MessageBuilder;
import java.util.Collections;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;
/**
* @author Mark Fisher
* @author Iwein Fuld
*/
public class SplitterParserTests {
@@ -104,4 +103,18 @@ public class SplitterParserTests {
inputChannel.send(MessageBuilder.withPayload(Collections.emptyList()).build());
}
@Test
public void splitterParserTestApplySequenceFalse() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
"splitterParserTests.xml", this.getClass());
context.start();
DirectChannel inputChannel = context.getBean("noSequenceInput", DirectChannel.class);
PollableChannel output = (PollableChannel) context.getBean("output");
inputChannel.send(MessageBuilder.withPayload(Collections.emptyList()).build());
Message<?> message = output.receive(1000);
assertThat(message.getHeaders().getSequenceNumber(), is(0));
assertThat(message.getHeaders().getSequenceSize(), is(0));
}
}

View File

@@ -32,6 +32,13 @@
output-channel="output"
requires-reply="true"/>
<splitter id="splitterBeanNoSequence"
ref="splitterBean"
input-channel="noSequenceInput"
output-channel="output"
apply-sequence="false"
/>
<beans:bean id="splitterBean" class="org.springframework.integration.router.config.TestSplitterBean"/>
<beans:bean id="splitterImpl" class="org.springframework.integration.router.config.TestSplitterImpl"/>