@Test public void testInterrupted() throws Exception { taskletStep.setStepExecutionListeners(new StepExecutionListener[] {new InterruptionListener()}); taskletStep.execute(stepExecution); assertEquals(STOPPED, stepExecution.getStatus()); assertEquals(STOPPED.toString(), stepExecution.getExitStatus().getExitCode()); }
@Test public void testUnexpectedRollback() throws Exception { taskletStep.setTransactionManager( new ResourcelessTransactionManager() { @Override protected void doCommit(DefaultTransactionStatus status) throws TransactionException { super.doRollback(status); throw new UnexpectedRollbackException("bar"); } }); taskletStep.setTasklet( new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { attributes .getStepContext() .getStepExecution() .getExecutionContext() .putString("foo", "bar"); return RepeatStatus.FINISHED; } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("bar", e.getMessage()); assertEquals(0, stepExecution.getCommitCount()); assertEquals(1, stepExecution.getRollbackCount()); // Failed transaction counts as rollback assertEquals(0, stepExecution.getExecutionContext().size()); }
@Test public void testAfterStepFailureWhenTaskletSucceeds() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStepExecutionListeners( new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override public ExitStatus afterStep(StepExecution stepExecution) { throw exception; } } }); taskletStep.setTasklet( new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); taskletStep.execute(stepExecution); assertEquals(COMPLETED, stepExecution.getStatus()); assertFalse(stepExecution.getFailureExceptions().contains(exception)); assertEquals(3, jobRepository.getUpdateCount()); }
@Test public void testPropertyFileLoaderJob() { try { logger.debug("Begin Testing File Loader"); SimpleJobLauncher jobLauncher = new SimpleJobLauncher(); jobLauncher.setTaskExecutor(new SyncTaskExecutor()); jobLauncher.setJobRepository(jobRepository); jobLauncherTestUtils.setJobLauncher(jobLauncher); SimpleJob job = importProductsJob(); logJobDetails(job); jobLauncherTestUtils.setJob(job); JobExecution exec = jobLauncherTestUtils.launchJob(new JobParameters()); Collection<String> stepNames = job.getStepNames(); for (String stepName : stepNames) { TaskletStep step = (TaskletStep) job.getStep(stepName); step.setTransactionManager(transactionManager); } assertTrue("Steps MUST exist", stepNames != null); assertTrue("At least ONE step MUST exist", stepNames.size() > 0); Assert.assertTrue( "Product Repository MUST have records", jobRepository.isJobInstanceExists(job.getName(), new JobParameters())); logger.debug("Job Execution Status {}", exec.getExitStatus()); logJobRepository(exec); Assert.assertEquals(BatchStatus.COMPLETED, exec.getStatus()); } catch (Exception e) { logger.error(e.getMessage(), e); Assert.fail(e.getMessage()); } }
@Before public void init() { taskletStep = new TaskletStep(); taskletStep.setTasklet(new ExceptionTasklet()); jobRepository = new UpdateCountingJobRepository(); taskletStep.setJobRepository(jobRepository); taskletStep.setTransactionManager(new ResourcelessTransactionManager()); JobInstance jobInstance = new JobInstance(1L, new JobParameters(), "testJob"); JobExecution jobExecution = new JobExecution(jobInstance); stepExecution = new StepExecution("testStep", jobExecution); }
@Test public void testInterruptedWithCustomStatus() throws Exception { taskletStep.setTasklet( new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception { contribution.setExitStatus(new ExitStatus("FUNNY")); throw new JobInterruptedException("Planned"); } }); taskletStep.execute(stepExecution); assertEquals(STOPPED, stepExecution.getStatus()); assertEquals("FUNNY", stepExecution.getExitStatus().getExitCode()); }
@Test public void testApplicationException() throws Exception { taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertEquals(FAILED.toString(), stepExecution.getExitStatus().getExitCode()); }
@Test public void testRepositoryErrorOnFailure() throws Exception { taskletStep.setTasklet( new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { throw new RuntimeException("Tasklet exception"); } }); jobRepository.setFailOnUpdateExecutionContext(true); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("Expected exception in step execution context persistence", e.getMessage()); }
@Test public void testRepositoryErrorOnUpdateStepExecution() throws Exception { taskletStep.setTasklet( new Tasklet() { public RepeatStatus execute(StepContribution contribution, ChunkContext attributes) throws Exception { return RepeatStatus.FINISHED; } }); jobRepository.setFailOnUpdateStepExecution(1); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); Throwable e = stepExecution.getFailureExceptions().get(0); assertEquals("JobRepository failure forcing exit with unknown status", e.getMessage()); }
@Test public void testBeforeStepFailure() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStepExecutionListeners( new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override public void beforeStep(StepExecution stepExecution) { throw exception; } } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(exception)); assertEquals(2, jobRepository.getUpdateCount()); }
@Test public void testOpenFailure() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStreams( new ItemStream[] { new ItemStreamSupport() { @Override public void open(ExecutionContext executionContext) throws ItemStreamException { throw exception; } } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(exception)); assertEquals(2, jobRepository.getUpdateCount()); }
@Test /* * Exception in afterStep is ignored (only logged). */ public void testAfterStepFailureWhenTaskletFails() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setStepExecutionListeners( new StepExecutionListenerSupport[] { new StepExecutionListenerSupport() { @Override public ExitStatus afterStep(StepExecution stepExecution) { throw exception; } } }); taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); assertFalse(stepExecution.getFailureExceptions().contains(exception)); assertEquals(2, jobRepository.getUpdateCount()); }
@Test public void testUpdateError() throws Exception { final RuntimeException exception = new RuntimeException(); taskletStep.setJobRepository( new UpdateCountingJobRepository() { boolean firstCall = true; @Override public void update(StepExecution arg0) { if (firstCall) { firstCall = false; return; } throw exception; } }); taskletStep.execute(stepExecution); assertEquals(UNKNOWN, stepExecution.getStatus()); assertTrue(stepExecution.getFailureExceptions().contains(exception)); assertTrue(stepExecution.getFailureExceptions().contains(taskletException)); }
/** * Build the step from the components collected by the fluent setters. Delegates first to {@link * #enhance(Step)} and then to {@link #createTasklet()} in subclasses to create the actual * tasklet. * * @return a tasklet step fully configured and read to execute */ public TaskletStep build() { registerStepListenerAsChunkListener(); TaskletStep step = new TaskletStep(getName()); super.enhance(step); step.setChunkListeners(chunkListeners.toArray(new ChunkListener[0])); if (transactionAttribute != null) { step.setTransactionAttribute(transactionAttribute); } if (stepOperations == null) { stepOperations = new RepeatTemplate(); if (taskExecutor != null) { TaskExecutorRepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); repeatTemplate.setTaskExecutor(taskExecutor); repeatTemplate.setThrottleLimit(throttleLimit); stepOperations = repeatTemplate; } ((RepeatTemplate) stepOperations).setExceptionHandler(exceptionHandler); } step.setStepOperations(stepOperations); step.setTasklet(createTasklet()); step.setStreams(streams.toArray(new ItemStream[0])); try { step.afterPropertiesSet(); } catch (Exception e) { throw new StepBuilderException(e); } return step; }
private SimpleJob importProductsJob() throws Exception { // Create Job SimpleJob bean = new SimpleJob(); bean.setName("importProductsJob"); bean.setJobRepository(jobRepository); bean.afterPropertiesSet(); // Create Steps List<Step> steps = new ArrayList<Step>(); // Create Tasklet Step TaskletStep step = new TaskletStep(); step.setName("importProducts"); step.setTransactionManager(transactionManager); step.setJobRepository(jobRepository); step.setStartLimit(100); // Create repeat template for Chunk Size RepeatTemplate repeatTemplate = new TaskExecutorRepeatTemplate(); repeatTemplate.setCompletionPolicy(new SimpleCompletionPolicy(5)); // TaskletStep <- RepeatTemplate step.setStepOperations(repeatTemplate); // Create Chunk Tasklet with Provider (reader) and Chunk Processor // Tasklet <- ChunkProvider <- ItemReader, RepeatTemplate // Tasklet <- ChunkProcessor <- ItemProcessor, ItemWriter ChunkOrientedTasklet<Product> tasklet = new ChunkOrientedTasklet<Product>( new SimpleChunkProvider<Product>(productReader(), repeatTemplate), new SimpleChunkProcessor<Product, Product>( new PassThroughItemProcessor<Product>(), new ProductItemLoggerWriter())); // Job <- Steps <- TaskletStep <- Tasklet step.setTasklet(tasklet); // Job <- Steps <- TaskletStep steps.add(step); // Job <- Steps bean.setSteps(steps); return bean; }
@Deprecated public void scheduleLoanArrearsAndPortfolioAtRisk( Date initialTime, long delay, JobRegistry jobRegistry, final JobRepository jobRepository, Map<String, Object> jobData, ResourcelessTransactionManager transactionManager) throws TaskSystemException { final String jobName = "LoanArrearsAndPortfolioAtRiskTask"; try { final TaskletStep step1 = new TaskletStep(); step1.setName("LoanArrearsAndPortfolioAtRiskTask-step-1"); step1.setTasklet( (Tasklet) Class.forName(BATCH_JOB_CLASS_PATH_PREFIX + getHelperName("LoanArrearsTask")) .newInstance()); step1.setJobRepository(jobRepository); step1.setTransactionManager(transactionManager); step1.afterPropertiesSet(); final TaskletStep step2 = new TaskletStep(); step2.setName("LoanArrearsAndPortfolioAtRiskTask-step-2"); step2.setTasklet( (Tasklet) Class.forName(BATCH_JOB_CLASS_PATH_PREFIX + getHelperName("PortfolioAtRiskTask")) .newInstance()); step2.setJobRepository(jobRepository); step2.setTransactionManager(transactionManager); step2.afterPropertiesSet(); jobRegistry.register( new JobFactory() { @Override public Job createJob() { SimpleJob job = new SimpleJob(jobName + "Job"); job.setJobRepository(jobRepository); job.setRestartable(true); job.registerJobExecutionListener(new BatchJobListener()); job.addStep(step1); job.addStep(step2); return job; } @Override public String getJobName() { return jobName + "Job"; } }); } catch (Exception e) { throw new TaskSystemException(e); } JobDetailBean jobDetailBean = new JobDetailBean(); jobDetailBean.setJobDataAsMap(jobData); try { jobDetailBean.setJobClass(Class.forName(BATCH_JOB_CLASS_PATH_PREFIX + "PortfolioAtRiskTask")); } catch (ClassNotFoundException cnfe) { throw new TaskSystemException(cnfe); } jobDetailBean.setName(jobName + "Job"); jobDetailBean.setGroup(Scheduler.DEFAULT_GROUP); jobDetailBean.afterPropertiesSet(); SimpleTrigger trigger = new SimpleTrigger(); trigger.setName(jobName + "Job"); trigger.setGroup(Scheduler.DEFAULT_GROUP); trigger.setStartTime(initialTime); trigger.setRepeatInterval(delay); trigger.setRepeatCount(SimpleTrigger.REPEAT_INDEFINITELY); try { scheduler.scheduleJob(jobDetailBean, trigger); } catch (SchedulerException se) { throw new TaskSystemException(se); } }