Package org.springframework.batch.core.jsr.job.flow

Source Code of org.springframework.batch.core.jsr.job.flow.JsrFlowJobTests

/*
* Copyright 2006-2014 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.job.flow;

import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.ExitStatus;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobInstance;
import org.springframework.batch.core.JobInterruptedException;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.StepExecution;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.explore.support.MapJobExplorerFactoryBean;
import org.springframework.batch.core.job.flow.Flow;
import org.springframework.batch.core.job.flow.FlowExecutionStatus;
import org.springframework.batch.core.job.flow.FlowExecutor;
import org.springframework.batch.core.job.flow.JobExecutionDecider;
import org.springframework.batch.core.job.flow.State;
import org.springframework.batch.core.job.flow.StateSupport;
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;
import org.springframework.batch.core.job.flow.support.state.EndState;
import org.springframework.batch.core.job.flow.support.state.FlowState;
import org.springframework.batch.core.job.flow.support.state.SplitState;
import org.springframework.batch.core.job.flow.support.state.StepState;
import org.springframework.batch.core.jsr.JsrStepExecution;
import org.springframework.batch.core.jsr.job.flow.support.JsrFlow;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.repository.dao.JobExecutionDao;
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
import org.springframework.batch.core.step.StepSupport;

import javax.batch.api.Decider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

/**
* @author Dave Syer
* @author Michael Minella
*/
public class JsrFlowJobTests {

  private JsrFlowJob job;

  private JobExecution jobExecution;

  private JobRepository jobRepository;

  private JobExplorer jobExplorer;

  private boolean fail = false;

  private JobExecutionDao jobExecutionDao;

  @Before
  public void setUp() throws Exception {
    job = new JsrFlowJob();
    MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean();
    jobRepositoryFactory.afterPropertiesSet();
    jobExecutionDao = jobRepositoryFactory.getJobExecutionDao();
    jobRepository = jobRepositoryFactory.getObject();
    job.setJobRepository(jobRepository);
    jobExecution = jobRepository.createJobExecution("job", new JobParameters());

    MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(jobRepositoryFactory);
    jobExplorerFactory.afterPropertiesSet();
    jobExplorer = jobExplorerFactory.getObject();
    job.setJobExplorer(jobExplorer);
  }

  @Test
  public void testGetSteps() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();
    assertEquals(2, job.getStepNames().size());
  }

  @Test
  public void testTwoSteps() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.doExecute(jobExecution);
    StepExecution stepExecution = getStepExecution(jobExecution, "step2");
    assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus());
    assertEquals(2, jobExecution.getStepExecutions().size());
  }

  @Test
  public void testFailedStep() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StateSupport("step1", FlowExecutionStatus.FAILED),
        "step2"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.doExecute(jobExecution);
    StepExecution stepExecution = getStepExecution(jobExecution, "step2");
    assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus());
    assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
    assertEquals(2, jobExecution.getStepExecutions().size());
  }

  @Test
  public void testFailedStepRestarted() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    State step2State = new StateSupport("step2") {
      @Override
      public FlowExecutionStatus handle(FlowExecutor executor) throws Exception {
        JobExecution jobExecution = executor.getJobExecution();
        StepExecution stepExecution = jobExecution.createStepExecution(getName());
        jobRepository.add(stepExecution);
        if (fail) {
          return FlowExecutionStatus.FAILED;
        }
        else {
          return FlowExecutionStatus.COMPLETED;
        }
      }
    };
    transitions.add(StateTransition.createStateTransition(step2State, ExitStatus.COMPLETED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2State, ExitStatus.FAILED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    fail = true;
    job.execute(jobExecution);
    assertEquals(ExitStatus.FAILED, jobExecution.getExitStatus());
    assertEquals(2, jobExecution.getStepExecutions().size());
    jobRepository.update(jobExecution);
    jobExecution = jobRepository.createJobExecution("job", new JobParameters());
    fail = false;
    job.execute(jobExecution);
    assertEquals(ExitStatus.COMPLETED, jobExecution.getExitStatus());
    assertEquals(1, jobExecution.getStepExecutions().size());
  }

  @Test
  public void testStoppingStep() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    State state2 = new StateSupport("step2", FlowExecutionStatus.FAILED);
    transitions.add(StateTransition.createStateTransition(state2, ExitStatus.FAILED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(state2, ExitStatus.COMPLETED.getExitCode(), "end1"));
    transitions.add(StateTransition.createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end0"),
        "step3"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step3")), "end2"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end2")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.doExecute(jobExecution);
    assertEquals(2, jobExecution.getStepExecutions().size());
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
  }

  @Test
  public void testInterrupted() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") {
      @Override
      public void execute(StepExecution stepExecution) throws JobInterruptedException {
        stepExecution.setStatus(BatchStatus.STOPPING);
        jobRepository.update(stepExecution);
      }
    }), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.execute(jobExecution);
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
    checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED);
    assertEquals(1, jobExecution.getAllFailureExceptions().size());
    assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass());
  }

  @Test
  public void testUnknownStatusStopsJob() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") {
      @Override
      public void execute(StepExecution stepExecution) throws JobInterruptedException {
        stepExecution.setStatus(BatchStatus.UNKNOWN);
        stepExecution.setTerminateOnly();
        jobRepository.update(stepExecution);
      }
    }), "step2"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.execute(jobExecution);
    assertEquals(BatchStatus.UNKNOWN, jobExecution.getStatus());
    checkRepository(BatchStatus.UNKNOWN, ExitStatus.STOPPED);
    assertEquals(1, jobExecution.getAllFailureExceptions().size());
    assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass());
  }

  @Test
  public void testInterruptedSplit() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    SimpleFlow flow1 = new JsrFlow("flow1");
    SimpleFlow flow2 = new JsrFlow("flow2");

    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") {
      @Override
      public void execute(StepExecution stepExecution) throws JobInterruptedException {
        if (!stepExecution.getJobExecution().getExecutionContext().containsKey("STOPPED")) {
          stepExecution.getJobExecution().getExecutionContext().put("STOPPED", true);
          stepExecution.setStatus(BatchStatus.STOPPED);
          jobRepository.update(stepExecution);
        }
        else {
          fail("The Job should have stopped by now");
        }
      }
    }), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow1.setStateTransitions(new ArrayList<StateTransition>(transitions));
    flow1.afterPropertiesSet();
    flow2.setStateTransitions(new ArrayList<StateTransition>(transitions));
    flow2.afterPropertiesSet();

    transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new SplitState(Arrays.<Flow> asList(flow1, flow2),
        "split"), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();

    job.setFlow(flow);
    job.afterPropertiesSet();
    job.execute(jobExecution);
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
    checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED);
    assertEquals(1, jobExecution.getAllFailureExceptions().size());
    assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass());
    assertEquals(1, jobExecution.getStepExecutions().size());
    for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
      assertEquals(BatchStatus.STOPPED, stepExecution.getStatus());
    }
  }

  @Test
  public void testInterruptedException() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") {
      @Override
      public void execute(StepExecution stepExecution) throws JobInterruptedException {
        throw new JobInterruptedException("Stopped");
      }
    }), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.execute(jobExecution);
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
    checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED);
    assertEquals(1, jobExecution.getAllFailureExceptions().size());
    assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass());
  }

  @Test
  public void testInterruptedSplitException() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    SimpleFlow flow1 = new JsrFlow("flow1");
    SimpleFlow flow2 = new JsrFlow("flow2");

    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1") {
      @Override
      public void execute(StepExecution stepExecution) throws JobInterruptedException {
        throw new JobInterruptedException("Stopped");
      }
    }), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow1.setStateTransitions(new ArrayList<StateTransition>(transitions));
    flow1.afterPropertiesSet();
    flow2.setStateTransitions(new ArrayList<StateTransition>(transitions));
    flow2.afterPropertiesSet();

    transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new SplitState(Arrays.<Flow> asList(flow1, flow2),
        "split"), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();

    job.setFlow(flow);
    job.afterPropertiesSet();
    job.execute(jobExecution);
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
    checkRepository(BatchStatus.STOPPED, ExitStatus.STOPPED);
    assertEquals(1, jobExecution.getAllFailureExceptions().size());
    assertEquals(JobInterruptedException.class, jobExecution.getFailureExceptions().get(0).getClass());
  }

  @Test
  public void testEndStateStopped() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
    transitions.add(StateTransition
        .createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end"), "step2"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.doExecute(jobExecution);
    assertEquals(1, jobExecution.getStepExecutions().size());
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
  }

  public void testEndStateFailed() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
    transitions
    .add(StateTransition.createStateTransition(new EndState(FlowExecutionStatus.FAILED, "end"), "step2"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), ExitStatus.FAILED
        .getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")),
        ExitStatus.COMPLETED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.doExecute(jobExecution);
    assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
    assertEquals(1, jobExecution.getStepExecutions().size());
  }

  @Test
  public void testEndStateStoppedWithRestart() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end"));
    transitions.add(StateTransition
        .createStateTransition(new EndState(FlowExecutionStatus.STOPPED, "end"), "step2"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();

    // To test a restart we have to use the AbstractJob.execute()...
    job.execute(jobExecution);
    assertEquals(BatchStatus.STOPPED, jobExecution.getStatus());
    assertEquals(1, jobExecution.getStepExecutions().size());

    jobExecution = jobRepository.createJobExecution("job", new JobParameters());
    job.execute(jobExecution);
    assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
    assertEquals(1, jobExecution.getStepExecutions().size());

  }

  @Test
  public void testBranching() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    StepState step1 = new StepState(new StubStep("step1"));
    transitions.add(StateTransition.createStateTransition(step1, "step2"));
    transitions.add(StateTransition.createStateTransition(step1, "COMPLETED", "step3"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
    StepState step3 = new StepState(new StubStep("step3"));
    transitions.add(StateTransition.createStateTransition(step3, ExitStatus.FAILED.getExitCode(), "end2"));
    transitions.add(StateTransition.createStateTransition(step3, ExitStatus.COMPLETED.getExitCode(), "end3"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.afterPropertiesSet();
    job.doExecute(jobExecution);
    StepExecution stepExecution = getStepExecution(jobExecution, "step2");
    assertEquals(ExitStatus.COMPLETED, stepExecution.getExitStatus());
    assertEquals(2, jobExecution.getStepExecutions().size());
  }

  @Test
  public void testBasicFlow() throws Throwable {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    job.setFlow(flow);
    job.execute(jobExecution);
    if (!jobExecution.getAllFailureExceptions().isEmpty()) {
      throw jobExecution.getAllFailureExceptions().get(0);
    }
    assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
  }

  @Test
  public void testDecisionFlow() throws Throwable {

    SimpleFlow flow = new JsrFlow("job");
    Decider decider = new Decider() {

      @Override
      public String decide(javax.batch.runtime.StepExecution[] executions)
          throws Exception {
        assertNotNull(executions);
        return "SWITCH";
      }
    };

    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "decision"));
    StepState decision = new StepState(new StubDecisionStep("decision", decider));
    transitions.add(StateTransition.createStateTransition(decision, "SWITCH", "step3"));
    transitions.add(StateTransition.createStateTransition(decision, "step2"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
    StepState step3 = new StepState(new StubStep("step3"));
    transitions.add(StateTransition.createStateTransition(step3, ExitStatus.FAILED.getExitCode(), "end2"));
    transitions.add(StateTransition.createStateTransition(step3, ExitStatus.COMPLETED.getExitCode(), "end3"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3")));
    flow.setStateTransitions(transitions);

    job.setFlow(flow);
    job.doExecute(jobExecution);

    StepExecution stepExecution = getStepExecution(jobExecution, "step3");
    if (!jobExecution.getAllFailureExceptions().isEmpty()) {
      throw jobExecution.getAllFailureExceptions().get(0);
    }

    assertEquals(BatchStatus.COMPLETED, stepExecution.getStatus());
    assertEquals(3, jobExecution.getStepExecutions().size());

  }

  @Test
  public void testDecisionFlowWithExceptionInDecider() throws Throwable {

    SimpleFlow flow = new JsrFlow("job");
    JobExecutionDecider decider = new JobExecutionDecider() {
      @Override
      public FlowExecutionStatus decide(JobExecution jobExecution, StepExecution stepExecution) {
        assertNotNull(stepExecution);
        throw new RuntimeException("Foo");
      }
    };

    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "decision"));
    DecisionState decision = new DecisionState(decider, "decision");
    transitions.add(StateTransition.createStateTransition(decision, "step2"));
    transitions.add(StateTransition.createStateTransition(decision, "SWITCH", "step3"));
    StepState step2 = new StepState(new StubStep("step2"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.COMPLETED.getExitCode(), "end0"));
    transitions.add(StateTransition.createStateTransition(step2, ExitStatus.FAILED.getExitCode(), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end1")));
    StepState step3 = new StepState(new StubStep("step3"));
    transitions.add(StateTransition.createStateTransition(step3, ExitStatus.FAILED.getExitCode(), "end2"));
    transitions.add(StateTransition.createStateTransition(step3, ExitStatus.COMPLETED.getExitCode(), "end3"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.FAILED, "end2")));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end3")));
    flow.setStateTransitions(transitions);

    job.setFlow(flow);
    try {
      job.execute(jobExecution);
    }
    finally {

      assertEquals(BatchStatus.FAILED, jobExecution.getStatus());
      assertEquals(1, jobExecution.getStepExecutions().size());

      assertEquals(1, jobExecution.getAllFailureExceptions().size());
      assertEquals("Foo", jobExecution.getAllFailureExceptions().get(0).getCause().getCause().getMessage());

    }
  }

  @Test
  public void testGetStepExists() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();

    Step step = job.getStep("step2");
    assertNotNull(step);
    assertEquals("step2", step.getName());
  }

  @Test
  public void testGetStepExistsWithPrefix() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState("job.step", new StubStep("step")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.setName(flow.getName());
    job.afterPropertiesSet();

    Step step = job.getStep("step");
    assertNotNull(step);
    assertEquals("step", step.getName());
  }

  @Test
  public void testGetStepNamesWithPrefix() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState("job.step", new StubStep("step")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.setName(flow.getName());
    job.afterPropertiesSet();

    assertEquals("[step]", job.getStepNames().toString());
  }

  @Test
  public void testGetStepNotExists() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();

    Step step = job.getStep("foo");
    assertNull(step);
  }

  @Test
  public void testGetStepNotStepState() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "step2"));
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();

    Step step = job.getStep("end0");
    assertNull(step);
  }

  @Test
  public void testGetStepNestedFlow() throws Exception {
    SimpleFlow nested = new JsrFlow("nested");
    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    nested.setStateTransitions(transitions);
    nested.afterPropertiesSet();

    SimpleFlow flow = new JsrFlow("job");
    transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "nested"));
    transitions.add(StateTransition.createStateTransition(new FlowState(nested, "nested"), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();
    job.setFlow(flow);
    job.afterPropertiesSet();

    List<String> names = new ArrayList<String>(job.getStepNames());
    Collections.sort(names);
    assertEquals("[step1, step2]", names.toString());
  }

  @Test
  public void testGetStepSplitFlow() throws Exception {
    SimpleFlow flow = new JsrFlow("job");
    SimpleFlow flow1 = new JsrFlow("flow1");
    SimpleFlow flow2 = new JsrFlow("flow2");

    List<StateTransition> transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step1")), "end0"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end0")));
    flow1.setStateTransitions(new ArrayList<StateTransition>(transitions));
    flow1.afterPropertiesSet();
    transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new StepState(new StubStep("step2")), "end1"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end1")));
    flow2.setStateTransitions(new ArrayList<StateTransition>(transitions));
    flow2.afterPropertiesSet();

    transitions = new ArrayList<StateTransition>();
    transitions.add(StateTransition.createStateTransition(new SplitState(Arrays.<Flow> asList(flow1, flow2),
        "split"), "end2"));
    transitions.add(StateTransition.createEndStateTransition(new EndState(FlowExecutionStatus.COMPLETED, "end2")));
    flow.setStateTransitions(transitions);
    flow.afterPropertiesSet();

    job.setFlow(flow);
    job.afterPropertiesSet();
    List<String> names = new ArrayList<String>(job.getStepNames());
    Collections.sort(names);
    assertEquals("[step1, step2]", names.toString());
  }

  /**
   * @author Dave Syer
   *
   */
  private class StubStep extends StepSupport {

    private StubStep(String name) {
      super(name);
    }

    @Override
    public void execute(StepExecution stepExecution) throws JobInterruptedException {
      stepExecution.setStatus(BatchStatus.COMPLETED);
      stepExecution.setExitStatus(ExitStatus.COMPLETED);
      jobRepository.update(stepExecution);
    }

  }

  /**
   * @author Michael Minella
   *
   */
  private class StubDecisionStep extends StepSupport {

    private Decider decider;

    private StubDecisionStep(String name, Decider decider) {
      super(name);
      this.decider = decider;
    }

    @Override
    public void execute(StepExecution stepExecution) throws JobInterruptedException {
      stepExecution.setStatus(BatchStatus.COMPLETED);
      try {
        stepExecution.setExitStatus(new ExitStatus(decider.decide(new javax.batch.runtime.StepExecution [] {new JsrStepExecution(stepExecution)})));
      } catch (Exception e) {
        throw new RuntimeException(e);
      }

      jobRepository.update(stepExecution);
    }
  }

  /**
   * @param jobExecution
   * @param stepName
   * @return the StepExecution corresponding to the specified step
   */
  private StepExecution getStepExecution(JobExecution jobExecution, String stepName) {
    for (StepExecution stepExecution : jobExecution.getStepExecutions()) {
      if (stepExecution.getStepName().equals(stepName)) {
        return stepExecution;
      }
    }
    fail("No stepExecution found with name: [" + stepName + "]");
    return null;
  }

  private void checkRepository(BatchStatus status, ExitStatus exitStatus) {
    // because map DAO stores in memory, it can be checked directly
    JobInstance jobInstance = jobExecution.getJobInstance();
    JobExecution other = jobExecutionDao.findJobExecutions(jobInstance).get(0);
    assertEquals(jobInstance.getId(), other.getJobId());
    assertEquals(status, other.getStatus());
    if (exitStatus != null) {
      assertEquals(exitStatus.getExitCode(), other.getExitStatus().getExitCode());
    }
  }

}
TOP

Related Classes of org.springframework.batch.core.jsr.job.flow.JsrFlowJobTests

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.