@Test public void testApplicationException() throws Exception { taskletStep.execute(stepExecution); assertEquals(FAILED, stepExecution.getStatus()); assertEquals(FAILED.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()); }
/** * @throws IOException if a temporary file cannot be created. * @throws NoSuchJobException if SpeciesPageHarvestingJob cannot be located * @throws JobParametersInvalidException if the job parameters are invalid * @throws JobInstanceAlreadyCompleteException if the job has already completed * @throws JobRestartException if the job cannot be restarted * @throws JobExecutionAlreadyRunningException if the job is already running */ @Test public final void testNotModifiedResponse() throws IOException, NoSuchJobException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException, JobParametersInvalidException { Map<String, JobParameter> parameters = new HashMap<String, JobParameter>(); parameters.put("query.string", new JobParameter("select i from Image i")); JobParameters jobParameters = new JobParameters(parameters); Job job = jobLocator.getJob("ImageProcessing"); assertNotNull("ImageProcessing must not be null", job); JobExecution jobExecution = jobLauncher.run(job, jobParameters); assertEquals( "The job should complete successfully", jobExecution.getExitStatus().getExitCode(), "COMPLETED"); for (StepExecution stepExecution : jobExecution.getStepExecutions()) { logger.info( stepExecution.getStepName() + " " + stepExecution.getReadCount() + " " + stepExecution.getFilterCount() + " " + stepExecution.getWriteCount()); } }
@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()); }
private void launchWorker(StepExecution workerStepExecution) { List<String> arguments = new ArrayList<>(); arguments.addAll(this.taskExecution.getArguments()); arguments.add( formatArgument( SPRING_CLOUD_TASK_JOB_EXECUTION_ID, String.valueOf(workerStepExecution.getJobExecution().getId()))); arguments.add( formatArgument( SPRING_CLOUD_TASK_STEP_EXECUTION_ID, String.valueOf(workerStepExecution.getId()))); arguments.add(formatArgument(SPRING_CLOUD_TASK_STEP_NAME, this.stepName)); Map<String, String> environmentProperties = new HashMap<>(this.environmentProperties.size()); environmentProperties.putAll(getCurrentEnvironmentProperties()); environmentProperties.putAll(this.environmentProperties); AppDefinition definition = new AppDefinition( String.format( "%s:%s:%s", taskExecution.getTaskName(), workerStepExecution.getJobExecution().getJobInstance().getJobName(), workerStepExecution.getStepName()), environmentProperties); AppDeploymentRequest request = new AppDeploymentRequest(definition, this.resource, this.deploymentProperties, arguments); taskLauncher.launch(request); }
@Before public void init() throws Exception { earlierExecution = MetaDataInstanceFactory.createJobExecutionWithStepExecutions(122L, Arrays.asList("step")); earlierExecution.setStatus(BatchStatus.FAILED); earlierExecution.setExitStatus(ExitStatus.FAILED); earlierExecution.setStartTime(new Date()); earlierExecution.setEndTime(new Date(earlierExecution.getStartTime().getTime() + 100)); assertFalse(earlierExecution.isRunning()); jobExecution = MetaDataInstanceFactory.createJobExecutionWithStepExecutions( 123L, Arrays.asList("first", "step")); jobExecution.setStatus(BatchStatus.COMPLETED); jobExecution.setExitStatus(ExitStatus.COMPLETED); jobExecution.setStartTime(new Date()); jobExecution.setEndTime(new Date(earlierExecution.getEndTime().getTime() + 100)); assertFalse(jobExecution.isRunning()); Iterator<StepExecution> iterator = jobExecution.getStepExecutions().iterator(); iterator.next(); StepExecution stepExecution = iterator.next(); stepExecution.setStatus(BatchStatus.COMPLETED); stepExecution.setExitStatus(ExitStatus.COMPLETED.addExitDescription("Foo")); metrics = new SimpleJobExecutionMetrics(jobService, "job"); }
@Override public JobExecutionInfoResource getSerializationValue() { JobInstance jobInstance = new JobInstance(1l, "job1"); JobExecution jobExecution = new JobExecution( jobInstance, 2l, new JobParametersBuilder() .addString("foo", "bar") .addDouble("baz", 3.0, false) .toJobParameters(), "configName.xml"); jobExecution.setVersion(1); jobExecution.setStatus(BatchStatus.STARTED); jobExecution.setCreateTime(new Date(0)); jobExecution.setStartTime(new Date(1000)); jobExecution.setLastUpdated(new Date(3000)); StepExecution stepExecution = new StepExecution("step1", jobExecution, 3l); stepExecution.setStatus(BatchStatus.STARTED); stepExecution.setStartTime(new Date(1000)); stepExecution.setLastUpdated(new Date(3000)); jobExecution.addStepExecutions(Arrays.asList(stepExecution)); JobExecutionInfoResource jobExecutionInfoResource = new JobExecutionInfoResource(jobExecution, TimeZone.getTimeZone("America/Chicago")); jobExecutionInfoResource.setStepExecutions( Arrays.asList( new StepExecutionInfoResource(stepExecution, TimeZone.getTimeZone("America/Chicago")))); return jobExecutionInfoResource; }
@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()); }
@Override public ExitStatus afterStep(StepExecution stepExecution) { if (!ExitStatus.FAILED.equals(stepExecution.getExitStatus()) && stepExecution.getSkipCount() > 0) { return new ExitStatus("COMPLETED WITH SKIPS"); } else { return stepExecution.getExitStatus(); } }
/** * Mock up the necessary job parameters * * @param outputFileName The filename we want the ItemWriter to write to */ private StepExecution getStepExecution(String outputFileName) throws IOException { JobParameters jobParams = mock(JobParameters.class); when(jobParams.getString("output.file")).thenReturn(outputFileName); StepExecution stepExecution = mock(StepExecution.class); when(stepExecution.getJobParameters()).thenReturn(jobParams); return stepExecution; }
@Test public void testSunnyDayFaultTolerant() throws Exception { JobExecution jobExecution = jobLauncher.run( job, new JobParameters(Collections.singletonMap("item.three", new JobParameter("3")))); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); StepExecution stepExecution = jobExecution.getStepExecutions().iterator().next(); assertEquals(9, stepExecution.getReadCount()); assertEquals(9, stepExecution.getWriteCount()); }
@Test @Ignore // FIXME public void testTransactionException() throws Exception { final SkipWriterStub<String> writer = new SkipWriterStub<String>(); FaultTolerantStepFactoryBean<String, String> factory = new FaultTolerantStepFactoryBean<String, String>(); factory.setItemWriter(writer); @SuppressWarnings("serial") DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(dataSource) { private boolean failed = false; @Override protected void doCommit(DefaultTransactionStatus status) throws TransactionException { if (writer.getWritten().isEmpty() || failed || !isExistingTransaction(status.getTransaction())) { super.doCommit(status); return; } failed = true; status.setRollbackOnly(); super.doRollback(status); throw new UnexpectedRollbackException("Planned"); } }; factory.setBeanName("stepName"); factory.setTransactionManager(transactionManager); factory.setCommitInterval(2); ItemReader<String> reader = new ListItemReader<String>(Arrays.asList("1", "2")); factory.setItemReader(reader); JobRepositoryFactoryBean repositoryFactory = new JobRepositoryFactoryBean(); repositoryFactory.setDataSource(dataSource); repositoryFactory.setTransactionManager(transactionManager); repositoryFactory.afterPropertiesSet(); JobRepository repository = repositoryFactory.getObject(); factory.setJobRepository(repository); JobExecution jobExecution = repository.createJobExecution("job", new JobParameters()); StepExecution stepExecution = jobExecution.createStepExecution(factory.getName()); repository.add(stepExecution); Step step = factory.getObject(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("[]", writer.getCommitted().toString()); }
@Test public void testFailedStepOnError() throws Exception { JobExecution jobExecution = jobLauncher.run( job, new JobParameters(Collections.singletonMap("item.three", new JobParameter("error")))); assertEquals(BatchStatus.FAILED, jobExecution.getStatus()); StepExecution stepExecution = jobExecution.getStepExecutions().iterator().next(); assertEquals(9, stepExecution.getReadCount()); // In principle the write count could be more than 2 and less than 9... assertEquals(7, stepExecution.getWriteCount()); }
public void alertEmail(StepExecution stepExecution) { try { String jobName = stepExecution.getJobExecution().getJobInstance().getJobName(); String jobInstanceId = "" + stepExecution.getJobExecution().getJobInstance().getId(); String jobExecutionId = "" + stepExecution.getJobExecution().getId(); String stepExecutionId = "" + stepExecution.getId(); SimpleMailMessage message = new SimpleMailMessage(this.templateMessage); message.setTo(emailTo); StringBuffer messageText = new StringBuffer(); messageText.append("\n\n"); messageText.append("This job fail: " + jobName + "\n"); messageText.append("\n\n"); messageText.append("## Job"); messageText.append("\n\n"); messageText.append("Name: " + jobName + ""); messageText.append("\n"); messageText.append("Id: " + jobInstanceId + ""); messageText.append("\n"); messageText.append("Job instance list url: " + urlPrefix + "jobs/" + jobName); messageText.append("\n\n"); messageText.append("## Job Execution"); messageText.append("\n\n"); messageText.append( "Job execution list url: " + urlPrefix + "jobs/" + jobName + "/" + jobInstanceId); messageText.append("\n\n"); messageText.append("## Step Error Details"); messageText.append("\n\n"); messageText.append( "Job execution url: " + urlPrefix + "jobs/executions/" + jobExecutionId + ""); messageText.append("\n\n"); messageText.append( "Job error details url: " + urlPrefix + "jobs/executions/" + jobExecutionId + "/steps/" + stepExecutionId + "/progress"); messageText.append("\n\n"); messageText.append("## Step Summary"); messageText.append("\n\n"); messageText.append("" + stepExecution.getSummary()); message.setText(messageText.toString()); this.mailSender.send(message); } catch (MailException e) { logger.error("erro with the email MailSender", e); } }
@Test public void testExecuteException() throws Exception { step.setJob( new JobSupport("child") { @Override public void execute(JobExecution execution) throws UnexpectedJobExecutionException { throw new RuntimeException("FOO"); } }); step.afterPropertiesSet(); step.execute(stepExecution); assertEquals(BatchStatus.FAILED, stepExecution.getStatus()); assertEquals("FOO", stepExecution.getFailureExceptions().get(0).getMessage()); }
@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 testSkipsInWriter() throws Exception { JobExecution jobExecution = jobLauncher.run( job, new JobParametersBuilder() .addString("item.three", "fail") .addLong("run.id", 1L) .toJobParameters()); assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus()); StepExecution stepExecution = jobExecution.getStepExecutions().iterator().next(); assertEquals(9, stepExecution.getReadCount()); assertEquals(7, stepExecution.getWriteCount()); // The whole chunk gets skipped... assertEquals(2, stepExecution.getWriteSkipCount()); }
@Test public void testNextStatus() { // Step 에서 Write 작업이 5번 일어났다면... stepExecution.setWriteCount(5); FlowExecutionStatus status = decider.decide(jobExecution, stepExecution); assertThat(status.getName()).isEqualTo("NEXT"); }
@Test public void testCompletedStatus() { // Step에서 Write 작업이 한번도 일어나지 않았다면... 더 이상 할 일이 없다... stepExecution.setWriteCount(0); FlowExecutionStatus status = decider.decide(jobExecution, stepExecution); assertThat(status).isEqualTo(FlowExecutionStatus.COMPLETED); }
public Collection<StepExecution> getStepExecutions(Long jobExecutionId) throws NoSuchJobExecutionException { JobExecution jobExecution = jobExecutionDao.getJobExecution(jobExecutionId); if (jobExecution == null) { throw new NoSuchJobExecutionException("No JobExecution with id=" + jobExecutionId); } stepExecutionDao.addStepExecutions(jobExecution); String jobName = jobExecution.getJobInstance() == null ? null : jobExecution.getJobInstance().getJobName(); Collection<String> missingStepNames = new LinkedHashSet<String>(); if (jobName != null) { missingStepNames.addAll( stepExecutionDao.findStepNamesForJobExecution(jobName, "*:partition*")); logger.debug("Found step executions in repository: " + missingStepNames); } Job job = null; try { job = jobLocator.getJob(jobName); } catch (NoSuchJobException e) { // expected } if (job instanceof StepLocator) { Collection<String> stepNames = ((StepLocator) job).getStepNames(); missingStepNames.addAll(stepNames); logger.debug("Added step executions from job: " + missingStepNames); } for (StepExecution stepExecution : jobExecution.getStepExecutions()) { String stepName = stepExecution.getStepName(); if (missingStepNames.contains(stepName)) { missingStepNames.remove(stepName); } logger.debug("Removed step executions from job execution: " + missingStepNames); } for (String stepName : missingStepNames) { StepExecution stepExecution = jobExecution.createStepExecution(stepName); stepExecution.setStatus(BatchStatus.UNKNOWN); } return jobExecution.getStepExecutions(); }
public Collection<String> getStepNamesForJob(String jobName) throws NoSuchJobException { try { Job job = jobLocator.getJob(jobName); if (job instanceof StepLocator) { return ((StepLocator) job).getStepNames(); } } catch (NoSuchJobException e) { // ignore } Collection<String> stepNames = new LinkedHashSet<String>(); for (JobExecution jobExecution : listJobExecutionsForJob(jobName, 0, 100)) { for (StepExecution stepExecution : jobExecution.getStepExecutions()) { stepNames.add(stepExecution.getStepName()); } } return Collections.unmodifiableList(new ArrayList<String>(stepNames)); }
@Test @SuppressWarnings({"unchecked", "rawtypes"}) public void testWrite() throws Exception { File file = new File(tmpDir, "foo.txt"); file.delete(); ByteArrayInputStream data = new ByteArrayInputStream("foobarbaz".getBytes()); Session session = mock(Session.class); SessionFactory factory = mock(SessionFactory.class); when(factory.getSession()).thenReturn(session); when(session.readRaw("foo.txt")).thenReturn(data); when(session.finalizeRaw()).thenReturn(true); StepExecution stepExecution = new StepExecution("foo", null); ExecutionContext stepExecutionContext = new ExecutionContext(); stepExecutionContext.putString("filePath", "foo.txt"); stepExecution.setExecutionContext(stepExecutionContext); StepContext stepContext = new StepContext(stepExecution); ChunkContext chunkContext = new ChunkContext(stepContext); RemoteFileTemplate template = new RemoteFileTemplate(factory); template.setBeanFactory(mock(BeanFactory.class)); template.afterPropertiesSet(); // clean up from old tests FileSystem fs = FileSystem.get(configuration); Path p = new Path("/qux/foo.txt"); fs.delete(p, true); assertFalse(fs.exists(p)); RemoteFileToHadoopTasklet tasklet = new RemoteFileToHadoopTasklet(template, configuration, "/qux"); assertEquals(RepeatStatus.FINISHED, tasklet.execute(null, chunkContext)); assertTrue(fs.exists(p)); FSDataInputStream stream = fs.open(p); byte[] out = new byte[9]; stream.readFully(out); stream.close(); assertEquals("foobarbaz", new String(out)); fs.close(); }
public void afterJob(JobExecution jobExecution) { StringBuilder protocol = new StringBuilder(); protocol.append("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); protocol.append("Protocol for " + jobExecution.getJobInstance().getJobName() + " \n"); protocol.append(" Started : " + jobExecution.getStartTime() + "\n"); protocol.append(" Finished : " + jobExecution.getEndTime() + "\n"); protocol.append(" Exit-Code : " + jobExecution.getExitStatus().getExitCode() + "\n"); protocol.append(" Exit-Descr. : " + jobExecution.getExitStatus().getExitDescription() + "\n"); protocol.append(" Status : " + jobExecution.getStatus() + "\n"); protocol.append("+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); protocol.append("Job-Parameter: \n"); JobParameters jp = jobExecution.getJobParameters(); for (Iterator<Entry<String, JobParameter>> iter = jp.getParameters().entrySet().iterator(); iter.hasNext(); ) { Entry<String, JobParameter> entry = iter.next(); protocol.append(" " + entry.getKey() + "=" + entry.getValue() + "\n"); } protocol.append("+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); for (StepExecution stepExecution : jobExecution.getStepExecutions()) { protocol.append("\n+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); protocol.append("Step " + stepExecution.getStepName() + " \n"); protocol.append("WriteCount: " + stepExecution.getWriteCount() + "\n"); protocol.append("Commits: " + stepExecution.getCommitCount() + "\n"); protocol.append("SkipCount: " + stepExecution.getSkipCount() + "\n"); protocol.append("Rollbacks: " + stepExecution.getRollbackCount() + "\n"); protocol.append("Filter: " + stepExecution.getFilterCount() + "\n"); protocol.append("+++++++++++++++++++++++++++++++++++++++++++++++++++++++ \n"); } LOGGER.info(protocol.toString()); }
@Test public void testDecisionUnmappedExitStatus() throws Exception { ApplicationContext context = new GenericXmlApplicationContext( "classpath:/org/springframework/batch/core/jsr/step/DecisionStepTests-decisionInvalidExitStatus-context.xml"); JobLauncher launcher = context.getBean(JobLauncher.class); Job job = context.getBean(Job.class); JobExecution execution = launcher.run(job, new JobParameters()); assertEquals(BatchStatus.COMPLETED, execution.getStatus()); assertEquals(2, execution.getStepExecutions().size()); for (org.springframework.batch.core.StepExecution curExecution : execution.getStepExecutions()) { assertEquals(BatchStatus.COMPLETED, curExecution.getStatus()); } }
@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()); }
public StepExecution getStepExecution(Long jobExecutionId, Long stepExecutionId) throws NoSuchJobExecutionException, NoSuchStepExecutionException { JobExecution jobExecution = getJobExecution(jobExecutionId); StepExecution stepExecution = stepExecutionDao.getStepExecution(jobExecution, stepExecutionId); if (stepExecution == null) { throw new NoSuchStepExecutionException( "There is no StepExecution with jobExecutionId=" + jobExecutionId + " and id=" + stepExecutionId); } try { stepExecution.setExecutionContext(executionContextDao.getExecutionContext(stepExecution)); } catch (Exception e) { logger.info("Cannot load execution context for step execution: " + stepExecution); } return stepExecution; }
@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()); }
public String getJobFailDescription(String jobName) { String failDescription = null; JobExplorer explorer = getBatchJobExplorer(); List<JobInstance> jobInstances = explorer.getJobInstances(jobName, 0, 1); if (jobInstances.size() > 0) { List<JobExecution> jobExecutions = explorer.getJobExecutions(jobInstances.get(0)); if (jobExecutions.size() > 0) { Collection<StepExecution> steps = jobExecutions.get(0).getStepExecutions(); if (steps.size() > 0) { StepExecution step = steps.iterator().next(); if (!step.getExitStatus().getExitDescription().isEmpty()) { failDescription = step.getExitStatus().getExitDescription(); } } } } return failDescription; }
@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()); }