/*
* Copyright (c) 2015 Red Hat, Inc. and/or its affiliates.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cheng Fang - Initial API and implementation
*/
package org.jberet.testapps.javajsl;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.IllegalFormatCodePointException;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import javax.batch.operations.BatchRuntimeException;
import javax.batch.runtime.BatchStatus;
import javax.batch.runtime.Metric;
import org.jberet.job.model.DecisionBuilder;
import org.jberet.job.model.FlowBuilder;
import org.jberet.job.model.Job;
import org.jberet.job.model.JobBuilder;
import org.jberet.job.model.SplitBuilder;
import org.jberet.job.model.StepBuilder;
import org.jberet.runtime.metric.StepMetrics;
import org.jberet.testapps.common.AbstractIT;
import org.junit.Assert;
import org.junit.Test;
public class JavaJSLIT extends AbstractIT {
static final String batchlet1Name = "batchlet1";
static final String deciderName = "decider2";
/**
* Creates a job with Java JSL:
* add 2 job properties;
* add 1 job listener that has 2 batch properties;
* add 1 step that has
* 2 step properties;
* 1 batchlet that has 2 batch properties;
* 1 step listener that has 2 batch properties;
* stop transition element;
* end transition element;
* fail transition element;
* next transition element;
* <p/>
* add another step that has
* 1 batchlet.
* <p/>
* Job or step properties can be set one by one, or set multiple properties together with either a series of String[]
* or java.util.Properties.
* <p/>
* Batch artifacts can be created along with its batch properties in the form of either a series of String[], or
* java.util.Properties. When using String[] to specify a property, the first element is key and the second element
* is its value.
*
* @throws Exception
*/
@Test
public void batchlet1() throws Exception {
final String jobName = "javaJSL-batchlet1";
final String stepName = jobName + ".step1";
final String step2Name = jobName + ".step2";
final Properties stepListenerProps = new Properties();
stepListenerProps.setProperty("stepListenerk1", "l");
stepListenerProps.setProperty("stepListenerk2", "l");
//used to test property resolution
params.setProperty("jobListenerPropVal", "L");
final Job job = new JobBuilder(jobName)
.restartable(false)
.property("jobk1", "J")
.property("jobk2", "J")
.listener("jobListener1", new String[]{"jobListenerk1", "#{jobParameters['jobListenerPropVal']}"},
new String[]{"jobListenerk2", "#{jobParameters['jobListenerPropVal']}"})
.step(new StepBuilder(stepName)
.properties(new String[]{"stepk1", "S"},
new String[]{"stepk2", "S"})
.batchlet(batchlet1Name, new String[]{"batchletk1", "B"},
new String[]{"batchletk2", "B"})
.listener("stepListener1", stepListenerProps)
.stopOn("STOP").restartFrom(stepName).exitStatus()
.endOn("END").exitStatus("new status for end")
.failOn("FAIL").exitStatus()
.nextOn("*").to(step2Name)
.build())
.step(new StepBuilder(step2Name)
.batchlet(batchlet1Name).build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
Assert.assertEquals("LL", jobExecution.getExitStatus());
Assert.assertEquals("JJSSBBll", stepExecution0.getExitStatus());
}
/**
* Runs a chunk step with item reader, processor, writer, chunk listener, and verifies the result step metrics.
* {@link ChunkListener1} sets the step exit status to {@code stepExitStatusExpected} in its {@code afterChunk}
* method, and expects the resulting step exit status to contain that string value.
* <p/>
* Note that {@link StepBuilder} does not have a chunk(...) method to match the XML i element.
* You just directly configure all chunk related attributes and sub-elements in {@code StepBuilder}.
*
* @throws Exception
*/
@Test
public void chunk1() throws Exception {
final String jobName = "javaJSL-chunk1";
final String stepName = jobName + ".step1";
final String stepExitStatusExpected = "stepExitStatusExpected";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "-1"}, new String[]{"writer.sleep.time", "0"})
.processor("integerProcessor")
.checkpointPolicy("item")
.listener("chunkListener1", new String[]{"stepExitStatus", stepExitStatusExpected})
.itemCount(10)
.allowStartIfComplete()
.startLimit(2)
.skipLimit(8)
.timeLimit(2, TimeUnit.MINUTES)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
System.out.printf("step exit status: %s%n", stepExecution0.getExitStatus());
Assert.assertEquals(true, stepExecution0.getExitStatus().contains(stepExitStatusExpected));
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(4, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Runs a job that contains step0 (does nothing), decision1 and a chunk step.
* The first run is expected to be stopped, and the restart should complete successfully.
*
* @throws Exception
*
* @see <a href="https://issues.jboss.org/browse/JBERET-184">JBERET-184</a>
*/
@Test
public void chunkRestartWithDecisionTest() throws Exception {
final String jobName = "javaJSL-chunkRestartWithDecisionTest";
final String step0Name = jobName + ".step0";
final String decisionName = jobName + "." + deciderName;
final String stepName = jobName + ".step1";
final String restartCompleted = "restartCompleted";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(step0Name)
.batchlet(batchlet1Name)
.next(decisionName)
.build())
.decision(new DecisionBuilder(decisionName, "decider2")
.nextOn("*").to(stepName)
.build())
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "#{jobParameters['fail.on.values']}"})
.startLimit(2)
.stopOn(BatchStatus.FAILED.name()).restartFrom(stepName).exitStatus()
.endOn(BatchStatus.COMPLETED.name()).exitStatus(restartCompleted) //new exit status for the job
.build())
.build();
params.setProperty("fail.on.values", "1");
startJobAndWait(job);
Assert.assertEquals(BatchStatus.STOPPED, jobExecution.getBatchStatus());
System.out.printf("Stopped job execution: %s, with exit status: %s%n", jobExecutionId, jobExecution.getExitStatus());
params.setProperty("fail.on.values", "-1");
restartAndWait();
if (stepExecutions.size() == 0) {
Assert.fail("No step executions in the restart job execution, which means the restart job execution did nothing.");
}
System.out.printf("Completed restart job execution: %s, with exit status: %s%n", jobExecutionId, jobExecution.getExitStatus());
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
Assert.assertEquals(restartCompleted, jobExecution.getExitStatus());
}
/**
* Runs a partitioned chunk step with item reader, processor, writer, and verifies the result step metrics.
* The partition is configured with a partition plan.
* <p/>
* Note that {@link StepBuilder} does not have a partition method matching the {@code partition} XML element.
* All partition configurations are specified directly under {@code StepBuilder}.
*
* @throws Exception
*/
@Test
public void chunkPartitionPlan() throws Exception {
final String jobName = "javaJSL-chunkPartition";
final String stepName = jobName + ".step1";
final int partitionCount = 3;
final List<Properties> listOfPartitionProps = new ArrayList<Properties>();
for (int i = 0; i < partitionCount; i++) {
listOfPartitionProps.add(new Properties());
}
listOfPartitionProps.get(0).put("partition.start", "0");
listOfPartitionProps.get(0).put("partition.end", "9");
listOfPartitionProps.get(1).put("partition.start", "10");
listOfPartitionProps.get(1).put("partition.end", "19");
listOfPartitionProps.get(2).put("partition.start", "20");
listOfPartitionProps.get(2).put("partition.end", "29");
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"},
new String[]{"partition.start", "#{partitionPlan['partition.start']}"},
new String[]{"partition.end", "#{partitionPlan['partition.end']}"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "-1"}, new String[]{"writer.sleep.time", "0"})
.partitionPlan(partitionCount, listOfPartitionProps)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(6, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Runs a partitioned chunk step with item reader, processor, writer, and verifies the result step metrics.
* The partition is configured with {@link PartitionMapper1}
*
* @throws Exception
*/
@Test
public void chunkPartitionMapper() throws Exception {
final String jobName = "javaJSL-chunkPartitionMapper";
final String stepName = jobName + ".step1";
final int partitionCount = 3;
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"},
new String[]{"partition.start", "#{partitionPlan['partition.start']}"},
new String[]{"partition.end", "#{partitionPlan['partition.end']}"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "-1"}, new String[]{"writer.sleep.time", "0"})
.partitionMapper("partitionMapper1", new String[]{"partitionCount", String.valueOf(partitionCount)})
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(6, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Runs a partitioned chunk step with item reader, processor, writer, partition collector, analyzer and reducer,
* and verifies the result step exit status.
*
* @throws Exception
*/
@Test
public void chunkPartitionCollectorAnalyzerReducer() throws Exception {
final String jobName = "javaJSL-chunkPartitionCollectorAnalyzerReducer";
final String stepName = jobName + ".step1";
final int partitionCount = 3;
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"},
new String[]{"partition.start", "#{partitionPlan['partition.start']}"},
new String[]{"partition.end", "#{partitionPlan['partition.end']}"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "-1"}, new String[]{"writer.sleep.time", "0"})
.partitionMapper("partitionMapper1", new String[]{"partitionCount", String.valueOf(partitionCount)})
.partitionCollector("partitionCollector1")
.partitionAnalyzer("partitionAnalyzer1")
.partitionReducer("partitionReducer1")
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
System.out.printf("step exit status: %s%n", stepExecution0.getExitStatus());
// collector * 2 chunk * 3 partitions + analyzer * 3 = 9
Assert.assertEquals("9", stepExecution0.getExitStatus());
}
/**
* Runs a chunk step with item reader, processor, writer, and skip-exception-classes,
* and verifies the result step metrics.
*
* @throws Exception
*/
@Test
public void skipExceptions() throws Exception {
final String jobName = "javaJSL-skipExceptions";
final String stepName = jobName + ".step1";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "29"}, new String[]{"writer.sleep.time", "0"})
.processor("integerProcessor")
.skippableExceptionsInclude(ArithmeticException.class, IllegalFormatCodePointException.class)
.skippableExceptionsExclude(IOException.class, FileNotFoundException.class)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(1, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(3, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(20, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Runs a chunk step with item reader, processor, writer, and retry-exception-classes,
* and verifies the result step metrics.
*
* @throws Exception
*/
@Test
public void retryExceptions() throws Exception {
final String jobName = "javaJSL-retryExceptions";
final String stepName = jobName + ".step1";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "29"}, new String[]{"writer.sleep.time", "0"})
.processor("integerProcessor")
.retryableExceptionsInclude(ArithmeticException.class, IllegalFormatCodePointException.class)
.retryableExceptionsExclude(IOException.class, FileNotFoundException.class)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(13, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(40, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(1, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Runs a chunk step with item reader, processor, writer, retry-exception-classes, and no-rollback-exception-classes
* and verifies the result step metrics.
*
* @throws Exception
*/
@Test
public void retryExceptionsAndNoRollbackExceptions() throws Exception {
final String jobName = "javaJSL-retryExceptionsAndNoRollbackExceptions";
final String stepName = jobName + ".step1";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "29"}, new String[]{"writer.sleep.time", "0"})
.processor("integerProcessor")
.retryableExceptionsInclude(ArithmeticException.class, IllegalFormatCodePointException.class)
.retryableExceptionsExclude(IOException.class, FileNotFoundException.class)
.noRollbackExceptionsInclude(ArithmeticException.class, IllegalStateException.class)
.noRollbackExceptionsExclude(IOException.class, FileNotFoundException.class)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(4, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Runs a chunk step with item reader, processor, writer, and verifies the result step metrics.
*
* @throws Exception
* @see {@link #chunk1()}
*/
@Test
public void checkpointAlgorithm() throws Exception {
final String jobName = "javaJSL-checkpointAlgorithm";
final String stepName = jobName + ".step1";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.reader("integerArrayReader", new String[]{"data.count", "30"})
.writer("integerArrayWriter", new String[]{"fail.on.values", "-1"}, new String[]{"writer.sleep.time", "0"})
.processor("integerProcessor")
.checkpointPolicy("custom")
.checkpointAlgorithm("checkpointAlgorithm1")
.startLimit(2)
.skipLimit(8)
.retryLimit(10)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
final Metric[] metrics = stepExecution0.getMetrics();
System.out.printf("metrics: %s%n", java.util.Arrays.asList(metrics));
final StepMetrics stepMetrics = stepExecution0.getStepMetrics();
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.WRITE_SKIP_COUNT));
Assert.assertEquals(31, stepMetrics.get(Metric.MetricType.COMMIT_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.READ_COUNT));
Assert.assertEquals(30, stepMetrics.get(Metric.MetricType.WRITE_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.READ_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.PROCESS_SKIP_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.ROLLBACK_COUNT));
Assert.assertEquals(0, stepMetrics.get(Metric.MetricType.FILTER_COUNT));
}
/**
* Builds a job consisting of 1 flow, which consists of 2 steps.
*
* @throws Exception
*/
@Test
public void flow1() throws Exception {
final String jobName = "javaJSL-flow1";
final String flowName = jobName + "flow1";
final String stepName = jobName + ".step1";
final String step2Name = jobName + ".step2";
final Job job = new JobBuilder(jobName)
.restartable()
.flow(new FlowBuilder(flowName)
.step(new StepBuilder(stepName).batchlet(batchlet1Name)
.next(step2Name)
.build())
.step(new StepBuilder(step2Name).batchlet(batchlet1Name)
.build())
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
Assert.assertEquals(2, stepExecutions.size());
Assert.assertEquals(stepName, stepExecution0.getStepName());
Assert.assertEquals(step2Name, stepExecutions.get(1).getStepName());
}
/**
* Builds a job consisting of 1 step and 1 decision.
*
* @throws Exception
*/
@Test
public void decision1() throws Exception {
final String jobName = "javaJSL-decision1";
final String stepName = jobName + ".step1";
final String decisionName = jobName + ".decision1";
final Job job = new JobBuilder(jobName)
.restartable(true)
.step(new StepBuilder(stepName).batchlet(batchlet1Name).next(decisionName)
.build())
.decision(new DecisionBuilder(decisionName, deciderName)
.failOn("FAIL").exitStatus()
.stopOn("STOP").restartFrom(stepName).exitStatus()
.nextOn("NEXT").to(stepName)
.endOn("*").exitStatus(stepName)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
Assert.assertEquals(1, stepExecutions.size());
Assert.assertEquals(stepName, stepExecution0.getStepName());
Assert.assertEquals(stepName, jobExecution.getExitStatus()); //set by the decision element endOn("*").exitStatus(...)
}
/**
* Builds a job consisting of 1 split and 1 step. The split consists of 2 flows, each of which consists of 1 step.
* Altogether 3 steps.
*
* @throws Exception
*/
@Test
public void split1() throws Exception {
final String jobName = "javaJSL-split1";
final String splitName = jobName + ".split1";
final String flowName = splitName + ".flow1";
final String flow2Name = splitName + ".flow2";
final String stepName = jobName + ".step1";
final String step2Name = jobName + ".step2";
final String step3Name = jobName + ".step3";
final Job job = new JobBuilder(jobName)
.split(new SplitBuilder(splitName)
.flow(new FlowBuilder(flowName)
.step(new StepBuilder(stepName).batchlet(batchlet1Name).build())
.build())
.flow(new FlowBuilder(flow2Name)
.step(new StepBuilder(step2Name).batchlet(batchlet1Name).build())
.build())
.next(step3Name)
.build())
.step(new StepBuilder(step3Name).batchlet(batchlet1Name)
.endOn("*").exitStatus(step3Name)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.COMPLETED, jobExecution.getBatchStatus());
Assert.assertEquals(3, stepExecutions.size());
//step1 and step2 execution order may be random, so stepExecution0 may point to step1 or step2
//Assert.assertEquals(stepName, stepExecution0.getStepName());
//Assert.assertEquals(step2Name, stepExecutions.get(1).getStepName());
Assert.assertEquals(step3Name, stepExecutions.get(2).getStepName());
}
@Test(expected = BatchRuntimeException.class)
public void duplicateStepId() throws Exception {
final String jobName = "javaJSL-duplicateStepId";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(jobName)
.batchlet(batchlet1Name)
.build())
.build();
startJob(job);
}
@Test(expected = BatchRuntimeException.class)
public void duplicateDecisionId() throws Exception {
final String jobName = "javaJSL-duplicateDecisionId";
final String stepName = jobName + ".step1";
final String decisionName = stepName;
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName)
.batchlet(batchlet1Name)
.next(decisionName)
.build())
.decision(new DecisionBuilder(decisionName, "decider2")
.endOn("*").exitStatus()
.build())
.build();
startJob(job);
}
@Test(expected = BatchRuntimeException.class)
public void duplicateFlowId() throws Exception {
final String jobName = "javaJSL-duplicateFlowId";
final String flowName = jobName + "flow1";
final String stepName = jobName + ".step1";
final String step2Name = jobName;
final Job job = new JobBuilder(jobName)
.flow(new FlowBuilder(flowName)
.step(new StepBuilder(stepName).batchlet(batchlet1Name)
.next(step2Name)
.build())
.step(new StepBuilder(step2Name).batchlet(batchlet1Name)
.build())
.build())
.build();
startJob(job);
}
@Test(expected = BatchRuntimeException.class)
public void duplicateSplitId() throws Exception {
final String jobName = "javaJSL-duplicateSplitId";
final String splitName = jobName + ".split1";
final String flowName = splitName + ".flow1";
final String flow2Name = splitName + ".flow2";
final String stepName = jobName + ".step1";
final String step2Name = jobName + ".step2";
final String step3Name = flowName;
final Job job = new JobBuilder(jobName)
.split(new SplitBuilder(splitName)
.flow(new FlowBuilder(flowName)
.step(new StepBuilder(stepName).batchlet(batchlet1Name).build())
.build())
.flow(new FlowBuilder(flow2Name)
.step(new StepBuilder(step2Name).batchlet(batchlet1Name).build())
.build())
.next(step3Name)
.build())
.step(new StepBuilder(step3Name).batchlet(batchlet1Name)
.endOn("*").exitStatus(step3Name)
.build())
.build();
startJob(job);
}
@Test
public void noClassDefFoundErrorFromBatchlet() throws Exception {
final String jobName = "javaJSL-noClassDefFoundErrorFromBatchlet";
final String stepName = jobName + ".step1";
final String batchletName = "batchletWithNoClassDefFoundError";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName).batchlet(batchletName).partitionPlan(2).build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.FAILED, stepExecution0.getBatchStatus());
Assert.assertEquals(BatchStatus.FAILED, jobExecution.getBatchStatus());
}
@Test
public void noClassDefFoundErrorFromItemReader() throws Exception {
final String jobName = "javaJSL-noClassDefFoundErrorFromItemReader";
final String stepName = jobName + ".step1";
final String itemReaderName = "itemReaderWithNoClassDefFoundError";
final String itemWriterName = "itemWriterWithNoClassDefFoundError";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName).reader(itemReaderName, new String[]{"throwError", "true"})
.writer(itemWriterName)
.partitionPlan(2).build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.FAILED, stepExecution0.getBatchStatus());
Assert.assertEquals(BatchStatus.FAILED, jobExecution.getBatchStatus());
}
@Test
public void noClassDefFoundErrorFromItemWriter() throws Exception {
final String jobName = "javaJSL-noClassDefFoundErrorFromItemWriter";
final String stepName = jobName + ".step1";
final String itemReaderName = "itemReaderWithNoClassDefFoundError";
final String itemWriterName = "itemWriterWithNoClassDefFoundError";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName).reader(itemReaderName)
.writer(itemWriterName, new String[]{"throwError", "true"})
.partitionPlan(2).build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.FAILED, stepExecution0.getBatchStatus());
Assert.assertEquals(BatchStatus.FAILED, jobExecution.getBatchStatus());
}
@Test
public void noClassDefFoundErrorFromItemProcessor() throws Exception {
final String jobName = "javaJSL-noClassDefFoundErrorFromItemProcessor";
final String stepName = jobName + ".step1";
final String itemReaderName = "itemReaderWithNoClassDefFoundError";
final String itemWriterName = "itemWriterWithNoClassDefFoundError";
final String itemProcessorName = "itemProcessorWithNoClassDefFoundError";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName).reader(itemReaderName).writer(itemWriterName)
.processor(itemProcessorName, new String[]{"throwError", "true"})
.partitionPlan(2).build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.FAILED, stepExecution0.getBatchStatus());
Assert.assertEquals(BatchStatus.FAILED, jobExecution.getBatchStatus());
}
@Test
public void noClassDefFoundErrorFromChunkListener() throws Exception {
final String jobName = "javaJSL-noClassDefFoundErrorFromChunkListener";
final String stepName = jobName + ".step1";
final String itemReaderName = "itemReaderWithNoClassDefFoundError";
final String itemWriterName = "itemWriterWithNoClassDefFoundError";
final String chunkListenerName = "chunkListenerWithNoClassDefFoundError";
final Job job = new JobBuilder(jobName)
.step(new StepBuilder(stepName).reader(itemReaderName).writer(itemWriterName)
.listener(chunkListenerName, new String[]{"throwError", "true"})
.partitionPlan(2)
.build())
.build();
startJobAndWait(job);
Assert.assertEquals(BatchStatus.FAILED, stepExecution0.getBatchStatus());
Assert.assertEquals(BatchStatus.FAILED, jobExecution.getBatchStatus());
}
}