BATCH-2072: Implemented wrapper for JSR-352 Decider
This commit is contained in:
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.jsr;
|
||||
|
||||
import javax.batch.api.Decider;
|
||||
import javax.batch.operations.BatchRuntimeException;
|
||||
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Wrapper for {@link Decider} implementation to allow it to be used
|
||||
* by the rest of the framework.
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DecisionAdapter implements JobExecutionDecider {
|
||||
|
||||
private Decider decider;
|
||||
|
||||
/**
|
||||
* @param decider a {@link Decider}
|
||||
*/
|
||||
public DecisionAdapter(Decider decider) {
|
||||
Assert.notNull(decider, "A Decider implementation is required");
|
||||
|
||||
this.decider = decider;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.batch.core.job.flow.JobExecutionDecider#decide(org.springframework.batch.core.JobExecution, org.springframework.batch.core.StepExecution)
|
||||
*/
|
||||
@Override
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution,
|
||||
StepExecution stepExecution) {
|
||||
|
||||
javax.batch.runtime.StepExecution [] executions = null;
|
||||
|
||||
//TODO: Address splits
|
||||
if(stepExecution != null) {
|
||||
executions = new org.springframework.batch.core.jsr.StepExecution[1];
|
||||
executions[0] = new org.springframework.batch.core.jsr.StepExecution(stepExecution);
|
||||
}
|
||||
|
||||
try {
|
||||
return new FlowExecutionStatus(decider.decide(executions));
|
||||
} catch (Exception e) {
|
||||
throw new BatchRuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,20 +21,34 @@ import java.lang.reflect.Modifier;
|
||||
import java.util.HashSet;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.batch.api.BatchProperty;
|
||||
import javax.batch.api.Batchlet;
|
||||
import javax.batch.api.Decider;
|
||||
import javax.batch.api.chunk.CheckpointAlgorithm;
|
||||
import javax.batch.api.chunk.ItemProcessor;
|
||||
import javax.batch.api.chunk.ItemReader;
|
||||
import javax.batch.api.chunk.ItemWriter;
|
||||
import javax.batch.api.chunk.listener.ChunkListener;
|
||||
import javax.batch.api.chunk.listener.ItemProcessListener;
|
||||
import javax.batch.api.chunk.listener.ItemReadListener;
|
||||
import javax.batch.api.chunk.listener.ItemWriteListener;
|
||||
import javax.batch.api.chunk.listener.RetryProcessListener;
|
||||
import javax.batch.api.chunk.listener.RetryReadListener;
|
||||
import javax.batch.api.chunk.listener.RetryWriteListener;
|
||||
import javax.batch.api.chunk.listener.SkipProcessListener;
|
||||
import javax.batch.api.chunk.listener.SkipReadListener;
|
||||
import javax.batch.api.chunk.listener.SkipWriteListener;
|
||||
import javax.batch.api.listener.JobListener;
|
||||
import javax.batch.api.listener.StepListener;
|
||||
import javax.batch.api.partition.PartitionAnalyzer;
|
||||
import javax.batch.api.partition.PartitionCollector;
|
||||
import javax.batch.api.partition.PartitionMapper;
|
||||
import javax.batch.api.partition.PartitionPlan;
|
||||
import javax.batch.api.partition.PartitionReducer;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.Step;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.batch.repeat.CompletionPolicy;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
@@ -47,114 +61,129 @@ import org.springframework.util.ReflectionUtils;
|
||||
* </p>
|
||||
*
|
||||
* @author Chris Schaefer
|
||||
* @author Michael Minella
|
||||
* @since 3.0
|
||||
*/
|
||||
public class BatchPropertyBeanPostProcessor implements BeanPostProcessor {
|
||||
@Autowired
|
||||
private BatchPropertyContext batchPropertyContext;
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
private Set<Class<? extends Annotation>> requiredAnnotations = new HashSet<Class<? extends Annotation>>();
|
||||
@Autowired
|
||||
private BatchPropertyContext batchPropertyContext;
|
||||
private Log logger = LogFactory.getLog(getClass());
|
||||
private Set<Class<? extends Annotation>> requiredAnnotations = new HashSet<Class<? extends Annotation>>();
|
||||
|
||||
public BatchPropertyBeanPostProcessor() {
|
||||
setRequiredAnnotations();
|
||||
}
|
||||
public BatchPropertyBeanPostProcessor() {
|
||||
setRequiredAnnotations();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
|
||||
if (!isBatchArtifact(bean)) {
|
||||
return bean;
|
||||
}
|
||||
@Override
|
||||
public Object postProcessBeforeInitialization(final Object bean, String beanName) throws BeansException {
|
||||
if (!isBatchArtifact(bean)) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
final Properties artifactProperties = batchPropertyContext.getBatchProperties(beanName);
|
||||
final Properties artifactProperties = batchPropertyContext.getBatchProperties(beanName);
|
||||
|
||||
if (artifactProperties.isEmpty()) {
|
||||
return bean;
|
||||
}
|
||||
if (artifactProperties.isEmpty()) {
|
||||
return bean;
|
||||
}
|
||||
|
||||
injectBatchProperties(bean, artifactProperties);
|
||||
injectBatchProperties(bean, artifactProperties);
|
||||
|
||||
return bean;
|
||||
}
|
||||
return bean;
|
||||
}
|
||||
|
||||
private void setRequiredAnnotations() {
|
||||
ClassLoader cl = BatchPropertyBeanPostProcessor.class.getClassLoader();
|
||||
@SuppressWarnings("unchecked")
|
||||
private void setRequiredAnnotations() {
|
||||
ClassLoader cl = BatchPropertyBeanPostProcessor.class.getClassLoader();
|
||||
|
||||
try {
|
||||
this.requiredAnnotations.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("javax.inject.Inject not found - @BatchProperty marked fields will not be processed.");
|
||||
}
|
||||
try {
|
||||
this.requiredAnnotations.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
|
||||
} catch (ClassNotFoundException ex) {
|
||||
logger.warn("javax.inject.Inject not found - @BatchProperty marked fields will not be processed.");
|
||||
}
|
||||
|
||||
this.requiredAnnotations.add(BatchProperty.class);
|
||||
}
|
||||
this.requiredAnnotations.add(BatchProperty.class);
|
||||
}
|
||||
|
||||
private boolean isBatchArtifact(Object bean) {
|
||||
return (bean instanceof ItemReader) ||
|
||||
(bean instanceof ItemProcessor) ||
|
||||
(bean instanceof ItemWriter) ||
|
||||
(bean instanceof CompletionPolicy) ||
|
||||
(bean instanceof Batchlet) ||
|
||||
(bean instanceof ItemReadListener) ||
|
||||
(bean instanceof ItemProcessListener) ||
|
||||
(bean instanceof ItemWriteListener) ||
|
||||
(bean instanceof JobExecutionDecider) ||
|
||||
(bean instanceof Step) ||
|
||||
(bean instanceof Job);
|
||||
}
|
||||
private boolean isBatchArtifact(Object bean) {
|
||||
return (bean instanceof ItemReader) ||
|
||||
(bean instanceof ItemProcessor) ||
|
||||
(bean instanceof ItemWriter) ||
|
||||
(bean instanceof CheckpointAlgorithm) ||
|
||||
(bean instanceof Batchlet) ||
|
||||
(bean instanceof ItemReadListener) ||
|
||||
(bean instanceof ItemProcessListener) ||
|
||||
(bean instanceof ItemWriteListener) ||
|
||||
(bean instanceof JobListener) ||
|
||||
(bean instanceof StepListener) ||
|
||||
(bean instanceof ChunkListener) ||
|
||||
(bean instanceof SkipReadListener) ||
|
||||
(bean instanceof SkipProcessListener) ||
|
||||
(bean instanceof SkipWriteListener) ||
|
||||
(bean instanceof RetryReadListener) ||
|
||||
(bean instanceof RetryProcessListener) ||
|
||||
(bean instanceof RetryWriteListener) ||
|
||||
(bean instanceof PartitionMapper) ||
|
||||
(bean instanceof PartitionReducer) ||
|
||||
(bean instanceof PartitionCollector) ||
|
||||
(bean instanceof PartitionAnalyzer) ||
|
||||
(bean instanceof PartitionPlan) ||
|
||||
(bean instanceof Decider);
|
||||
}
|
||||
|
||||
private void injectBatchProperties(final Object bean, final Properties artifactProperties) {
|
||||
ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
|
||||
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
if (isValidFieldModifier(field) && isAnnotated(field)) {
|
||||
boolean isAccessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
private void injectBatchProperties(final Object bean, final Properties artifactProperties) {
|
||||
ReflectionUtils.doWithFields(bean.getClass(), new ReflectionUtils.FieldCallback() {
|
||||
@Override
|
||||
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
|
||||
if (isValidFieldModifier(field) && isAnnotated(field)) {
|
||||
boolean isAccessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
|
||||
String batchProperty = getBatchPropertyFieldValue(field, artifactProperties);
|
||||
String batchProperty = getBatchPropertyFieldValue(field, artifactProperties);
|
||||
|
||||
if (batchProperty != null) {
|
||||
field.set(bean, batchProperty);
|
||||
}
|
||||
if (batchProperty != null) {
|
||||
field.set(bean, batchProperty);
|
||||
}
|
||||
|
||||
field.setAccessible(isAccessible);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
field.setAccessible(isAccessible);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String getBatchPropertyFieldValue(Field field, Properties batchArtifactProperties) {
|
||||
BatchProperty batchProperty = field.getAnnotation(BatchProperty.class);
|
||||
private String getBatchPropertyFieldValue(Field field, Properties batchArtifactProperties) {
|
||||
BatchProperty batchProperty = field.getAnnotation(BatchProperty.class);
|
||||
|
||||
if (!"".equals(batchProperty.name())) {
|
||||
return getBatchProperty(batchProperty.name(), batchArtifactProperties);
|
||||
}
|
||||
if (!"".equals(batchProperty.name())) {
|
||||
return getBatchProperty(batchProperty.name(), batchArtifactProperties);
|
||||
}
|
||||
|
||||
return getBatchProperty(field.getName(), batchArtifactProperties);
|
||||
}
|
||||
return getBatchProperty(field.getName(), batchArtifactProperties);
|
||||
}
|
||||
|
||||
private String getBatchProperty(String propertyKey, Properties batchArtifactProperties) {
|
||||
if (batchArtifactProperties.containsKey(propertyKey)) {
|
||||
return (String) batchArtifactProperties.get(propertyKey);
|
||||
}
|
||||
private String getBatchProperty(String propertyKey, Properties batchArtifactProperties) {
|
||||
if (batchArtifactProperties.containsKey(propertyKey)) {
|
||||
return (String) batchArtifactProperties.get(propertyKey);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isAnnotated(Field field) {
|
||||
for (Class<? extends Annotation> annotation : requiredAnnotations) {
|
||||
if(!field.isAnnotationPresent(annotation)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
private boolean isAnnotated(Field field) {
|
||||
for (Class<? extends Annotation> annotation : requiredAnnotations) {
|
||||
if(!field.isAnnotationPresent(annotation)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean isValidFieldModifier(Field field) {
|
||||
return !Modifier.isStatic(field.getModifiers()) && !Modifier.isFinal(field.getModifiers());
|
||||
}
|
||||
private boolean isValidFieldModifier(Field field) {
|
||||
return !Modifier.isStatic(field.getModifiers()) && !Modifier.isFinal(field.getModifiers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
@Override
|
||||
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
|
||||
return bean;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,6 @@ import java.util.Collection;
|
||||
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
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.xml.ParserContext;
|
||||
import org.w3c.dom.Element;
|
||||
@@ -27,7 +26,7 @@ import org.w3c.dom.Element;
|
||||
/**
|
||||
* Parser for the <decision /> element as specified in JSR-352. The current state
|
||||
* parses a decision element and assumes that it refers to a {@link JobExecutionDecider}
|
||||
*
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @author Chris Schaefer
|
||||
* @since 3.0
|
||||
@@ -42,9 +41,9 @@ public class DecisionParser {
|
||||
String idAttribute = element.getAttribute(ID_ATTRIBUTE);
|
||||
|
||||
BeanDefinitionBuilder stateBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.batch.core.job.flow.support.state.DecisionState");
|
||||
stateBuilder.addConstructorArgValue(new RuntimeBeanReference(refAttribute));
|
||||
stateBuilder.addConstructorArgValue(idAttribute);
|
||||
BeanDefinitionBuilder.genericBeanDefinition("org.springframework.batch.core.jsr.configuration.xml.DecisionStateFactoryBean");
|
||||
stateBuilder.addPropertyReference("decider", refAttribute);
|
||||
stateBuilder.addPropertyValue("name", idAttribute);
|
||||
|
||||
new PropertyParser(refAttribute, parserContext).parseProperties(element);
|
||||
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright 2013 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.batch.core.jsr.configuration.xml;
|
||||
|
||||
import javax.batch.api.Decider;
|
||||
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.batch.core.job.flow.State;
|
||||
import org.springframework.batch.core.job.flow.support.state.DecisionState;
|
||||
import org.springframework.batch.core.jsr.DecisionAdapter;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link FactoryBean} for creating a {@link DecisionState}. If the underlying
|
||||
* decider is a {@link Decider}, it will be wrapped in a {@link DecisionAdapter}.
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @since 3.0
|
||||
*/
|
||||
public class DecisionStateFactoryBean implements FactoryBean<State>, InitializingBean {
|
||||
|
||||
private Decider jsrDecider;
|
||||
private JobExecutionDecider decider;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* @param decider either a {@link Decider} or a {@link JobExecutionDecider}
|
||||
* @throws IllegalArgumentException if the type passed in is not a valid type
|
||||
*/
|
||||
public void setDecider(Object decider) {
|
||||
if(decider instanceof JobExecutionDecider) {
|
||||
this.decider = (JobExecutionDecider) decider;
|
||||
} else if(decider instanceof Decider) {
|
||||
this.jsrDecider = (Decider) decider;
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid type for a decider");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of the state
|
||||
*
|
||||
* @param name
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObject()
|
||||
*/
|
||||
@Override
|
||||
public State getObject() throws Exception {
|
||||
JobExecutionDecider wrappedDecider = null;
|
||||
|
||||
if(decider != null) {
|
||||
wrappedDecider = decider;
|
||||
} else if(jsrDecider != null) {
|
||||
wrappedDecider = new DecisionAdapter(jsrDecider);
|
||||
}
|
||||
State state = new DecisionState(wrappedDecider, name);
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#getObjectType()
|
||||
*/
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return JobExecutionDecider.class;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.FactoryBean#isSingleton()
|
||||
*/
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.isTrue(!(decider == null && jsrDecider == null), "A decider implementation is required");
|
||||
Assert.notNull(name, "A name is required for a decision state");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
package org.springframework.batch.core.jsr.configuration.xml;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import javax.batch.api.Decider;
|
||||
import javax.batch.runtime.StepExecution;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.batch.core.job.flow.State;
|
||||
import org.springframework.batch.core.job.flow.support.state.DecisionState;
|
||||
|
||||
public class DecisionStateFactoryBeanTests {
|
||||
|
||||
private DecisionStateFactoryBean factoryBean;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
factoryBean = new DecisionStateFactoryBean();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetObjectType() {
|
||||
assertEquals(JobExecutionDecider.class, factoryBean.getObjectType());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIsSingleton() {
|
||||
assertTrue(factoryBean.isSingleton());
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullDeciderAndName() throws Exception {
|
||||
factoryBean.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullDecider() throws Exception{
|
||||
factoryBean.setName("state1");
|
||||
factoryBean.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void testNullName() throws Exception {
|
||||
factoryBean.setDecider(new DeciderSupport());
|
||||
factoryBean.afterPropertiesSet();
|
||||
}
|
||||
|
||||
@Test(expected=IllegalArgumentException.class)
|
||||
public void setWrongDeciderType() {
|
||||
factoryBean.setDecider("Some decider");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testJobExecutionDeciderState() throws Exception {
|
||||
factoryBean.setDecider(new JobExecutionDeciderSupport());
|
||||
factoryBean.setName("IL");
|
||||
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
State state = factoryBean.getObject();
|
||||
|
||||
assertEquals("IL", state.getName());
|
||||
assertEquals(DecisionState.class, state.getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeciderDeciderState() throws Exception {
|
||||
factoryBean.setDecider(new DeciderSupport());
|
||||
factoryBean.setName("IL");
|
||||
|
||||
factoryBean.afterPropertiesSet();
|
||||
|
||||
State state = factoryBean.getObject();
|
||||
|
||||
assertEquals("IL", state.getName());
|
||||
assertEquals(DecisionState.class, state.getClass());
|
||||
}
|
||||
|
||||
public static class DeciderSupport implements Decider {
|
||||
|
||||
@Override
|
||||
public String decide(StepExecution[] executions) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class JobExecutionDeciderSupport implements JobExecutionDecider {
|
||||
|
||||
@Override
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution,
|
||||
org.springframework.batch.core.StepExecution stepExecution) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,8 @@ import java.util.List;
|
||||
|
||||
import javax.batch.api.BatchProperty;
|
||||
import javax.batch.api.Batchlet;
|
||||
import javax.batch.api.Decider;
|
||||
import javax.batch.api.chunk.CheckpointAlgorithm;
|
||||
import javax.batch.api.chunk.ItemProcessor;
|
||||
import javax.batch.api.chunk.ItemReader;
|
||||
import javax.batch.api.chunk.ItemWriter;
|
||||
@@ -37,13 +39,7 @@ import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.Job;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
|
||||
import org.springframework.batch.core.job.flow.JobExecutionDecider;
|
||||
import org.springframework.batch.core.launch.JobLauncher;
|
||||
import org.springframework.batch.repeat.CompletionPolicy;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
@@ -335,32 +331,13 @@ public class JobPropertyTests {
|
||||
}
|
||||
}
|
||||
|
||||
public static final class TestCheckpointAlgorithm implements CompletionPolicy {
|
||||
public static final class TestCheckpointAlgorithm implements CheckpointAlgorithm {
|
||||
@Inject @BatchProperty String algorithmPropertyName1;
|
||||
@Inject @BatchProperty String algorithmPropertyName2;
|
||||
@Inject @BatchProperty(name = "annotationNamedAlgorithmPropertyName") String annotationNamedProperty;
|
||||
@Inject @BatchProperty String notDefinedProperty;
|
||||
@Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty;
|
||||
|
||||
@Override
|
||||
public boolean isComplete(RepeatContext context, RepeatStatus result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isComplete(RepeatContext context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RepeatContext start(RepeatContext parent) {
|
||||
return parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(RepeatContext context) {
|
||||
}
|
||||
|
||||
String getAlgorithmPropertyName1() {
|
||||
return algorithmPropertyName1;
|
||||
}
|
||||
@@ -380,21 +357,33 @@ public class JobPropertyTests {
|
||||
String getNotDefinedAnnotationNamedProperty() {
|
||||
return notDefinedAnnotationNamedProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int checkpointTimeout() throws Exception {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void beginCheckpoint() throws Exception {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isReadyToCheckpoint() throws Exception {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endCheckpoint() throws Exception {
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestDecider implements JobExecutionDecider {
|
||||
public static class TestDecider implements Decider {
|
||||
@Inject @BatchProperty String deciderPropertyName1;
|
||||
@Inject @BatchProperty String deciderPropertyName2;
|
||||
@Inject @BatchProperty(name = "annotationNamedDeciderPropertyName") String annotationNamedProperty;
|
||||
@Inject @BatchProperty String notDefinedProperty;
|
||||
@Inject @BatchProperty(name = "notDefinedAnnotationNamedProperty") String notDefinedAnnotationNamedProperty;
|
||||
|
||||
@Override
|
||||
public FlowExecutionStatus decide(JobExecution jobExecution,
|
||||
StepExecution stepExecution) {
|
||||
return new FlowExecutionStatus("step2");
|
||||
}
|
||||
|
||||
String getDeciderPropertyName1() {
|
||||
return deciderPropertyName1;
|
||||
}
|
||||
@@ -414,6 +403,12 @@ public class JobPropertyTests {
|
||||
String getNotDefinedAnnotationNamedProperty() {
|
||||
return notDefinedAnnotationNamedProperty;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decide(javax.batch.runtime.StepExecution[] executions)
|
||||
throws Exception {
|
||||
return "step2";
|
||||
}
|
||||
}
|
||||
|
||||
public static class TestStepListener implements javax.batch.api.chunk.listener.ItemReadListener,
|
||||
|
||||
Reference in New Issue
Block a user