Polish
This commit is contained in:
@@ -43,7 +43,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(name = "spring.cloud.task.batch.fail-on-job-failure", havingValue = "true", matchIfMissing = false)
|
||||
@ConditionalOnProperty(name = "spring.cloud.task.batch.fail-on-job-failure", havingValue = "true")
|
||||
@EnableConfigurationProperties(TaskBatchProperties.class)
|
||||
@AutoConfigureBefore(BatchAutoConfiguration.class)
|
||||
public class TaskJobLauncherAutoConfiguration {
|
||||
@@ -51,15 +51,6 @@ public class TaskJobLauncherAutoConfiguration {
|
||||
@Autowired
|
||||
private TaskBatchProperties properties;
|
||||
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(JobRepository.class)
|
||||
public JobRepository jobRepository(DataSource dataSource) throws Exception{
|
||||
JobRepositoryFactoryBean factoryBean = new JobRepositoryFactoryBean();
|
||||
factoryBean.setDataSource(dataSource);
|
||||
return factoryBean.getObject();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(JobLauncher jobLauncher,
|
||||
JobExplorer jobExplorer, List<Job> jobs, JobRegistry jobRegistry, JobRepository jobRepository) {
|
||||
|
||||
@@ -42,8 +42,6 @@ import org.springframework.batch.core.repository.JobExecutionAlreadyRunningExcep
|
||||
import org.springframework.batch.core.repository.JobInstanceAlreadyCompleteException;
|
||||
import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.batch.repeat.RepeatCallback;
|
||||
import org.springframework.batch.repeat.RepeatContext;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.batch.repeat.support.RepeatTemplate;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
@@ -113,7 +111,7 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
||||
public void run(String... args) throws JobExecutionException {
|
||||
logger.info("Running default command line with: " + Arrays.asList(args));
|
||||
launchJobFromProperties(StringUtils.splitArrayElementsIntoProperties(args, "="));
|
||||
validateJobExecutions();
|
||||
monitorJobExecutions();
|
||||
}
|
||||
|
||||
protected void execute(Job job, JobParameters jobParameters)
|
||||
@@ -161,69 +159,72 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
||||
}
|
||||
}
|
||||
|
||||
private void validateJobExecutions() {
|
||||
private void monitorJobExecutions() {
|
||||
RepeatTemplate template = new RepeatTemplate();
|
||||
|
||||
Date startDate = new Date();
|
||||
|
||||
template.iterate(new RepeatCallback() {
|
||||
template.iterate(context -> {
|
||||
|
||||
public RepeatStatus doInIteration(RepeatContext context) throws InterruptedException {
|
||||
List<JobExecution> failedJobExecutions = new ArrayList<>();
|
||||
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
|
||||
for (JobExecution jobExecution : jobExecutionList) {
|
||||
JobExecution currentJobExecution = taskJobExplorer.getJobExecution(jobExecution.getId());
|
||||
BatchStatus batchStatus = currentJobExecution.getStatus();
|
||||
if (batchStatus.isRunning()) {
|
||||
repeatStatus = RepeatStatus.CONTINUABLE;
|
||||
}
|
||||
if (batchStatus.equals(BatchStatus.FAILED)) {
|
||||
failedJobExecutions.add(jobExecution);
|
||||
}
|
||||
List<JobExecution> failedJobExecutions = new ArrayList<>();
|
||||
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
|
||||
for (JobExecution jobExecution : jobExecutionList) {
|
||||
JobExecution currentJobExecution = taskJobExplorer.getJobExecution(jobExecution.getId());
|
||||
BatchStatus batchStatus = currentJobExecution.getStatus();
|
||||
if (batchStatus.isRunning()) {
|
||||
repeatStatus = RepeatStatus.CONTINUABLE;
|
||||
}
|
||||
Thread.sleep(taskBatchProperties.getFailOnJobFailurePollInterval());
|
||||
|
||||
if (repeatStatus.equals(RepeatStatus.FINISHED) && failedJobExecutions.size() > 0) {
|
||||
throwJobFailedException(failedJobExecutions);
|
||||
if (batchStatus.equals(BatchStatus.FAILED)) {
|
||||
failedJobExecutions.add(jobExecution);
|
||||
}
|
||||
if (repeatStatus.isContinuable() && taskBatchProperties.getFailOnJobFailurewaitTime() != 0
|
||||
&& (new Date()).getTime() - startDate.getTime() > taskBatchProperties.getFailOnJobFailurewaitTime()) {
|
||||
throw new IllegalStateException("Not all jobs were completed " +
|
||||
"within the time specified by spring.cloud.task.batch." +
|
||||
"failOnJobFailurewaitTime.");
|
||||
}
|
||||
return repeatStatus;
|
||||
}
|
||||
Thread.sleep(taskBatchProperties.getFailOnJobFailurePollInterval());
|
||||
|
||||
if (repeatStatus.equals(RepeatStatus.FINISHED) && failedJobExecutions.size() > 0) {
|
||||
throwJobFailedException(failedJobExecutions);
|
||||
}
|
||||
if (repeatStatus.isContinuable() && taskBatchProperties.getFailOnJobFailurewaitTime() != 0
|
||||
&& (new Date()).getTime() - startDate.getTime() > taskBatchProperties.getFailOnJobFailurewaitTime()) {
|
||||
throw new IllegalStateException("Not all jobs were completed " +
|
||||
"within the time specified by spring.cloud.task.batch." +
|
||||
"failOnJobFailurewaitTime.");
|
||||
}
|
||||
return repeatStatus;
|
||||
});
|
||||
}
|
||||
|
||||
public void throwJobFailedException(List<JobExecution> failedJobExecutions) {
|
||||
String message = "The following Jobs have failed: \n";
|
||||
private void throwJobFailedException(List<JobExecution> failedJobExecutions) {
|
||||
StringBuilder message = new StringBuilder("The following Jobs have failed: \n");
|
||||
for (JobExecution failedJobExecution : failedJobExecutions) {
|
||||
message += String.format("Job %s failed during " +
|
||||
"execution for jobId %s with jobExecutionId of %s \n",
|
||||
message.append(String.format("Job %s failed during " +
|
||||
"execution for job instance id %s with jobExecutionId of %s \n",
|
||||
failedJobExecution.getJobInstance().getJobName(),
|
||||
failedJobExecution.getJobId(), failedJobExecution.getId());
|
||||
failedJobExecution.getJobId(), failedJobExecution.getId()));
|
||||
}
|
||||
|
||||
logger.error(message);
|
||||
throw new TaskException(message);
|
||||
|
||||
throw new TaskException(message.toString());
|
||||
|
||||
}
|
||||
private JobParameters removeNonIdentifying(JobParameters parameters) {
|
||||
Map<String, JobParameter> parameterMap = parameters.getParameters();
|
||||
HashMap<String, JobParameter> copy = new HashMap<>(parameterMap);
|
||||
|
||||
for (Map.Entry<String, JobParameter> parameter : copy.entrySet()) {
|
||||
if (!parameter.getValue().isIdentifying()) {
|
||||
parameterMap.remove(parameter.getKey());
|
||||
}
|
||||
}
|
||||
|
||||
return new JobParameters(parameterMap);
|
||||
}
|
||||
|
||||
private boolean isStoppedOrFailed(JobExecution execution) {
|
||||
BatchStatus status = execution.getStatus();
|
||||
return (status == BatchStatus.STOPPED || status == BatchStatus.FAILED);
|
||||
}
|
||||
|
||||
private JobParameters merge(JobParameters parameters, JobParameters additionals) {
|
||||
Map<String, JobParameter> merged = new HashMap<>();
|
||||
merged.putAll(parameters.getParameters());
|
||||
|
||||
@@ -42,6 +42,7 @@ import org.springframework.batch.core.repository.JobRepository;
|
||||
import org.springframework.batch.core.repository.JobRestartException;
|
||||
import org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean;
|
||||
import org.springframework.batch.core.step.tasklet.Tasklet;
|
||||
import org.springframework.batch.repeat.RepeatStatus;
|
||||
import org.springframework.batch.support.transaction.ResourcelessTransactionManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.task.batch.configuration.TaskBatchProperties;
|
||||
@@ -72,9 +73,6 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||
@Autowired
|
||||
private JobExplorer jobExplorer;
|
||||
|
||||
@Autowired
|
||||
private BatchConfiguration batchConfigurer;
|
||||
|
||||
@Autowired
|
||||
private PlatformTransactionManager transactionManager;
|
||||
|
||||
@@ -90,10 +88,9 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||
|
||||
@Before
|
||||
public void init() {
|
||||
batchConfigurer.clear();
|
||||
this.jobs = new JobBuilderFactory(this.jobRepository);
|
||||
this.steps = new StepBuilderFactory(this.jobRepository, this.transactionManager);
|
||||
Tasklet tasklet = (contribution, chunkContext) -> null;
|
||||
Tasklet tasklet = (contribution, chunkContext) -> RepeatStatus.FINISHED;
|
||||
this.step = this.steps.get("step").tasklet(tasklet).build();
|
||||
this.job = this.jobs.get("job").start(this.step).build();
|
||||
this.runner = new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer, jobRepository, new TaskBatchProperties());
|
||||
@@ -132,6 +129,7 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||
}
|
||||
|
||||
@DirtiesContext
|
||||
@Test
|
||||
public void runDifferentInstances() throws Exception {
|
||||
this.job = this.jobs.get("job")
|
||||
@@ -162,10 +160,8 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
|
||||
|
||||
// try to re-run a failed execution
|
||||
Executable executable = () -> {
|
||||
this.runner.execute(this.job,
|
||||
new JobParametersBuilder().addLong("run.id", 1L).toJobParameters());
|
||||
};
|
||||
Executable executable = () -> this.runner.execute(this.job,
|
||||
new JobParametersBuilder().addLong("run.id", 1L).toJobParameters());
|
||||
Throwable exception = assertThrows(JobRestartException.class, executable);
|
||||
AssertionsForClassTypes.assertThat(exception.getMessage())
|
||||
.isEqualTo("JobInstance already exists and is not restartable");
|
||||
@@ -187,6 +183,7 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||
}
|
||||
|
||||
|
||||
@DirtiesContext
|
||||
@Test
|
||||
public void retryFailedExecutionWithDifferentNonIdentifyingParametersFromPreviousExecution()
|
||||
throws Exception {
|
||||
@@ -254,10 +251,6 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||
this.jobRepository = this.jobRepositoryFactory.getObject();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
this.jobRepositoryFactory.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JobRepository getJobRepository() {
|
||||
return this.jobRepository;
|
||||
|
||||
@@ -70,7 +70,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
private static final String DEFAULT_ERROR_MESSAGE = "The following Jobs have failed: \n" +
|
||||
"Job jobA failed during execution for jobId 1 with jobExecutionId of 1 \n";
|
||||
"Job jobA failed during execution for job instance id 1 with jobExecutionId of 1 \n";
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
@@ -146,9 +146,8 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
||||
validateContext();
|
||||
assertThat(applicationContext.getBean(JobLauncherCommandLineRunner.class)).isNotNull();
|
||||
|
||||
Executable executable = () -> {
|
||||
applicationContext.getBean(TaskJobLauncherCommandLineRunner.class);
|
||||
};
|
||||
Executable executable = () -> applicationContext.getBean(TaskJobLauncherCommandLineRunner.class);
|
||||
|
||||
Throwable exception = assertThrows(NoSuchBeanDefinitionException.class, executable);
|
||||
assertThat(exception.getMessage()).isEqualTo("No qualifying bean of type " +
|
||||
"'org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner' available");
|
||||
@@ -168,9 +167,9 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
||||
}
|
||||
|
||||
private void validateForFail(String errorMessage, Class clazz, String [] enabledArgs) {
|
||||
Executable executable = () -> {
|
||||
this.applicationContext = SpringApplication
|
||||
.run(new Class[] { clazz,PropertyPlaceholderAutoConfiguration.class}, enabledArgs);};
|
||||
Executable executable = () -> this.applicationContext = SpringApplication
|
||||
.run(new Class[] { clazz,PropertyPlaceholderAutoConfiguration.class}, enabledArgs);
|
||||
|
||||
Throwable exception = assertThrows(IllegalStateException.class, executable);
|
||||
assertThat(exception.getCause().getMessage()).isEqualTo(errorMessage);
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class PrefixTests {
|
||||
@Test
|
||||
public void testPrefix() {
|
||||
this.applicationContext = SpringApplication.run(
|
||||
JobConfiguration.class, new String[] { "--spring.cloud.task.tablePrefix=FOO_" });
|
||||
JobConfiguration.class, "--spring.cloud.task.tablePrefix=FOO_");
|
||||
|
||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ import static org.junit.Assert.assertEquals;
|
||||
*/
|
||||
public class TaskBatchExecutionListenerTests {
|
||||
|
||||
public static final String[] ARGS = new String[] {};
|
||||
private static final String[] ARGS = new String[] {};
|
||||
|
||||
private ConfigurableApplicationContext applicationContext;
|
||||
|
||||
@@ -89,35 +89,35 @@ public class TaskBatchExecutionListenerTests {
|
||||
@Test(expected = AssertionError.class)
|
||||
public void testNoAutoConfigurationEnabled() {
|
||||
this.applicationContext = SpringApplication.run(JobConfiguration.class,
|
||||
new String[] {"--spring.cloud.task.batch.listener.enabled=false"});
|
||||
"--spring.cloud.task.batch.listener.enabled=false");
|
||||
validateContext();
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void testNoAutoConfigurationEnable() {
|
||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
||||
new String[] {"--spring.cloud.task.batch.listener.enable=false"});
|
||||
"--spring.cloud.task.batch.listener.enable=false");
|
||||
validateContext();
|
||||
}
|
||||
|
||||
@Test(expected = AssertionError.class)
|
||||
public void testNoAutoConfigurationBothDisabled() {
|
||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
||||
new String[] {"--spring.cloud.task.batch.listener.enable=false --spring.cloud.task.batch.listener.enabled=false"});
|
||||
"--spring.cloud.task.batch.listener.enable=false --spring.cloud.task.batch.listener.enabled=false");
|
||||
validateContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoConfigurationEnable() {
|
||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
||||
new String[] {"--spring.cloud.task.batch.listener.enable=true"});
|
||||
"--spring.cloud.task.batch.listener.enable=true");
|
||||
validateContext();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAutoConfigurationEnabled() {
|
||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
||||
new String[] {"--spring.cloud.task.batch.listener.enabled=true"});
|
||||
"--spring.cloud.task.batch.listener.enabled=true");
|
||||
validateContext();
|
||||
}
|
||||
|
||||
@@ -198,7 +198,7 @@ public class TaskBatchExecutionListenerTests {
|
||||
|
||||
@Test
|
||||
public void testBatchExecutionListenerBeanPostProcessorWithJobNames() {
|
||||
List jobNames = new ArrayList<String>(3);
|
||||
List<String> jobNames = new ArrayList<>(3);
|
||||
jobNames.add("job1");
|
||||
jobNames.add("job2");
|
||||
jobNames.add("TESTOBJECT");
|
||||
@@ -215,7 +215,7 @@ public class TaskBatchExecutionListenerTests {
|
||||
@Test
|
||||
public void testBatchExecutionListenerBeanPostProcessorWithEmptyJobNames() {
|
||||
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor =
|
||||
beanPostProcessor(Collections.<String>emptyList());
|
||||
beanPostProcessor(Collections.emptyList());
|
||||
|
||||
SimpleJob testObject = new SimpleJob();
|
||||
SimpleJob bean = (SimpleJob) beanPostProcessor.
|
||||
@@ -226,8 +226,7 @@ public class TaskBatchExecutionListenerTests {
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBatchExecutionListenerBeanPostProcessorNullJobNames() {
|
||||
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor =
|
||||
beanPostProcessor(null);
|
||||
beanPostProcessor(null);
|
||||
}
|
||||
|
||||
private TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor(
|
||||
|
||||
Reference in New Issue
Block a user