Resolve issues introduced by Boot 2.6.0.M1 upgrade

Updated versions and fixed jdbc test

Updated versions for samples
This commit is contained in:
Glenn Renfro
2021-07-23 08:51:14 -04:00
parent 723fa1353a
commit 78621e7b03
21 changed files with 45 additions and 408 deletions

View File

@@ -28,7 +28,6 @@ import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration;
import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
@@ -36,7 +35,7 @@ import org.springframework.context.annotation.Configuration;
/**
* Provides auto configuration for the
* {@link org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner}.
* {@link org.springframework.cloud.task.batch.handler.TaskJobLauncherApplicationRunner}.
*
* @author Glenn Renfro
*/
@@ -49,20 +48,6 @@ public class TaskJobLauncherAutoConfiguration {
@Autowired
private TaskBatchProperties properties;
@Bean
@ConditionalOnMissingClass("org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner")
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(
JobLauncher jobLauncher, JobExplorer jobExplorer, List<Job> jobs,
JobRegistry jobRegistry, JobRepository jobRepository,
BatchProperties batchProperties) {
TaskJobLauncherCommandLineRunnerFactoryBean taskJobLauncherCommandLineRunnerFactoryBean;
taskJobLauncherCommandLineRunnerFactoryBean = new TaskJobLauncherCommandLineRunnerFactoryBean(
jobLauncher, jobExplorer, jobs, this.properties, jobRegistry,
jobRepository, batchProperties);
return taskJobLauncherCommandLineRunnerFactoryBean;
}
@Bean
@ConditionalOnClass(
name = "org.springframework.boot.autoconfigure.batch.JobLauncherApplicationRunner")

View File

@@ -1,107 +0,0 @@
/*
* Copyright 2018-2020 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
*
* https://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.cloud.task.batch.configuration;
import java.util.List;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.configuration.JobRegistry;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.boot.autoconfigure.batch.BatchProperties;
import org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* Factory bean for creating an instance of {@link TaskJobLauncherCommandLineRunner}.
*
* @author Glenn Renfro
* @deprecated Use
* {@link org.springframework.cloud.task.batch.handler.TaskJobLauncherApplicationRunner}
*/
public class TaskJobLauncherCommandLineRunnerFactoryBean
implements FactoryBean<TaskJobLauncherCommandLineRunner> {
private JobLauncher jobLauncher;
private JobExplorer jobExplorer;
private List<Job> jobs;
private String jobNames;
private JobRegistry jobRegistry;
private Integer order = 0;
private TaskBatchProperties taskBatchProperties;
private JobRepository jobRepository;
public TaskJobLauncherCommandLineRunnerFactoryBean(JobLauncher jobLauncher,
JobExplorer jobExplorer, List<Job> jobs,
TaskBatchProperties taskBatchProperties, JobRegistry jobRegistry,
JobRepository jobRepository, BatchProperties batchProperties) {
Assert.notNull(taskBatchProperties, "taskBatchProperties must not be null");
Assert.notNull(batchProperties, "batchProperties must not be null");
this.jobLauncher = jobLauncher;
this.jobExplorer = jobExplorer;
Assert.notEmpty(jobs, "jobs must not be null nor empty");
this.jobs = jobs;
this.jobNames = taskBatchProperties.getJobNames();
this.jobRegistry = jobRegistry;
this.taskBatchProperties = taskBatchProperties;
if (StringUtils.hasText(batchProperties.getJob().getNames())) {
this.jobNames = batchProperties.getJob().getNames();
}
else {
this.jobNames = taskBatchProperties.getJobNames();
}
this.order = taskBatchProperties.getCommandLineRunnerOrder();
this.jobRepository = jobRepository;
}
public void setOrder(int order) {
this.order = order;
}
@Override
public TaskJobLauncherCommandLineRunner getObject() {
TaskJobLauncherCommandLineRunner taskJobLauncherCommandLineRunner = new TaskJobLauncherCommandLineRunner(
this.jobLauncher, this.jobExplorer, this.jobRepository,
this.taskBatchProperties);
taskJobLauncherCommandLineRunner.setJobs(this.jobs);
if (StringUtils.hasText(this.jobNames)) {
taskJobLauncherCommandLineRunner.setJobNames(this.jobNames);
}
taskJobLauncherCommandLineRunner.setJobRegistry(this.jobRegistry);
if (this.order != null) {
taskJobLauncherCommandLineRunner.setOrder(this.order);
}
return taskJobLauncherCommandLineRunner;
}
@Override
public Class<?> getObjectType() {
return TaskJobLauncherCommandLineRunner.class;
}
}

View File

@@ -1,236 +0,0 @@
/*
* Copyright 2018-2020 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
*
* https://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.cloud.task.batch.handler;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.BatchStatus;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.JobExecutionException;
import org.springframework.batch.core.JobParameter;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.JobParametersIncrementer;
import org.springframework.batch.core.JobParametersInvalidException;
import org.springframework.batch.core.explore.JobExplorer;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.batch.core.repository.JobExecutionAlreadyRunningException;
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.RepeatStatus;
import org.springframework.batch.repeat.support.RepeatTemplate;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.autoconfigure.batch.JobExecutionEvent;
import org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner;
import org.springframework.cloud.task.batch.configuration.TaskBatchProperties;
import org.springframework.cloud.task.listener.TaskException;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.core.task.TaskExecutor;
import org.springframework.util.StringUtils;
/**
* {@link CommandLineRunner} to {@link JobLauncher launch} Spring Batch jobs. Runs all
* jobs in the surrounding context by default and throws an exception upon the first job
* that returns an {@link BatchStatus} of FAILED if a {@link TaskExecutor} in the
* {@link JobLauncher} is not specified. If a {@link TaskExecutor} is specified in the
* {@link JobLauncher} then all Jobs are launched and an exception is thrown if one or
* more of the jobs has an {@link BatchStatus} of FAILED. TaskJobLauncherCommandLineRunner
* can also be used to launch a specific job by providing a jobName. The
* TaskJobLaunchercommandLineRunner takes the place of the
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner} when
* it is in use.
*
* @author Glenn Renfro
* @since 2.0.0
* @deprecated Use {@link TaskJobLauncherApplicationRunner}
*/
public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunner {
private static final Log logger = LogFactory
.getLog(TaskJobLauncherCommandLineRunner.class);
private JobLauncher taskJobLauncher;
private JobExplorer taskJobExplorer;
private JobRepository taskJobRepository;
private List<JobExecution> jobExecutionList = new ArrayList<>();
private ApplicationEventPublisher taskApplicationEventPublisher;
private TaskBatchProperties taskBatchProperties;
/**
* Create a new {@link TaskJobLauncherCommandLineRunner}.
* @param jobLauncher to launch jobs
* @param jobExplorer to check the job repository for previous executions
* @param jobRepository to check if a job instance exists with the given parameters
* when running a job
* @param taskBatchProperties the properties used to configure the
* taskBatchProperties.
*/
public TaskJobLauncherCommandLineRunner(JobLauncher jobLauncher,
JobExplorer jobExplorer, JobRepository jobRepository,
TaskBatchProperties taskBatchProperties) {
super(jobLauncher, jobExplorer, jobRepository);
this.taskJobLauncher = jobLauncher;
this.taskJobExplorer = jobExplorer;
this.taskJobRepository = jobRepository;
this.taskBatchProperties = taskBatchProperties;
}
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
super.setApplicationEventPublisher(publisher);
this.taskApplicationEventPublisher = publisher;
}
@Override
public void run(String... args) throws JobExecutionException {
logger.info("Running default command line with: " + Arrays.asList(args));
launchJobFromProperties(StringUtils.splitArrayElementsIntoProperties(args, "="));
monitorJobExecutions();
}
protected void execute(Job job, JobParameters jobParameters)
throws JobExecutionAlreadyRunningException, JobRestartException,
JobInstanceAlreadyCompleteException, JobParametersInvalidException {
String jobName = job.getName();
JobParameters parameters = jobParameters;
boolean jobInstanceExists = this.taskJobRepository.isJobInstanceExists(jobName,
parameters);
if (jobInstanceExists) {
JobExecution lastJobExecution = this.taskJobRepository
.getLastJobExecution(jobName, jobParameters);
if (lastJobExecution != null && isStoppedOrFailed(lastJobExecution)
&& job.isRestartable()) {
// Retry a failed or stopped execution with previous parameters
JobParameters previousParameters = lastJobExecution.getJobParameters();
/*
* remove Non-identifying parameters from the previous execution's
* parameters since there is no way to remove them programmatically. If
* they are required (or need to be modified) on a restart, they need to
* be (re)specified.
*/
JobParameters previousIdentifyingParameters = removeNonIdentifying(
previousParameters);
// merge additional parameters with previous ones (overriding those with
// the same key)
parameters = merge(previousIdentifyingParameters, jobParameters);
}
}
else {
JobParametersIncrementer incrementer = job.getJobParametersIncrementer();
if (incrementer != null) {
JobParameters nextParameters = new JobParametersBuilder(jobParameters,
this.taskJobExplorer).getNextJobParameters(job).toJobParameters();
parameters = merge(nextParameters, jobParameters);
}
}
JobExecution execution = this.taskJobLauncher.run(job, parameters);
if (this.taskApplicationEventPublisher != null) {
this.taskApplicationEventPublisher
.publishEvent(new JobExecutionEvent(execution));
}
this.jobExecutionList.add(execution);
if (execution.getStatus().equals(BatchStatus.FAILED)) {
throwJobFailedException(Collections.singletonList(execution));
}
}
private void monitorJobExecutions() {
RepeatTemplate template = new RepeatTemplate();
Date startDate = new Date();
template.iterate(context -> {
List<JobExecution> failedJobExecutions = new ArrayList<>();
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
for (JobExecution jobExecution : this.jobExecutionList) {
JobExecution currentJobExecution = this.taskJobExplorer
.getJobExecution(jobExecution.getId());
BatchStatus batchStatus = currentJobExecution.getStatus();
if (batchStatus.isRunning()) {
repeatStatus = RepeatStatus.CONTINUABLE;
}
if (batchStatus.equals(BatchStatus.FAILED)) {
failedJobExecutions.add(jobExecution);
}
}
Thread.sleep(this.taskBatchProperties.getFailOnJobFailurePollInterval());
if (repeatStatus.equals(RepeatStatus.FINISHED)
&& failedJobExecutions.size() > 0) {
throwJobFailedException(failedJobExecutions);
}
return repeatStatus;
});
}
private void throwJobFailedException(List<JobExecution> failedJobExecutions) {
StringBuilder message = new StringBuilder("The following Jobs have failed: \n");
for (JobExecution failedJobExecution : failedJobExecutions) {
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()));
}
logger.error(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());
merged.putAll(additionals.getParameters());
return new JobParameters(merged);
}
}

View File

@@ -26,7 +26,6 @@ import org.springframework.boot.autoconfigure.jdbc.EmbeddedDataSourceConfigurati
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.task.batch.handler.TaskJobLauncherApplicationRunner;
import org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner;
import org.springframework.cloud.task.batch.listener.TaskBatchExecutionListenerTests;
import org.springframework.test.util.ReflectionTestUtils;
@@ -102,7 +101,7 @@ public class TaskJobLauncherAutoConfigurationTests {
public void testAutoBuiltDataSourceWithTaskJobLauncherCLRDisabled() {
this.contextRunner.run(context -> {
assertThat(context).hasSingleBean(JobLauncherApplicationRunner.class);
assertThat(context).doesNotHaveBean(TaskJobLauncherCommandLineRunner.class);
assertThat(context).doesNotHaveBean(TaskJobLauncherApplicationRunner.class);
});
}

View File

@@ -60,8 +60,8 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
*/
@ExtendWith(SpringExtension.class)
@ContextConfiguration(
classes = { TaskJobLauncherCommandLineRunnerCoreTests.BatchConfiguration.class })
public class TaskJobLauncherCommandLineRunnerCoreTests {
classes = { TaskJobLauncherApplicationRunnerCoreTests.BatchConfiguration.class })
public class TaskJobLauncherApplicationRunnerCoreTests {
@Autowired
private JobRepository jobRepository;
@@ -75,7 +75,7 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
@Autowired
private PlatformTransactionManager transactionManager;
private TaskJobLauncherCommandLineRunner runner;
private TaskJobLauncherApplicationRunner runner;
private JobBuilderFactory jobs;
@@ -92,7 +92,7 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
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.runner = new TaskJobLauncherApplicationRunner(this.jobLauncher,
this.jobExplorer, this.jobRepository, new TaskBatchProperties());
}

View File

@@ -67,7 +67,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Glenn Renfro
*/
public class TaskJobLauncherCommandLineRunnerTests {
public class TaskJobLauncherApplicationRunnerTests {
private static final String DEFAULT_ERROR_MESSAGE = "The following Jobs have failed: \n"
+ "Job jobA failed during execution for job instance id 1 with jobExecutionId of 1 \n";
@@ -86,7 +86,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.failOnJobFailure=true" };
validateForFail(DEFAULT_ERROR_MESSAGE,
TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class,
TaskJobLauncherApplicationRunnerTests.JobWithFailureConfiguration.class,
enabledArgs);
}
@@ -99,7 +99,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
String[] enabledArgs = new String[] {
"--spring.cloud.task.batch.failOnJobFailure=true" };
validateForFail(DEFAULT_ERROR_MESSAGE,
TaskJobLauncherCommandLineRunnerTests.JobWithFailureAnnotatedConfiguration.class,
TaskJobLauncherApplicationRunnerTests.JobWithFailureAnnotatedConfiguration.class,
enabledArgs);
}
@@ -109,7 +109,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
"--spring.cloud.task.batch.failOnJobFailure=true",
"--spring.cloud.task.batch.failOnJobFailurePollInterval=500" };
validateForFail(DEFAULT_ERROR_MESSAGE,
TaskJobLauncherCommandLineRunnerTests.JobWithFailureTaskExecutorConfiguration.class,
TaskJobLauncherApplicationRunnerTests.JobWithFailureTaskExecutorConfiguration.class,
enabledArgs);
}
@@ -120,7 +120,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
"--spring.cloud.task.batch.failOnJobFailurePollInterval=500",
"--spring.batch.job.enabled=false" };
this.applicationContext = SpringApplication.run(new Class[] {
TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class },
TaskJobLauncherApplicationRunnerTests.JobWithFailureConfiguration.class },
enabledArgs);
JobExplorer jobExplorer = this.applicationContext.getBean(JobExplorer.class);
assertThat(jobExplorer.getJobNames().size()).isEqualTo(0);
@@ -134,7 +134,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
boolean isExceptionThrown = false;
try {
this.applicationContext = SpringApplication.run(new Class[] {
TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class },
TaskJobLauncherApplicationRunnerTests.JobWithFailureConfiguration.class },
enabledArgs);
}
catch (IllegalStateException exception) {
@@ -145,22 +145,22 @@ public class TaskJobLauncherCommandLineRunnerTests {
}
@Test
public void testCommandLineRunnerSetToFalse() {
public void testApplicationRunnerSetToFalse() {
String[] enabledArgs = new String[] {};
this.applicationContext = SpringApplication.run(
new Class[] {
TaskJobLauncherCommandLineRunnerTests.JobConfiguration.class },
TaskJobLauncherApplicationRunnerTests.JobConfiguration.class },
enabledArgs);
validateContext();
assertThat(this.applicationContext.getBean(JobLauncherApplicationRunner.class))
.isNotNull();
Executable executable = () -> this.applicationContext
.getBean(TaskJobLauncherCommandLineRunner.class);
.getBean(TaskJobLauncherApplicationRunner.class);
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
.isThrownBy(executable::execute).withMessage("No qualifying bean of type "
+ "'org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner' available");
+ "'org.springframework.cloud.task.batch.handler.TaskJobLauncherApplicationRunner' available");
validateContext();
}