BATCHADM-58: first cut with all features and SI 2.0

This commit is contained in:
David Syer
2010-08-11 12:46:40 +00:00
committed by Michael Minella
parent 19b8263623
commit bced2c5595
20 changed files with 159 additions and 123 deletions

View File

@@ -10,7 +10,7 @@
<maven.test.failure.ignore>true</maven.test.failure.ignore>
<spring.batch.version>2.1.1.RELEASE</spring.batch.version>
<spring.framework.version>3.0.3.RELEASE</spring.framework.version>
<spring.integration.version>1.0.3.RELEASE</spring.integration.version>
<spring.integration.version>2.0.0.BUILD-SNAPSHOT</spring.integration.version>
</properties>
<profiles>
<profile>

View File

@@ -1,10 +1,10 @@
#Fri May 14 17:06:42 BST 2010
#Fri Jul 30 14:07:10 BST 2010
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/chunk/ChunkStepIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1102" endstart\="1096" start\="901" startend\="967"/>\n<bounds height\="118" width\="79" x\="15" y\="17"/>\n</element>\n<element type\="job">\n<structure end\="1473" endstart\="1467" start\="1107" startend\="1182"/>\n<bounds height\="118" width\="127" x\="106" y\="17"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/chunk/RemoteChunkFaultTolerantStepIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1667" endstart\="1661" start\="1306" startend\="1372"/>\n<bounds height\="118" width\="79" x\="15" y\="17"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/chunk/RemoteChunkFaultTolerantStepJmsIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<graph>\r\n<element type\="job">\r\n<structure end\="1767" endstart\="1761" start\="1416" startend\="1482"/>\r\n<bounds height\="118" width\="75" x\="15" y\="17"/>\r\n</element>\r\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/chunk/RemoteChunkStepIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1269" endstart\="1263" start\="1067" startend\="1133"/>\n<bounds height\="118" width\="79" x\="15" y\="17"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/chunk/RemoteChunkFaultTolerantStepJmsIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1767" endstart\="1761" start\="1416" startend\="1482"/>\n<bounds height\="118" width\="79" x\="15" y\="17"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/chunk/RemoteChunkStepIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1267" endstart\="1261" start\="1065" startend\="1131"/>\n<bounds height\="118" width\="79" x\="15" y\="17"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/file/FileToMessagesJobIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\r\n<graph>\r\n<element type\="job">\r\n<structure end\="972" endstart\="966" start\="771" startend\="837"/>\r\n<bounds height\="118" width\="75" x\="15" y\="17"/>\r\n</element>\r\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/partition/VanillaIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="2969" endstart\="2963" start\="2774" startend\="2841"/>\n<bounds height\="128" width\="131" x\="100" y\="19"/>\n</element>\n<element type\="step">\n<structure end\="3575" endstart\="3568" start\="3075" startend\="3144"/>\n<bounds height\="34" width\="65" x\="17" y\="19"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/partition/VanillaIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="2963" endstart\="2957" start\="2768" startend\="2835"/>\n<bounds height\="128" width\="131" x\="100" y\="19"/>\n</element>\n<element type\="step">\n<structure end\="3569" endstart\="3562" start\="3069" startend\="3138"/>\n<bounds height\="34" width\="65" x\="17" y\="19"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/step/StepGatewayIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1419" endstart\="1413" start\="1302" startend\="1368"/>\n<bounds height\="128" width\="79" x\="109" y\="19"/>\n</element>\n<element type\="step">\n<structure end\="1953" endstart\="1946" start\="1846" startend\="1916"/>\n<bounds height\="34" width\="74" x\="17" y\="19"/>\n</element>\n</graph>
//com.springsource.sts.config.flow.coordinates\:http\://www.springframework.org/schema/batch\:/spring-batch-integration/src/test/resources/org/springframework/batch/integration/tasklet/StepGatewayIntegrationTests-context.xml=<?xml version\="1.0" encoding\="UTF-8"?>\n<graph>\n<element type\="job">\n<structure end\="1421" endstart\="1415" start\="1302" startend\="1368"/>\n<bounds height\="128" width\="79" x\="109" y\="19"/>\n</element>\n<element type\="step">\n<structure end\="1962" endstart\="1955" start\="1855" startend\="1925"/>\n<bounds height\="34" width\="74" x\="17" y\="19"/>\n</element>\n</graph>
eclipse.preferences.version=1

View File

@@ -75,12 +75,6 @@
<version>${spring.integration.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-adapter</artifactId>
<version>${spring.integration.version}</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>

View File

@@ -34,7 +34,10 @@ import org.springframework.batch.item.ExecutionContext;
import org.springframework.batch.item.ItemStream;
import org.springframework.batch.item.ItemStreamException;
import org.springframework.batch.item.ItemWriter;
import org.springframework.integration.gateway.MessagingGateway;
import org.springframework.integration.Message;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessagingOperations;
import org.springframework.integration.core.PollableChannel;
import org.springframework.util.Assert;
public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSupport implements ItemWriter<T>,
@@ -48,7 +51,7 @@ public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSuppo
private static final long DEFAULT_THROTTLE_LIMIT = 6;
private MessagingGateway messagingGateway;
private MessagingOperations messagingGateway;
private LocalState localState = new LocalState();
@@ -58,6 +61,8 @@ public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSuppo
private int maxWaitTimeouts = DEFAULT_MAX_WAIT_TIMEOUTS;
private PollableChannel replyChannel;
/**
* The maximum number of times to wait at the end of a step for a non-null result from the remote workers. This is a
* multiplier on the receive timeout set separately on the gateway. The ideal value is a compromise between allowing
@@ -78,10 +83,14 @@ public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSuppo
this.throttleLimit = throttleLimit;
}
public void setMessagingGateway(MessagingGateway messagingGateway) {
public void setMessagingOperations(MessagingOperations messagingGateway) {
this.messagingGateway = messagingGateway;
}
public void setReplyChannel(PollableChannel replyChannel) {
this.replyChannel = replyChannel;
}
public void write(List<? extends T> items) throws Exception {
// Block until expecting <= throttle limit
@@ -94,7 +103,7 @@ public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSuppo
logger.debug("Dispatching chunk: " + items);
ChunkRequest<T> request = new ChunkRequest<T>(items, localState.getJobId(), localState
.createStepContribution());
messagingGateway.send(request);
messagingGateway.send(new GenericMessage<ChunkRequest<T>>(request));
localState.incrementExpected();
}
@@ -192,8 +201,9 @@ public class ChunkMessageChannelItemWriter<T> extends StepExecutionListenerSuppo
* and we shouldn't be)
*/
private void getNextResult() throws AsynchronousFailureException {
ChunkResponse payload = (ChunkResponse) messagingGateway.receive();
if (payload != null) {
Message<ChunkResponse> message = messagingGateway.receive(replyChannel);
if (message != null) {
ChunkResponse payload = message.getPayload();
if (logger.isDebugEnabled()) {
logger.debug("Found result: " + payload);
}

View File

@@ -18,6 +18,7 @@ package org.springframework.batch.integration.chunk;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.annotation.Header;
import org.springframework.integration.jms.JmsHeaders;
/**
* @author Dave Syer
@@ -27,7 +28,7 @@ public class JmsRedeliveredExtractor {
private static final Log logger = LogFactory.getLog(JmsRedeliveredExtractor.class);
public ChunkResponse extract(ChunkResponse input, @Header("springintegration_jms_redelivered") boolean redelivered) {
public ChunkResponse extract(ChunkResponse input, @Header(JmsHeaders.REDELIVERED) boolean redelivered) {
logger.debug("Extracted redelivered flag for response, value="+redelivered);
return new ChunkResponse(input, redelivered);
}

View File

@@ -3,13 +3,14 @@ package org.springframework.batch.integration.chunk;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.integration.Message;
import org.springframework.integration.channel.ChannelInterceptor;
import org.springframework.integration.channel.interceptor.ChannelInterceptorAdapter;
import org.springframework.integration.core.Message;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.message.MessageSource;
import org.springframework.integration.core.MessageSource;
import org.springframework.util.Assert;
/**
* A {@link ChannelInterceptor} that turns a pollable channel into a "pass-thru channel": if a client calls
* <code>receive()</code> on the channel it will delegate to a {@link MessageSource} to pull the message directly from

View File

@@ -9,12 +9,13 @@ import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.partition.PartitionHandler;
import org.springframework.batch.core.partition.StepExecutionSplitter;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.integration.Message;
import org.springframework.integration.annotation.Aggregator;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.core.Message;
import org.springframework.integration.core.MessageBuilder;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.gateway.MessagingGateway;
import org.springframework.integration.message.MessageBuilder;
import org.springframework.integration.core.MessagingOperations;
import org.springframework.integration.core.PollableChannel;
import org.springframework.util.Assert;
/**
@@ -38,13 +39,15 @@ public class MessageChannelPartitionHandler implements PartitionHandler {
private int gridSize = 1;
private MessagingGateway messagingGateway;
private MessagingOperations messagingGateway;
private String stepName;
private PollableChannel replyChannel;
public void afterPropertiesSet() throws Exception {
Assert.notNull(stepName, "A step name must be provided for the remote workers.");
Assert.state(messagingGateway != null, "The MessagingGateway must be set");
Assert.state(messagingGateway != null, "The MessagingOperations must be set");
}
/**
@@ -60,12 +63,16 @@ public class MessageChannelPartitionHandler implements PartitionHandler {
* The timeout for the repoy should be set sufficiently long that the remote
* steps have time to complete.
*
* @param messagingGateway the {@link MessagingGateway} to set
* @param messagingGateway the {@link MessagingOperations} to set
*/
public void setMessagingGateway(MessagingGateway messagingGateway) {
public void setMessagingOperations(MessagingOperations messagingGateway) {
this.messagingGateway = messagingGateway;
}
public void setReplyChannel(PollableChannel replyChannel) {
this.replyChannel = replyChannel;
}
/**
* Passed to the {@link StepExecutionSplitter} in the
* {@link #handle(StepExecutionSplitter, StepExecution)} method, instructing
@@ -97,18 +104,18 @@ public class MessageChannelPartitionHandler implements PartitionHandler {
* @param messages the messages to be aggregated
* @return the list as it was passed in
*/
@Aggregator(sendPartialResultsOnTimeout = true)
@Aggregator(sendPartialResultsOnExpiry = true)
public List<?> aggregate(List<?> messages) {
return messages;
}
/**
* Sends {@link StepExecutionRequest} objects to the request channel of the
* {@link MessagingGateway}, and then receives the result back as a list of
* {@link MessagingOperations}, and then receives the result back as a list of
* {@link StepExecution} on a reply channel. Use the
* {@link #aggregate(List)} method as an aggregator of the individual remote
* replies. The receive timeout needs to be set realistically in the
* {@link MessagingGateway} <b>and</b> the aggregator, so that there is a
* {@link MessagingOperations} <b>and</b> the aggregator, so that there is a
* good chance of all work being done.
*
* @see PartitionHandler#handle(StepExecutionSplitter, StepExecution)
@@ -123,8 +130,8 @@ public class MessageChannelPartitionHandler implements PartitionHandler {
.getJobExecutionId(), stepExecution.getId())));
}
@SuppressWarnings("unchecked")
Collection<StepExecution> result = (Collection<StepExecution>) messagingGateway.receive();
Message<Collection<StepExecution>> message = messagingGateway.receive(replyChannel);
Collection<StepExecution> result = message.getPayload();
return result;
}

View File

@@ -6,13 +6,12 @@ import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.core.Message;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.core.PollableChannel;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -22,14 +21,12 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
public class SmokeTests {
@Autowired
@Qualifier("smokein")
private MessageChannel smokein;
@Autowired
@Qualifier("smokeout")
private PollableChannel smokeout;
// This has to be static because the MessageBus registers the handler
// This has to be static because Spring Integration registers the handler
// more than once (every time a test instance is created), but only one of
// them will get the message.
private volatile static int count = 0;

View File

@@ -33,11 +33,11 @@ import org.springframework.batch.item.support.ListItemReader;
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.core.Message;
import org.springframework.integration.Message;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.gateway.SimpleMessagingGateway;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.core.PollableChannel;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.StringUtils;
@@ -73,12 +73,12 @@ public class ChunkMessageItemWriterIntegrationTests {
factory.setItemWriter(writer);
factory.setCommitInterval(4);
SimpleMessagingGateway gateway = new SimpleMessagingGateway();
writer.setMessagingGateway(gateway);
MessagingTemplate gateway = new MessagingTemplate();
writer.setMessagingOperations(gateway);
gateway.setRequestChannel(requests);
gateway.setReplyChannel(replies);
gateway.setReplyTimeout(100);
gateway.setDefaultChannel(requests);
writer.setReplyChannel(replies);
gateway.setReceiveTimeout(100);
TestItemWriter.count = 0;

View File

@@ -4,10 +4,10 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.springframework.integration.Message;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.message.MessageSource;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessageSource;
public class MessageSourcePollerInterceptorTests {

View File

@@ -2,8 +2,10 @@ package org.springframework.batch.integration.chunk;
import static org.junit.Assert.assertEquals;
import java.io.File;
import java.util.Collections;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.batch.core.BatchStatus;
@@ -17,10 +19,16 @@ import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.FileSystemUtils;
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class RemoteChunkFaultTolerantStepJmsIntegrationTests {
@BeforeClass
public static void clear() {
FileSystemUtils.deleteRecursively(new File("activemq-data"));
}
@Autowired
private JobLauncher jobLauncher;

View File

@@ -27,12 +27,9 @@ import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.channel.SubscribableChannel;
import org.springframework.integration.core.Message;
import org.springframework.integration.message.MessageDeliveryException;
import org.springframework.integration.message.MessageHandler;
import org.springframework.integration.message.MessageHandlingException;
import org.springframework.integration.message.MessageRejectedException;
import org.springframework.integration.Message;
import org.springframework.integration.core.MessageHandler;
import org.springframework.integration.core.SubscribableChannel;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -56,8 +53,7 @@ public class FileToMessagesJobIntegrationTests implements MessageHandler {
int count = 0;
public void handleMessage(Message<?> message) throws MessageRejectedException, MessageHandlingException,
MessageDeliveryException {
public void handleMessage(Message<?> message) {
count++;
}

View File

@@ -25,12 +25,12 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.io.Resource;
import org.springframework.integration.Message;
import org.springframework.integration.annotation.MessageEndpoint;
import org.springframework.integration.annotation.Splitter;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.core.Message;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.core.PollableChannel;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

View File

@@ -16,12 +16,12 @@ import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.integration.JobSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.channel.PollableChannel;
import org.springframework.integration.core.Message;
import org.springframework.integration.Message;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.MessagingException;
import org.springframework.integration.core.GenericMessage;
import org.springframework.integration.core.MessageChannel;
import org.springframework.integration.core.MessageHeaders;
import org.springframework.integration.core.MessagingException;
import org.springframework.integration.message.GenericMessage;
import org.springframework.integration.core.PollableChannel;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

View File

@@ -5,7 +5,7 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx

View File

@@ -5,8 +5,8 @@
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-1.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
@@ -42,18 +42,28 @@
<bean id="writer" class="org.springframework.batch.integration.chunk.TestItemWriter" />
<bean id="chunkWriter" class="org.springframework.batch.integration.chunk.ChunkMessageChannelItemWriter" scope="step">
<property name="messagingGateway" ref="messagingGateway" />
<property name="messagingOperations" ref="messagingGateway" />
<property name="replyChannel" ref="replies" />
</bean>
<bean id="messagingGateway" class="org.springframework.integration.gateway.SimpleMessagingGateway">
<property name="requestChannel" ref="requests" />
<property name="replyChannel" ref="replies" />
<property name="replyTimeout" value="1000" />
<bean id="messagingGateway" class="org.springframework.integration.core.MessagingTemplate">
<property name="defaultChannel" ref="requests" />
<property name="receiveTimeout" value="1000" />
</bean>
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope" />
</entry>
</map>
</property>
</bean>
<integration:channel id="requests" />
<!-- If we use a direct channel for requests then the replies can come in on a thread-local -->
<integration:thread-local-channel id="replies"/>
<integration:channel id="replies" scope="thread"><integration:queue/></integration:channel>
<integration:service-activator input-channel="requests" output-channel="replies" ref="chunkHandler" />
<bean id="chunkHandler" class="org.springframework.batch.integration.chunk.RemoteChunkHandlerFactoryBean">

View File

@@ -5,8 +5,8 @@
xmlns:jms="http://www.springframework.org/schema/jms" xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/jms http://www.springframework.org/schema/jms/spring-jms-3.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-1.0.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/integration/jms http://www.springframework.org/schema/integration/jms/spring-integration-jms-2.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
@@ -44,25 +44,38 @@
<bean id="writer" class="org.springframework.batch.integration.chunk.TestItemWriter" />
<bean id="chunkWriter" class="org.springframework.batch.integration.chunk.ChunkMessageChannelItemWriter" scope="step">
<property name="messagingGateway" ref="messagingGateway" />
<property name="messagingOperations" ref="messagingGateway" />
<property name="replyChannel" ref="replies" />
</bean>
<bean id="messagingGateway" class="org.springframework.integration.gateway.SimpleMessagingGateway">
<property name="requestChannel" ref="requests" />
<property name="replyChannel" ref="replies" />
<property name="replyTimeout" value="1000" />
<bean id="messagingGateway" class="org.springframework.integration.core.MessagingTemplate">
<property name="defaultChannel" ref="requests" />
<property name="receiveTimeout" value="1000" />
</bean>
<int-jms:outbound-channel-adapter connection-factory="connectionFactory" channel="requests"
destination-name="requests" />
<integration:channel id="requests" />
<integration:channel id="incoming" />
<integration:transformer input-channel="incoming" output-channel="replies" ref="headerExtractor" method="extract"/>
<bean id="headerExtractor" class="org.springframework.batch.integration.chunk.JmsRedeliveredExtractor"/>
<integration:thread-local-channel id="replies">
<integration:transformer input-channel="incoming" output-channel="replies" ref="headerExtractor"
method="extract" />
<bean id="headerExtractor" class="org.springframework.batch.integration.chunk.JmsRedeliveredExtractor" />
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<bean class="org.springframework.context.support.SimpleThreadScope" />
</entry>
</map>
</property>
</bean>
<!-- If we use a direct channel for requests then the replies can come in on a thread-local -->
<integration:channel id="replies" scope="thread">
<integration:queue />
<integration:interceptors>
<bean id="pollerInterceptor" class="org.springframework.batch.integration.chunk.MessageSourcePollerInterceptor">
<property name="messageSource">
@@ -76,29 +89,29 @@
</constructor-arg>
</bean>
</property>
<property name="channel" ref="incoming"/>
<property name="channel" ref="incoming" />
</bean>
</integration:interceptors>
</integration:thread-local-channel>
</integration:channel>
<jms:listener-container connection-factory="connectionFactory" transaction-manager="transactionManager"
acknowledge="transacted">
<jms:listener destination="requests" response-destination="replies" ref="chunkHandler" method="handleChunk" />
</jms:listener-container>
<jms:listener-container connection-factory="connectionFactory" transaction-manager="transactionManager"
acknowledge="transacted">
<jms:listener destination="requests" response-destination="replies" ref="chunkHandler" method="handleChunk" />
</jms:listener-container>
<bean id="chunkHandler" class="org.springframework.batch.integration.chunk.RemoteChunkHandlerFactoryBean">
<property name="chunkWriter" ref="chunkWriter" />
<property name="step" ref="step" />
</bean>
<bean id="chunkHandler" class="org.springframework.batch.integration.chunk.RemoteChunkHandlerFactoryBean">
<property name="chunkWriter" ref="chunkWriter" />
<property name="step" ref="step" />
</bean>
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean">
<property name="transactionManager" ref="transactionManager" />
</bean>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
<property name="jobRepository" ref="jobRepository" />
</bean>
</beans>

View File

@@ -1,10 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:integration="http://www.springframework.org/schema/integration"
xmlns:beans="http://www.springframework.org/schema/beans" xmlns:integration="http://www.springframework.org/schema/integration"
xmlns:batch="http://www.springframework.org/schema/batch" xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
xsi:schemaLocation="http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
@@ -37,19 +36,19 @@
<bean id="writer" class="org.springframework.batch.integration.chunk.TestItemWriter" />
<bean id="chunkWriter" class="org.springframework.batch.integration.chunk.ChunkMessageChannelItemWriter" scope="step">
<property name="messagingGateway" ref="messagingGateway" />
</bean>
<bean id="messagingGateway" class="org.springframework.integration.gateway.SimpleMessagingGateway">
<property name="requestChannel" ref="requests" />
<property name="messagingOperations" ref="messagingGateway" />
<property name="replyChannel" ref="replies" />
<property name="replyTimeout" value="1000" />
</bean>
<task:executor id="poolExecutor" pool-size="5-10" queue-capacity="0"/>
<bean id="messagingGateway" class="org.springframework.integration.core.MessagingTemplate">
<property name="defaultChannel" ref="requests" />
<property name="receiveTimeout" value="1000" />
</bean>
<!-- A pub-sub channel with task executor is a decent approximation to a JMS outbound adapter -->
<integration:publish-subscribe-channel id="requests" task-executor="poolExecutor"/>
<task:executor id="poolExecutor" pool-size="5-10" queue-capacity="0" />
<!-- A pub-sub channel with task executor is a decent approximation to a JMS outbound adapter -->
<integration:publish-subscribe-channel id="requests" task-executor="poolExecutor" />
<integration:channel id="replies">
<integration:queue />
</integration:channel>

View File

@@ -9,7 +9,7 @@
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd
http://www.springframework.org/schema/integration/spring-integration-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<integration:annotation-config/>
<integration:channel id="resources" />

View File

@@ -43,13 +43,13 @@
</bean>
<bean id="partitionHandler" class="org.springframework.batch.integration.partition.MessageChannelPartitionHandler">
<property name="messagingGateway">
<bean class="org.springframework.integration.gateway.SimpleMessagingGateway">
<property name="requestChannel" ref="requests" />
<property name="replyChannel" ref="replies" />
<property name="replyTimeout" value="10000" />
<property name="messagingOperations">
<bean class="org.springframework.integration.core.MessagingTemplate">
<property name="defaultChannel" ref="requests" />
<property name="receiveTimeout" value="10000" />
</bean>
</property>
<property name="replyChannel" ref="replies"/>
<property name="stepName" value="step1" />
<property name="gridSize" value="2" />
</bean>