BATCH-2095: Change JSR version of Split to execute flows in separate threads.
This commit is contained in:
@@ -18,10 +18,14 @@ package org.springframework.batch.core.jsr.configuration.xml;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.beans.factory.support.ManagedList;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
@@ -29,9 +33,12 @@ import org.w3c.dom.Element;
|
||||
* Parses a <split /> element as defined in JSR-352.
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @author Chris Schaefer
|
||||
* @since 3.0
|
||||
*/
|
||||
public class SplitParser {
|
||||
private static final String TASK_EXECUTOR_PROPERTY_NAME = "taskExecutor";
|
||||
private static final String JSR_352_SPLIT_TASK_EXECUTOR_BEAN_NAME = "jsr352splitTaskExecutor";
|
||||
|
||||
private String jobFactoryRef;
|
||||
|
||||
@@ -63,6 +70,25 @@ public class SplitParser {
|
||||
stateBuilder.addConstructorArgValue(flows);
|
||||
stateBuilder.addConstructorArgValue(idAttribute);
|
||||
|
||||
PropertyValue propertyValue = getSplitTaskExecutorPropertyValue(parserContext.getRegistry());
|
||||
stateBuilder.addPropertyValue(propertyValue.getName(), propertyValue.getValue());
|
||||
|
||||
return FlowParser.getNextElements(parserContext, null, stateBuilder.getBeanDefinition(), element);
|
||||
}
|
||||
|
||||
protected PropertyValue getSplitTaskExecutorPropertyValue(BeanDefinitionRegistry beanDefinitionRegistry) {
|
||||
PropertyValue propertyValue;
|
||||
|
||||
if (hasBeanDefinition(beanDefinitionRegistry, JSR_352_SPLIT_TASK_EXECUTOR_BEAN_NAME)) {
|
||||
propertyValue = new PropertyValue(TASK_EXECUTOR_PROPERTY_NAME, new RuntimeBeanReference(JSR_352_SPLIT_TASK_EXECUTOR_BEAN_NAME));
|
||||
} else {
|
||||
propertyValue = new PropertyValue(TASK_EXECUTOR_PROPERTY_NAME, new SimpleAsyncTaskExecutor());
|
||||
}
|
||||
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
private boolean hasBeanDefinition(BeanDefinitionRegistry beanDefinitionRegistry, String beanName) {
|
||||
return beanDefinitionRegistry.containsBeanDefinition(beanName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
@@ -29,16 +29,19 @@ import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.parsing.BeanDefinitionParsingException;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
import org.springframework.core.task.SimpleAsyncTaskExecutor;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
@ContextConfiguration({"SplitParsingTests-context.xml", "jsr-base-context.xml"})
|
||||
@ContextConfiguration()
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SplitParsingTests {
|
||||
|
||||
@Autowired
|
||||
public Job job;
|
||||
|
||||
@@ -49,7 +52,6 @@ public class SplitParsingTests {
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void test() throws Exception {
|
||||
JobExecution execution = jobLauncher.run(job, new JobParameters());
|
||||
assertEquals(BatchStatus.COMPLETED, execution.getStatus());
|
||||
@@ -57,15 +59,33 @@ public class SplitParsingTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testOneFlowInSplit() {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/invalid-split-context.xml");
|
||||
} catch (BeanDefinitionParsingException bdpe) {
|
||||
assertTrue(bdpe.getMessage().indexOf("A <split/> must contain at least two 'flow' elements.") >= 0);
|
||||
assertTrue(bdpe.getMessage().contains("A <split/> must contain at least two 'flow' elements."));
|
||||
return;
|
||||
}
|
||||
|
||||
fail("Expected exception was not thrown");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUserSpecifiedTaskExecutor() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/user-specified-split-task-executor-context.xml");
|
||||
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) context.getBeanFactory();
|
||||
PropertyValue propertyValue = new SplitParser(null).getSplitTaskExecutorPropertyValue(registry);
|
||||
|
||||
RuntimeBeanReference runtimeBeanReferenceValue = (RuntimeBeanReference) propertyValue.getValue();
|
||||
|
||||
Assert.assertTrue("RuntimeBeanReference should have a name of jsr352splitTaskExecutor" , "jsr352splitTaskExecutor".equals(runtimeBeanReferenceValue.getBeanName()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultTaskExecutor() {
|
||||
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/org/springframework/batch/core/jsr/configuration/xml/default-split-task-executor-context.xml");
|
||||
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) context.getBeanFactory();
|
||||
PropertyValue propertyValue = new SplitParser(null).getSplitTaskExecutorPropertyValue(registry);
|
||||
Assert.assertTrue("Task executor not an instance of SimpleAsyncTaskExecutor" , (propertyValue.getValue() instanceof SimpleAsyncTaskExecutor));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="step1" next="step2">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
<split id="step2" next="step3">
|
||||
<flow id="step2a">
|
||||
<step id="step2aStep1">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
</flow>
|
||||
<flow id="step2b">
|
||||
<step id="step2bStep1" next="step2bStep2">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
<step id="step2bStep2">
|
||||
<chunk checkpoint-policy="item" item-count="3">
|
||||
<reader ref="generatingItemReader1"/>
|
||||
<processor ref="countingItemProcessor"/>
|
||||
<writer ref="sysoutItemWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="step3">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">
|
||||
|
||||
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
|
||||
<step id="step1" next="step2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<split id="step2" next="step3">
|
||||
<flow id="step2a">
|
||||
<step id="step2aStep1">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</flow>
|
||||
<flow id="step2b">
|
||||
<step id="step2bStep1" next="step2bStep2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<step id="step2bStep2">
|
||||
<chunk checkpoint-policy="item" item-count="3">
|
||||
<reader ref="generatingItemReader1"/>
|
||||
<processor ref="countingItemProcessor"/>
|
||||
<writer ref="sysoutItemWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="step3">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
|
||||
|
||||
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<value>One</value>
|
||||
<value>Two</value>
|
||||
<value>Three</value>
|
||||
<value>Four</value>
|
||||
<value>Five</value>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.CountingItemProcessor"/>
|
||||
|
||||
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
|
||||
<property name="targetObject">
|
||||
<util:constant static-field="java.lang.System.out"/>
|
||||
</property>
|
||||
<property name="targetMethod" value="println"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository"/>
|
||||
</bean>
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">
|
||||
|
||||
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
|
||||
<step id="step1" next="step2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<split id="step2" next="step3">
|
||||
<flow id="step2a">
|
||||
<step id="step2aStep1">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</flow>
|
||||
<flow id="step2b">
|
||||
<step id="step2bStep1" next="step2bStep2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<step id="step2bStep2">
|
||||
<chunk checkpoint-policy="item" item-count="3">
|
||||
<reader ref="generatingItemReader1"/>
|
||||
<processor ref="countingItemProcessor"/>
|
||||
<writer ref="sysoutItemWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="step3">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
|
||||
|
||||
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<value>One</value>
|
||||
<value>Two</value>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.CountingItemProcessor"/>
|
||||
|
||||
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
|
||||
<property name="targetObject">
|
||||
<util:constant static-field="java.lang.System.out"/>
|
||||
</property>
|
||||
<property name="targetMethod" value="println"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository"/>
|
||||
</bean>
|
||||
</beans>
|
||||
@@ -1,19 +1,25 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd"
|
||||
version="1.0">
|
||||
<step id="step1" next="step2">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
<split id="step2" next="step3">
|
||||
<flow id="step2a">
|
||||
<step id="step2aStep1">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="step3">
|
||||
<batchlet ref="step1Ref" />
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">
|
||||
|
||||
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
|
||||
<step id="step1" next="step2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<split id="step2" next="step3">
|
||||
<flow id="step2a">
|
||||
<step id="step2aStep1">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="step3">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:util="http://www.springframework.org/schema/util"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
|
||||
http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/jobXML_1_0.xsd">
|
||||
|
||||
<job id="job1" xmlns="http://xmlns.jcp.org/xml/ns/javaee" version="1.0">
|
||||
<step id="step1" next="step2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<split id="step2" next="step3">
|
||||
<flow id="step2a">
|
||||
<step id="step2aStep1">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</flow>
|
||||
<flow id="step2b">
|
||||
<step id="step2bStep1" next="step2bStep2">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
<step id="step2bStep2">
|
||||
<chunk checkpoint-policy="item" item-count="3">
|
||||
<reader ref="generatingItemReader1"/>
|
||||
<processor ref="countingItemProcessor"/>
|
||||
<writer ref="sysoutItemWriter"/>
|
||||
</chunk>
|
||||
</step>
|
||||
</flow>
|
||||
</split>
|
||||
<step id="step3">
|
||||
<batchlet ref="step1Ref"/>
|
||||
</step>
|
||||
</job>
|
||||
|
||||
<bean id="step1Ref" class="org.springframework.batch.core.step.tasklet.TaskletSupport"/>
|
||||
|
||||
<bean id="generatingItemReader1" class="org.springframework.batch.item.support.ListItemReader">
|
||||
<constructor-arg>
|
||||
<list>
|
||||
<value>One</value>
|
||||
<value>Two</value>
|
||||
</list>
|
||||
</constructor-arg>
|
||||
</bean>
|
||||
|
||||
<bean id="countingItemProcessor" class="org.springframework.batch.core.jsr.configuration.xml.CountingItemProcessor"/>
|
||||
|
||||
<bean id="sysoutItemWriter" class="org.springframework.batch.item.adapter.ItemWriterAdapter">
|
||||
<property name="targetObject">
|
||||
<util:constant static-field="java.lang.System.out"/>
|
||||
</property>
|
||||
<property name="targetMethod" value="println"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jobRepository" class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean"/>
|
||||
|
||||
<bean id="transactionManager" class="org.springframework.batch.support.transaction.ResourcelessTransactionManager"/>
|
||||
|
||||
<bean id="jobLauncher" class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
|
||||
<property name="jobRepository" ref="jobRepository"/>
|
||||
</bean>
|
||||
|
||||
<bean id="jsr352splitTaskExecutor" class="org.springframework.core.task.SyncTaskExecutor"/>
|
||||
</beans>
|
||||
Reference in New Issue
Block a user