Added comparitor for state transitions when using java config
Spring Batch orders the transitions as it goes from state to state based
on specificity. The XML configuration has always had this
functionality. However, when creating the JSR-352 implementation, the
mechanism for which this occured was refactored. That occured at about
the same time as the java builders were introduced. Because of this
crossing of paths, the java configuration option for defining jobs has
never correctly sorted the transitions. This PR applys the sorting
algorithm to the java configuration, making XML and java configuration
behave the same.
Resolves #3638
(cherry picked from commit 8e8f9c8101)
This commit is contained in:
committed by
Mahmoud Ben Hassine
parent
3f92cd0bc3
commit
041eb28fd6
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -30,6 +30,7 @@ import org.springframework.batch.core.job.flow.Flow;
|
||||
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.DefaultStateTransitionComparator;
|
||||
import org.springframework.batch.core.job.flow.support.SimpleFlow;
|
||||
import org.springframework.batch.core.job.flow.support.StateTransition;
|
||||
import org.springframework.batch.core.job.flow.support.state.DecisionState;
|
||||
@@ -44,6 +45,7 @@ import org.springframework.core.task.TaskExecutor;
|
||||
* conditional transitions that depend on the exit status of the previous step.
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
*
|
||||
* @since 2.2
|
||||
*
|
||||
@@ -244,6 +246,7 @@ public class FlowBuilder<Q> {
|
||||
}
|
||||
addDanglingEndStates();
|
||||
flow.setStateTransitions(transitions);
|
||||
flow.setStateTransitionComparator(new DefaultStateTransitionComparator());
|
||||
dirty = false;
|
||||
return flow;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2020 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.
|
||||
@@ -15,7 +15,11 @@
|
||||
*/
|
||||
package org.springframework.batch.core.job.builder;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.batch.core.ExitStatus;
|
||||
import org.springframework.batch.core.JobExecution;
|
||||
import org.springframework.batch.core.JobInterruptedException;
|
||||
import org.springframework.batch.core.JobParameters;
|
||||
@@ -23,13 +27,17 @@ import org.springframework.batch.core.StepExecution;
|
||||
import org.springframework.batch.core.UnexpectedJobExecutionException;
|
||||
import org.springframework.batch.core.job.SimpleStepHandler;
|
||||
import org.springframework.batch.core.job.flow.Flow;
|
||||
import org.springframework.batch.core.job.flow.FlowExecution;
|
||||
import org.springframework.batch.core.job.flow.JobFlowExecutor;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.StepSupport;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
* @author Michael Minella
|
||||
*
|
||||
*/
|
||||
public class FlowBuilderTests {
|
||||
@@ -47,4 +55,43 @@ public class FlowBuilderTests {
|
||||
}).end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testTransitionOrdering() throws Exception {
|
||||
FlowBuilder<Flow> builder = new FlowBuilder<>("transitionsFlow");
|
||||
JobRepository jobRepository = new MapJobRepositoryFactoryBean().getObject();
|
||||
JobExecution execution = jobRepository.createJobExecution("foo", new JobParameters());
|
||||
|
||||
StepSupport stepA = new StepSupport("stepA") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
stepExecution.setExitStatus(new ExitStatus("FAILED"));
|
||||
}
|
||||
};
|
||||
|
||||
StepSupport stepB = new StepSupport("stepB") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
}
|
||||
};
|
||||
|
||||
StepSupport stepC = new StepSupport("stepC") {
|
||||
@Override
|
||||
public void execute(StepExecution stepExecution) throws JobInterruptedException,
|
||||
UnexpectedJobExecutionException {
|
||||
}
|
||||
};
|
||||
|
||||
FlowExecution flowExecution = builder.start(stepA)
|
||||
.on("*").to(stepB)
|
||||
.from(stepA).on("FAILED").to(stepC)
|
||||
.end().start(new JobFlowExecutor(jobRepository, new SimpleStepHandler(jobRepository), execution));
|
||||
|
||||
Iterator<StepExecution> stepExecutions = execution.getStepExecutions().iterator();
|
||||
StepExecution stepExecutionA = stepExecutions.next();
|
||||
assertEquals(stepExecutionA.getStepName(), "stepA");
|
||||
StepExecution stepExecutionC = stepExecutions.next();
|
||||
assertEquals(stepExecutionC.getStepName(), "stepC");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user