package org.springframework.batch.integration.partition; import org.springframework.batch.core.BatchStatus; import org.springframework.batch.core.JobInterruptedException; import org.springframework.batch.core.Step; import org.springframework.batch.core.StepExecution; import org.springframework.batch.core.explore.JobExplorer; import org.springframework.batch.core.step.NoSuchStepException; import org.springframework.batch.core.step.StepLocator; import org.springframework.integration.annotation.MessageEndpoint; import org.springframework.integration.annotation.ServiceActivator; /** * A {@link MessageEndpoint} that can handle a {@link StepExecutionRequest} and * return a {@link StepExecution} as the result. Typically these need to be * aggregated into a response to a partition handler. * * @author Dave Syer * */ @MessageEndpoint public class StepExecutionRequestHandler { private JobExplorer jobExplorer; private StepLocator stepLocator; /** * Used to locate a {@link Step} to execute for each request. * @param stepLocator a {@link StepLocator} */ public void setStepLocator(StepLocator stepLocator) { this.stepLocator = stepLocator; } /** * An explorer that should be used to check for {@link StepExecution} * completion. * * @param jobExplorer a {@link JobExplorer} that is linked to the shared * repository used by all remote workers. */ public void setJobExplorer(JobExplorer jobExplorer) { this.jobExplorer = jobExplorer; } @ServiceActivator public StepExecution handle(StepExecutionRequest request) { Long jobExecutionId = request.getJobExecutionId(); Long stepExecutionId = request.getStepExecutionId(); StepExecution stepExecution = jobExplorer.getStepExecution(jobExecutionId, stepExecutionId); if (stepExecution == null) { throw new NoSuchStepException("No StepExecution could be located for this request: " + request); } String stepName = request.getStepName(); Step step = stepLocator.getStep(stepName); if (step == null) { throw new NoSuchStepException(String.format("No Step with name [%s] could be located.", stepName)); } try { step.execute(stepExecution); } catch (JobInterruptedException e) { stepExecution.setStatus(BatchStatus.STOPPED); // The receiver should update the stepExecution in repository } catch (Throwable e) { stepExecution.addFailureException(e); stepExecution.setStatus(BatchStatus.FAILED); // The receiver should update the stepExecution in repository } return stepExecution; } }