Added checkstyle

This commit is contained in:
Marcin Grzejszczak
2019-02-03 19:27:07 +01:00
parent 4d0acf120c
commit 60f1e21d03
249 changed files with 7450 additions and 5857 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.configuration;
import org.springframework.batch.core.Job;
@@ -38,8 +39,9 @@ import org.springframework.context.annotation.Configuration;
* @author Michael Minella
*/
@Configuration
@ConditionalOnBean({Job.class})
@ConditionalOnProperty(name = {"spring.cloud.task.batch.listener.enable", "spring.cloud.task.batch.listener.enabled"}, havingValue = "true", matchIfMissing = true)
@ConditionalOnBean({ Job.class })
@ConditionalOnProperty(name = { "spring.cloud.task.batch.listener.enable",
"spring.cloud.task.batch.listener.enabled" }, havingValue = "true", matchIfMissing = true)
public class TaskBatchAutoConfiguration {
@Bean
@@ -48,6 +50,9 @@ public class TaskBatchAutoConfiguration {
return new TaskBatchExecutionListenerBeanPostProcessor();
}
/**
* Auto configuration for Task Batch Execution Listener.
*/
@Configuration
@ConditionalOnMissingBean(name = "taskBatchExecutionListener")
@EnableConfigurationProperties(TaskProperties.class)
@@ -60,20 +65,23 @@ public class TaskBatchAutoConfiguration {
private TaskProperties taskProperties;
@Bean
public TaskBatchExecutionListenerFactoryBean taskBatchExecutionListener(TaskExplorer taskExplorer) {
public TaskBatchExecutionListenerFactoryBean taskBatchExecutionListener(
TaskExplorer taskExplorer) {
TaskConfigurer taskConfigurer = null;
if(!this.context.getBeansOfType(TaskConfigurer.class).isEmpty()) {
if (!this.context.getBeansOfType(TaskConfigurer.class).isEmpty()) {
taskConfigurer = this.context.getBean(TaskConfigurer.class);
}
if(taskConfigurer != null && taskConfigurer.getTaskDataSource() != null) {
if (taskConfigurer != null && taskConfigurer.getTaskDataSource() != null) {
return new TaskBatchExecutionListenerFactoryBean(
taskConfigurer.getTaskDataSource(),
taskExplorer, taskProperties.getTablePrefix());
taskConfigurer.getTaskDataSource(), taskExplorer,
this.taskProperties.getTablePrefix());
}
else {
return new TaskBatchExecutionListenerFactoryBean(null,
taskExplorer, taskProperties.getTablePrefix());
return new TaskBatchExecutionListenerFactoryBean(null, taskExplorer,
this.taskProperties.getTablePrefix());
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.configuration;
import java.util.ArrayList;
@@ -28,7 +29,7 @@ import org.springframework.util.Assert;
/**
* Injects a configured {@link TaskBatchExecutionListener} into any batch jobs (beans
* assignable to {@link AbstractJob}) that are executed within the scope of a task. The
* assignable to {@link AbstractJob}) that are executed within the scope of a task. The
* context this is used within is expected to have only one bean of type
* {@link TaskBatchExecutionListener}.
*
@@ -50,17 +51,17 @@ public class TaskBatchExecutionListenerBeanPostProcessor implements BeanPostProc
@Override
public Object postProcessAfterInitialization(Object bean, String beanName)
throws BeansException {
if(jobNames.size() > 0 && !jobNames.contains(beanName)) {
return bean;
if (this.jobNames.size() > 0 && !this.jobNames.contains(beanName)) {
return bean;
}
int length = this.applicationContext
.getBeanNamesForType(TaskBatchExecutionListener.class).length;
if(bean instanceof AbstractJob) {
if(length != 1) {
throw new IllegalStateException("The application context is required to " +
"have exactly 1 instance of the TaskBatchExecutionListener but has " +
length);
if (bean instanceof AbstractJob) {
if (length != 1) {
throw new IllegalStateException("The application context is required to "
+ "have exactly 1 instance of the TaskBatchExecutionListener but has "
+ length);
}
((AbstractJob) bean).registerJobExecutionListener(
this.applicationContext.getBean(TaskBatchExecutionListener.class));
@@ -73,4 +74,5 @@ public class TaskBatchExecutionListenerBeanPostProcessor implements BeanPostProc
this.jobNames = jobNames;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,9 +13,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.configuration;
import java.lang.reflect.Field;
import javax.sql.DataSource;
import org.springframework.aop.framework.Advised;
@@ -32,13 +34,14 @@ import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
/**
* {@link FactoryBean} for a {@link TaskBatchExecutionListener}. Provides a jdbc based
* listener if there is a {@link DataSource} available. Otherwise, builds a listener that
* {@link FactoryBean} for a {@link TaskBatchExecutionListener}. Provides a jdbc based
* listener if there is a {@link DataSource} available. Otherwise, builds a listener that
* uses the map based implementation.
*
* @author Michael Minella
*/
public class TaskBatchExecutionListenerFactoryBean implements FactoryBean<TaskBatchExecutionListener> {
public class TaskBatchExecutionListenerFactoryBean
implements FactoryBean<TaskBatchExecutionListener> {
private TaskBatchExecutionListener listener;
@@ -49,45 +52,45 @@ public class TaskBatchExecutionListenerFactoryBean implements FactoryBean<TaskBa
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
/**
* Initializes the TaskBatchExecutionListenerFactoryBean and defaults the
* tablePrefix to {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
*
* Initializes the TaskBatchExecutionListenerFactoryBean and defaults the tablePrefix
* to {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
* @param dataSource the dataSource to use for the TaskBatchExecutionListener.
* @param taskExplorer the taskExplorer to use for the TaskBatchExecutionListener.
*/
public TaskBatchExecutionListenerFactoryBean(DataSource dataSource, TaskExplorer taskExplorer) {
public TaskBatchExecutionListenerFactoryBean(DataSource dataSource,
TaskExplorer taskExplorer) {
this.dataSource = dataSource;
this.taskExplorer = taskExplorer;
}
/**
* Initializes the TaskBatchExecutionListenerFactoryBean.
*
* @param dataSource the dataSource to use for the TaskBatchExecutionListener.
* @param taskExplorer the taskExplorer to use for the TaskBatchExecutionListener.
* @param tablePrefix the prefix for the task tables accessed by the
* TaskBatchExecutionListener.
*/
public TaskBatchExecutionListenerFactoryBean(DataSource dataSource, TaskExplorer taskExplorer, String tablePrefix) {
this(dataSource,taskExplorer);
public TaskBatchExecutionListenerFactoryBean(DataSource dataSource,
TaskExplorer taskExplorer, String tablePrefix) {
this(dataSource, taskExplorer);
Assert.hasText(tablePrefix, "tablePrefix must not be null nor empty.");
this.tablePrefix = tablePrefix;
}
@Override
public TaskBatchExecutionListener getObject() throws Exception {
if(listener != null){
return listener;
if (this.listener != null) {
return this.listener;
}
if(this.dataSource == null) {
if (this.dataSource == null) {
this.listener = new TaskBatchExecutionListener(getMapTaskBatchDao());
}
else {
this.listener = new TaskBatchExecutionListener(
new JdbcTaskBatchDao(this.dataSource, tablePrefix));
new JdbcTaskBatchDao(this.dataSource, this.tablePrefix));
}
return listener;
return this.listener;
}
@Override
@@ -101,22 +104,25 @@ public class TaskBatchExecutionListenerFactoryBean implements FactoryBean<TaskBa
}
private MapTaskBatchDao getMapTaskBatchDao() throws Exception {
Field taskExecutionDaoField = ReflectionUtils.findField(SimpleTaskExplorer.class, "taskExecutionDao");
Field taskExecutionDaoField = ReflectionUtils.findField(SimpleTaskExplorer.class,
"taskExecutionDao");
taskExecutionDaoField.setAccessible(true);
MapTaskExecutionDao taskExecutionDao;
if(AopUtils.isJdkDynamicProxy(this.taskExplorer)) {
SimpleTaskExplorer dereferencedTaskRepository = (SimpleTaskExplorer) ((Advised) this.taskExplorer).getTargetSource().getTarget();
if (AopUtils.isJdkDynamicProxy(this.taskExplorer)) {
SimpleTaskExplorer dereferencedTaskRepository = (SimpleTaskExplorer) ((Advised) this.taskExplorer)
.getTargetSource().getTarget();
taskExecutionDao =
(MapTaskExecutionDao) ReflectionUtils.getField(taskExecutionDaoField, dereferencedTaskRepository);
taskExecutionDao = (MapTaskExecutionDao) ReflectionUtils
.getField(taskExecutionDaoField, dereferencedTaskRepository);
}
else {
taskExecutionDao =
(MapTaskExecutionDao) ReflectionUtils.getField(taskExecutionDaoField, this.taskExplorer);
taskExecutionDao = (MapTaskExecutionDao) ReflectionUtils
.getField(taskExecutionDaoField, this.taskExplorer);
}
return new MapTaskBatchDao(taskExecutionDao.getBatchJobAssociations());
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 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
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://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.
* 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;
@@ -19,18 +19,17 @@ package org.springframework.cloud.task.batch.configuration;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Establish properties to be used for how Tasks work with
* Spring Batch.
* Establish properties to be used for how Tasks work with Spring Batch.
*
* @author Glenn Renfro
* @author Michael Minella
*
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "spring.cloud.task.batch")
public class TaskBatchProperties {
private static final long DEFAULT_POLL_INTERVAL = 5000L;
/**
* Comma-separated list of job names to execute on startup (for instance,
* `job1,job2`). By default, all Jobs found in the context are executed.
@@ -39,16 +38,16 @@ public class TaskBatchProperties {
/**
* The order for the {@code CommandLineRunner} used to run batch jobs when
* {@code spring.cloud.task.batch.fail-on-job-failure=true}. Defaults to 0 (same as the
* {@code spring.cloud.task.batch.fail-on-job-failure=true}. Defaults to 0 (same as
* the
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner}).
*/
private int commandLineRunnerOrder = 0;
/**
* Fixed delay in milliseconds that Spring Cloud Task will wait when checking if
* {@link org.springframework.batch.core.JobExecution}s have completed,
* when spring.cloud.task.batch.failOnJobFailure is set to true. Defaults
* to 5000.
* {@link org.springframework.batch.core.JobExecution}s have completed, when
* spring.cloud.task.batch.failOnJobFailure is set to true. Defaults to 5000.
*/
private long failOnJobFailurePollInterval = DEFAULT_POLL_INTERVAL;
@@ -61,7 +60,7 @@ public class TaskBatchProperties {
}
public int getCommandLineRunnerOrder() {
return commandLineRunnerOrder;
return this.commandLineRunnerOrder;
}
public void setCommandLineRunnerOrder(int commandLineRunnerOrder) {
@@ -69,10 +68,11 @@ public class TaskBatchProperties {
}
public long getFailOnJobFailurePollInterval() {
return failOnJobFailurePollInterval;
return this.failOnJobFailurePollInterval;
}
public void setFailOnJobFailurePollInterval(long failOnJobFailurePollInterval) {
this.failOnJobFailurePollInterval = failOnJobFailurePollInterval;
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 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
*
* http://www.apache.org/licenses/LICENSE-2.0
* Copyright 2015-2019 the original author or authors.
*
* 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.
* 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
*
* http://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;
@@ -47,16 +47,15 @@ public class TaskJobLauncherAutoConfiguration {
private TaskBatchProperties properties;
@Bean
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(JobLauncher jobLauncher,
JobExplorer jobExplorer, List<Job> jobs, JobRegistry jobRegistry, JobRepository jobRepository) {
TaskJobLauncherCommandLineRunnerFactoryBean taskJobLauncherCommandLineRunnerFactoryBean =
new TaskJobLauncherCommandLineRunnerFactoryBean(jobLauncher,
jobExplorer,
jobs,
this.properties,
jobRegistry,
jobRepository);
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(
JobLauncher jobLauncher, JobExplorer jobExplorer, List<Job> jobs,
JobRegistry jobRegistry, JobRepository jobRepository) {
TaskJobLauncherCommandLineRunnerFactoryBean taskJobLauncherCommandLineRunnerFactoryBean;
taskJobLauncherCommandLineRunnerFactoryBean = new TaskJobLauncherCommandLineRunnerFactoryBean(
jobLauncher, jobExplorer, jobs, this.properties, jobRegistry,
jobRepository);
return taskJobLauncherCommandLineRunnerFactoryBean;
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 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
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://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.
* 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;
@@ -33,7 +33,8 @@ import org.springframework.util.StringUtils;
*
* @author Glenn Renfro
*/
public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<TaskJobLauncherCommandLineRunner> {
public class TaskJobLauncherCommandLineRunnerFactoryBean
implements FactoryBean<TaskJobLauncherCommandLineRunner> {
private JobLauncher jobLauncher;
@@ -52,8 +53,9 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
private JobRepository jobRepository;
public TaskJobLauncherCommandLineRunnerFactoryBean(JobLauncher jobLauncher,
JobExplorer jobExplorer, List<Job> jobs, TaskBatchProperties taskBatchProperties,
JobRegistry jobRegistry, JobRepository jobRepository) {
JobExplorer jobExplorer, List<Job> jobs,
TaskBatchProperties taskBatchProperties, JobRegistry jobRegistry,
JobRepository jobRepository) {
Assert.notNull(taskBatchProperties, "properties must not be null");
this.jobLauncher = jobLauncher;
this.jobExplorer = jobExplorer;
@@ -72,15 +74,16 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
@Override
public TaskJobLauncherCommandLineRunner getObject() {
TaskJobLauncherCommandLineRunner taskJobLauncherCommandLineRunner =
new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer, this.jobRepository, this.taskBatchProperties);
TaskJobLauncherCommandLineRunner taskJobLauncherCommandLineRunner = new TaskJobLauncherCommandLineRunner(
this.jobLauncher, this.jobExplorer, this.jobRepository,
this.taskBatchProperties);
taskJobLauncherCommandLineRunner.setJobs(this.jobs);
if(StringUtils.hasText(this.jobNames)) {
if (StringUtils.hasText(this.jobNames)) {
taskJobLauncherCommandLineRunner.setJobNames(this.jobNames);
}
taskJobLauncherCommandLineRunner.setJobRegistry(this.jobRegistry);
if(this.order != null) {
if (this.order != null) {
taskJobLauncherCommandLineRunner.setOrder(this.order);
}
return taskJobLauncherCommandLineRunner;

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 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
* 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
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://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.
* 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;
@@ -57,11 +57,11 @@ 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 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.
*
@@ -70,15 +70,15 @@ import org.springframework.util.StringUtils;
*/
public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunner {
private static final Log logger = LogFactory
.getLog(TaskJobLauncherCommandLineRunner.class);
private JobLauncher taskJobLauncher;
private JobExplorer taskJobExplorer;
private JobRepository taskJobRepository;
private static final Log logger = LogFactory
.getLog(TaskJobLauncherCommandLineRunner.class);
private List<JobExecution> jobExecutionList = new ArrayList<>();
private ApplicationEventPublisher taskApplicationEventPublisher;
@@ -91,10 +91,12 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
* @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.
* @param taskBatchProperties the properties used to configure the
* taskBatchProperties.
*/
public TaskJobLauncherCommandLineRunner(JobLauncher jobLauncher, JobExplorer jobExplorer,
JobRepository jobRepository, TaskBatchProperties taskBatchProperties) {
public TaskJobLauncherCommandLineRunner(JobLauncher jobLauncher,
JobExplorer jobExplorer, JobRepository jobRepository,
TaskBatchProperties taskBatchProperties) {
super(jobLauncher, jobExplorer, jobRepository);
this.taskJobLauncher = jobLauncher;
this.taskJobExplorer = jobExplorer;
@@ -151,7 +153,8 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
}
JobExecution execution = this.taskJobLauncher.run(job, parameters);
if (this.taskApplicationEventPublisher != null) {
this.taskApplicationEventPublisher.publishEvent(new JobExecutionEvent(execution));
this.taskApplicationEventPublisher
.publishEvent(new JobExecutionEvent(execution));
}
this.jobExecutionList.add(execution);
if (execution.getStatus().equals(BatchStatus.FAILED)) {
@@ -168,8 +171,9 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
List<JobExecution> failedJobExecutions = new ArrayList<>();
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
for (JobExecution jobExecution : jobExecutionList) {
JobExecution currentJobExecution = taskJobExplorer.getJobExecution(jobExecution.getId());
for (JobExecution jobExecution : this.jobExecutionList) {
JobExecution currentJobExecution = this.taskJobExplorer
.getJobExecution(jobExecution.getId());
BatchStatus batchStatus = currentJobExecution.getStatus();
if (batchStatus.isRunning()) {
repeatStatus = RepeatStatus.CONTINUABLE;
@@ -178,9 +182,10 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
failedJobExecutions.add(jobExecution);
}
}
Thread.sleep(taskBatchProperties.getFailOnJobFailurePollInterval());
Thread.sleep(this.taskBatchProperties.getFailOnJobFailurePollInterval());
if (repeatStatus.equals(RepeatStatus.FINISHED) && failedJobExecutions.size() > 0) {
if (repeatStatus.equals(RepeatStatus.FINISHED)
&& failedJobExecutions.size() > 0) {
throwJobFailedException(failedJobExecutions);
}
return repeatStatus;
@@ -190,8 +195,8 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
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",
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()));
}
@@ -201,6 +206,7 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
throw new TaskException(message.toString());
}
private JobParameters removeNonIdentifying(JobParameters parameters) {
Map<String, JobParameter> parameterMap = parameters.getParameters();
HashMap<String, JobParameter> copy = new HashMap<>(parameterMap);
@@ -225,4 +231,5 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
merged.putAll(additionals.getParameters());
return new JobParameters(merged);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.listener;
import org.springframework.batch.core.JobExecution;
@@ -28,9 +29,9 @@ public interface TaskBatchDao {
/**
* Saves the relationship between a task execution and a job execution.
*
* @param taskExecution task execution
* @param jobExecution job execution
*/
void saveRelationship(TaskExecution taskExecution, JobExecution jobExecution);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,10 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.listener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.batch.core.JobExecution;
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
import org.springframework.cloud.task.listener.annotation.BeforeTask;
@@ -31,14 +33,14 @@ import org.springframework.util.Assert;
*/
public class TaskBatchExecutionListener extends JobExecutionListenerSupport {
private static final Log logger = LogFactory.getLog(TaskBatchExecutionListener.class);
private TaskExecution taskExecution;
private TaskBatchDao taskBatchDao;
private static final Log logger = LogFactory.getLog(TaskBatchExecutionListener.class);
/**
* @param taskBatchDao dao used to persist the relationship. Must not be null
* @param taskBatchDao dao used to persist the relationship. Must not be null
*/
public TaskBatchExecutionListener(TaskBatchDao taskBatchDao) {
Assert.notNull(taskBatchDao, "A TaskBatchDao is required");
@@ -53,14 +55,16 @@ public class TaskBatchExecutionListener extends JobExecutionListenerSupport {
@Override
public void beforeJob(JobExecution jobExecution) {
if(this.taskExecution == null) {
logger.warn("This job was executed outside the scope of a task but still used the task listener.");
if (this.taskExecution == null) {
logger.warn(
"This job was executed outside the scope of a task but still used the task listener.");
}
else {
logger.info(String.format("The job execution id %s was run within the task execution %s",
jobExecution.getId(),
this.taskExecution.getExecutionId()));
taskBatchDao.saveRelationship(taskExecution, jobExecution);
logger.info(String.format(
"The job execution id %s was run within the task execution %s",
jobExecution.getId(), this.taskExecution.getExecutionId()));
this.taskBatchDao.saveRelationship(this.taskExecution, jobExecution);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.listener.support;
import javax.sql.DataSource;
@@ -27,7 +28,7 @@ import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
/**
* JDBC based implementation of the {@link TaskBatchDao}. Intended to be used in
* JDBC based implementation of the {@link TaskBatchDao}. Intended to be used in
* conjunction with the JDBC based
* {@link org.springframework.cloud.task.repository.TaskRepository}
*
@@ -36,10 +37,10 @@ import org.springframework.util.StringUtils;
*/
public class JdbcTaskBatchDao implements TaskBatchDao {
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
private static final String INSERT_STATEMENT = "INSERT INTO %PREFIX%TASK_BATCH VALUES(?, ?)";
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
private JdbcOperations jdbcTemplate;
/**
@@ -68,10 +69,12 @@ public class JdbcTaskBatchDao implements TaskBatchDao {
public void saveRelationship(TaskExecution taskExecution, JobExecution jobExecution) {
Assert.notNull(taskExecution, "A taskExecution is required");
Assert.notNull(jobExecution, "A jobExecution is required");
jdbcTemplate.update(getQuery(INSERT_STATEMENT), taskExecution.getExecutionId(), jobExecution.getId());
this.jdbcTemplate.update(getQuery(INSERT_STATEMENT),
taskExecution.getExecutionId(), jobExecution.getId());
}
private String getQuery(String base) {
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
return StringUtils.replace(base, "%PREFIX%", this.tablePrefix);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.listener.support;
import java.util.Map;
@@ -25,8 +26,10 @@ import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.util.Assert;
/**
* Map implementation of the {@link TaskBatchDao}. <p> This is intended for
* testing purposes only!</p>
* Map implementation of the {@link TaskBatchDao}.
* <p>
* This is intended for testing purposes only!
* </p>
*
* @author Michael Minella
*/
@@ -44,8 +47,9 @@ public class MapTaskBatchDao implements TaskBatchDao {
Assert.notNull(taskExecution, "A taskExecution is required");
Assert.notNull(jobExecution, "A jobExecution is required");
if(this.relationships.containsKey(taskExecution.getExecutionId())) {
this.relationships.get(taskExecution.getExecutionId()).add(jobExecution.getId());
if (this.relationships.containsKey(taskExecution.getExecutionId())) {
this.relationships.get(taskExecution.getExecutionId())
.add(jobExecution.getId());
}
else {
TreeSet<Long> jobExecutionIds = new TreeSet<>();
@@ -54,4 +58,5 @@ public class MapTaskBatchDao implements TaskBatchDao {
this.relationships.put(taskExecution.getExecutionId(), jobExecutionIds);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.List;
@@ -33,10 +34,10 @@ public interface CommandLineArgsProvider {
* worker for the specified {@link ExecutionContext}.
*
* Note: This method is called once per partition.
*
* @param executionContext the unique state for the step to be executed.
* @return a list of formatted command line arguments to be passed to the worker (the
* list will be joined via spaces).
* list will be joined via spaces).
*/
List<String> getCommandLineArgs(ExecutionContext executionContext);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.ArrayList;
@@ -51,39 +52,57 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* <p>A {@link PartitionHandler} implementation that delegates to a {@link TaskLauncher} for
* each of the workers. The id of the worker's StepExecution is passed as an environment
* variable to the worker. The worker, bootstrapped by the
* <p>
* A {@link PartitionHandler} implementation that delegates to a {@link TaskLauncher} for
* each of the workers. The id of the worker's StepExecution is passed as an environment
* variable to the worker. The worker, bootstrapped by the
* {@link DeployerStepExecutionHandler}, looks up the StepExecution in the JobRepository
* and executes it. This PartitionHandler polls the JobRepository for the results.</p>
* and executes it. This PartitionHandler polls the JobRepository for the results.
* </p>
*
* <p>If the job fails, the partitions will be re-executed per normal batch rules (steps that
* <p>
* If the job fails, the partitions will be re-executed per normal batch rules (steps that
* are complete should do nothing, failed steps should restart based on their
* configurations).</p>
* configurations).
* </p>
*
* <p>This PartitionHandler and all of the worker processes must share the same JobRepository
* data store (aka point the same database).</p>
* <p>
* This PartitionHandler and all of the worker processes must share the same JobRepository
* data store (aka point the same database).
* </p>
*
* @author Michael Minella
*/
public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAware, InitializingBean {
public class DeployerPartitionHandler
implements PartitionHandler, EnvironmentAware, InitializingBean {
/**
* ID of Spring Cloud Task job execution.
*/
public static final String SPRING_CLOUD_TASK_JOB_EXECUTION_ID = "spring.cloud.task.job-execution-id";
/**
* ID of Spring Cloud Task step execution.
*/
public static final String SPRING_CLOUD_TASK_STEP_EXECUTION_ID = "spring.cloud.task.step-execution-id";
/**
* Name of Spring Cloud Task step.
*/
public static final String SPRING_CLOUD_TASK_STEP_NAME = "spring.cloud.task.step-name";
/**
* ID of Spring Cloud Task parent execution.
*/
public static final String SPRING_CLOUD_TASK_PARENT_EXECUTION_ID = "spring.cloud.task.parentExecutionId";
/**
* Spring Cloud Task property name.
*/
public static final String SPRING_CLOUD_TASK_NAME = "spring.cloud.task.name";
private static final long DEFAULT_POLL_INTERVAL = 10000;
public static final String SPRING_CLOUD_TASK_JOB_EXECUTION_ID =
"spring.cloud.task.job-execution-id";
public static final String SPRING_CLOUD_TASK_STEP_EXECUTION_ID =
"spring.cloud.task.step-execution-id";
public static final String SPRING_CLOUD_TASK_STEP_NAME =
"spring.cloud.task.step-name";
public static final String SPRING_CLOUD_TASK_PARENT_EXECUTION_ID =
"spring.cloud.task.parentExecutionId";
public static final String SPRING_CLOUD_TASK_NAME = "spring.cloud.task.name";
private int maxWorkers = -1;
private int gridSize = 1;
@@ -118,10 +137,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
private boolean defaultArgsAsEnvironmentVars = false;
public DeployerPartitionHandler(TaskLauncher taskLauncher,
JobExplorer jobExplorer,
Resource resource,
String stepName) {
public DeployerPartitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer,
Resource resource, String stepName) {
Assert.notNull(taskLauncher, "A taskLauncher is required");
Assert.notNull(jobExplorer, "A jobExplorer is required");
Assert.notNull(resource, "A resource is required");
@@ -135,17 +152,16 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
/**
* Used to provide any environment variables to be set on each worker launched.
*
* @param environmentVariablesProvider an {@link EnvironmentVariablesProvider}
*/
public void setEnvironmentVariablesProvider(EnvironmentVariablesProvider environmentVariablesProvider) {
public void setEnvironmentVariablesProvider(
EnvironmentVariablesProvider environmentVariablesProvider) {
this.environmentVariablesProvider = environmentVariablesProvider;
}
/**
* If set to true, the default args that are used internally by Spring Cloud Task and
* Spring Batch are passed as environment variables instead of command line arguments.
*
* @param defaultArgsAsEnvironmentVars defaults to false
*/
public void setDefaultArgsAsEnvironmentVars(boolean defaultArgsAsEnvironmentVars) {
@@ -154,17 +170,16 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
/**
* Used to provide any command line arguements to be passed to each worker launched.
*
* @param commandLineArgsProvider {@link CommandLineArgsProvider}
*/
public void setCommandLineArgsProvider(CommandLineArgsProvider commandLineArgsProvider) {
public void setCommandLineArgsProvider(
CommandLineArgsProvider commandLineArgsProvider) {
this.commandLineArgsProvider = commandLineArgsProvider;
}
/**
* The maximum number of workers to be executing at once.
*
* @param maxWorkers number of workers. Defaults to -1 (unlimited)
* @param maxWorkers number of workers. Defaults to -1 (unlimited)
*/
public void setMaxWorkers(int maxWorkers) {
Assert.isTrue(maxWorkers != 0, "maxWorkers cannot be 0");
@@ -172,11 +187,11 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
}
/**
* Approximate size of the pool of worker JVMs available. May be used by the
* Approximate size of the pool of worker JVMs available. May be used by the
* {@link StepExecutionSplitter} to determine how many partitions to create (at the
* discretion of the {@link org.springframework.batch.core.partition.support.Partitioner}).
*
* @param gridSize size of grid. Defaults to 1
* discretion of the
* {@link org.springframework.batch.core.partition.support.Partitioner}).
* @param gridSize size of grid. Defaults to 1
*/
public void setGridSize(int gridSize) {
this.gridSize = gridSize;
@@ -184,25 +199,22 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
/**
* The interval to check the job repository for completed steps.
*
* @param pollInterval interval. Defaults to 10 seconds
* @param pollInterval interval. Defaults to 10 seconds
*/
public void setPollInterval(long pollInterval) {
this.pollInterval = pollInterval;
}
/**
* Timeout for the master step. This is a timeout for all workers to complete.
*
* @param timeout timeout. Defaults to none (-1).
* Timeout for the master step. This is a timeout for all workers to complete.
* @param timeout timeout. Defaults to none (-1).
*/
public void setTimeout(long timeout) {
this.timeout = timeout;
}
/**
* Map of deployment properties to be used by the {@link TaskLauncher}
*
* Map of deployment properties to be used by the {@link TaskLauncher}.
* @param deploymentProperties properties to be used by the {@link TaskLauncher}
*/
public void setDeploymentProperties(Map<String, String> deploymentProperties) {
@@ -210,9 +222,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
}
/**
* The name of the application to be launched. Useful in environments where
* The name of the application to be launched. Useful in environments where
* application deployments are reused (such as CloudFoundry).
*
* @param applicationName The name of the application to be launched
*/
public void setApplicationName(String applicationName) {
@@ -223,9 +234,9 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
public void beforeTask(TaskExecution taskExecution) {
this.taskExecution = taskExecution;
if(this.commandLineArgsProvider == null) {
SimpleCommandLineArgsProvider provider = new
SimpleCommandLineArgsProvider(taskExecution);
if (this.commandLineArgsProvider == null) {
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(
taskExecution);
this.commandLineArgsProvider = provider;
}
@@ -235,8 +246,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter,
StepExecution stepExecution) throws Exception {
final Set<StepExecution> tempCandidates =
stepSplitter.split(stepExecution, this.gridSize);
final Set<StepExecution> tempCandidates = stepSplitter.split(stepExecution,
this.gridSize);
// Following two lines due to https://jira.spring.io/browse/BATCH-2490
final Set<StepExecution> candidates = new HashSet<>(tempCandidates.size());
@@ -244,7 +255,7 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
int partitions = candidates.size();
logger.debug(String.format("%s partitions were returned", partitions));
this.logger.debug(String.format("%s partitions were returned", partitions));
final Set<StepExecution> executed = new HashSet<>(candidates.size());
@@ -259,7 +270,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
return pollReplies(stepExecution, executed, candidates, partitions);
}
private void launchWorkers(Set<StepExecution> candidates, Set<StepExecution> executed) {
private void launchWorkers(Set<StepExecution> candidates,
Set<StepExecution> executed) {
for (StepExecution execution : candidates) {
if (this.currentWorkers < this.maxWorkers || this.maxWorkers < 0) {
launchWorker(execution);
@@ -273,59 +285,59 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
private void launchWorker(StepExecution workerStepExecution) {
List<String> arguments = new ArrayList<>();
ExecutionContext copyContext = new ExecutionContext(workerStepExecution.getExecutionContext());
ExecutionContext copyContext = new ExecutionContext(
workerStepExecution.getExecutionContext());
arguments.addAll(
this.commandLineArgsProvider
.getCommandLineArgs(copyContext));
arguments.addAll(this.commandLineArgsProvider.getCommandLineArgs(copyContext));
if(!this.defaultArgsAsEnvironmentVars) {
if (!this.defaultArgsAsEnvironmentVars) {
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));
arguments.add(formatArgument(SPRING_CLOUD_TASK_NAME, String.format("%s_%s_%s",
taskExecution.getTaskName(),
workerStepExecution.getJobExecution().getJobInstance().getJobName(),
workerStepExecution.getStepName())));
arguments
.add(formatArgument(SPRING_CLOUD_TASK_NAME,
String.format("%s_%s_%s", this.taskExecution.getTaskName(),
workerStepExecution.getJobExecution().getJobInstance()
.getJobName(),
workerStepExecution.getStepName())));
arguments.add(formatArgument(SPRING_CLOUD_TASK_PARENT_EXECUTION_ID,
String.valueOf(taskExecution.getExecutionId())));
String.valueOf(this.taskExecution.getExecutionId())));
}
copyContext = new ExecutionContext(workerStepExecution.getExecutionContext());
Map<String, String> environmentVariables = this.environmentVariablesProvider.getEnvironmentVariables(copyContext);
Map<String, String> environmentVariables = this.environmentVariablesProvider
.getEnvironmentVariables(copyContext);
if(this.defaultArgsAsEnvironmentVars) {
if (this.defaultArgsAsEnvironmentVars) {
environmentVariables.put(SPRING_CLOUD_TASK_JOB_EXECUTION_ID,
String.valueOf(workerStepExecution.getJobExecution().getId()));
environmentVariables.put(SPRING_CLOUD_TASK_STEP_EXECUTION_ID,
String.valueOf(workerStepExecution.getId()));
environmentVariables.put(SPRING_CLOUD_TASK_STEP_NAME, this.stepName);
environmentVariables.put(SPRING_CLOUD_TASK_NAME, String.format("%s_%s_%s",
taskExecution.getTaskName(),
workerStepExecution.getJobExecution().getJobInstance().getJobName(),
workerStepExecution.getStepName()));
environmentVariables
.put(SPRING_CLOUD_TASK_NAME,
String.format("%s_%s_%s", this.taskExecution.getTaskName(),
workerStepExecution.getJobExecution().getJobInstance()
.getJobName(),
workerStepExecution.getStepName()));
environmentVariables.put(SPRING_CLOUD_TASK_PARENT_EXECUTION_ID,
String.valueOf(taskExecution.getExecutionId()));
String.valueOf(this.taskExecution.getExecutionId()));
}
AppDefinition definition =
new AppDefinition(resolveApplicationName(),
environmentVariables);
AppDefinition definition = new AppDefinition(resolveApplicationName(),
environmentVariables);
AppDeploymentRequest request =
new AppDeploymentRequest(definition,
this.resource,
this.deploymentProperties,
arguments);
AppDeploymentRequest request = new AppDeploymentRequest(definition, this.resource,
this.deploymentProperties, arguments);
taskLauncher.launch(request);
this.taskLauncher.launch(request);
}
private String resolveApplicationName() {
if(StringUtils.hasText(this.applicationName)) {
if (StringUtils.hasText(this.applicationName)) {
return this.applicationName;
}
else {
@@ -338,8 +350,7 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
}
private Collection<StepExecution> pollReplies(final StepExecution masterStepExecution,
final Set<StepExecution> executed,
final Set<StepExecution> candidates,
final Set<StepExecution> executed, final Set<StepExecution> candidates,
final int size) throws Exception {
final Collection<StepExecution> result = new ArrayList<>(executed.size());
@@ -351,13 +362,14 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
for (StepExecution curStepExecution : executed) {
if (!result.contains(curStepExecution)) {
StepExecution partitionStepExecution =
jobExplorer.getStepExecution(masterStepExecution.getJobExecutionId(), curStepExecution.getId());
StepExecution partitionStepExecution = DeployerPartitionHandler.this.jobExplorer
.getStepExecution(masterStepExecution.getJobExecutionId(),
curStepExecution.getId());
BatchStatus batchStatus = partitionStepExecution.getStatus();
if (batchStatus != null && isComplete(batchStatus)) {
result.add(partitionStepExecution);
currentWorkers--;
DeployerPartitionHandler.this.currentWorkers--;
if (!candidates.isEmpty()) {
@@ -382,8 +394,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
Poller<Collection<StepExecution>> poller = new DirectPoller<>(this.pollInterval);
Future<Collection<StepExecution>> resultsFuture = poller.poll(callback);
if (timeout >= 0) {
return resultsFuture.get(timeout, TimeUnit.MILLISECONDS);
if (this.timeout >= 0) {
return resultsFuture.get(this.timeout, TimeUnit.MILLISECONDS);
}
else {
return resultsFuture.get();
@@ -391,7 +403,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
}
private boolean isComplete(BatchStatus status) {
return status.equals(BatchStatus.COMPLETED) || status.isGreaterThan(BatchStatus.STARTED);
return status.equals(BatchStatus.COMPLETED)
|| status.isGreaterThan(BatchStatus.STARTED);
}
@Override
@@ -401,10 +414,11 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
@Override
public void afterPropertiesSet() throws Exception {
if(this.environmentVariablesProvider == null) {
this.environmentVariablesProvider =
new SimpleEnvironmentVariablesProvider(this.environment);
if (this.environmentVariablesProvider == null) {
this.environmentVariablesProvider = new SimpleEnvironmentVariablesProvider(
this.environment);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import org.apache.commons.logging.Log;
@@ -34,20 +35,24 @@ import org.springframework.core.env.Environment;
import org.springframework.util.Assert;
/**
* <p>A {@link CommandLineRunner} used to execute a {@link Step}. No result is provided
* <p>
* A {@link CommandLineRunner} used to execute a {@link Step}. No result is provided
* directly to the associated {@link DeployerPartitionHandler} as it will obtain the step
* results directly from the shared job repository.</p>
* results directly from the shared job repository.
* </p>
*
* <p>The {@link StepExecution} is rehydrated based on the environment variables provided.
* Specifically, the following variables are required:</p>
* <p>
* The {@link StepExecution} is rehydrated based on the environment variables provided.
* Specifically, the following variables are required:
* </p>
* <ul>
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_JOB_EXECUTION_ID}: The id of
* the JobExecution.</li>
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_EXECUTION_ID}: The id of
* the StepExecution.</li>
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_NAME}: The id of the
* bean definition for the Step to execute. The id must be found within the provided
* {@link BeanFactory}</li>
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_JOB_EXECUTION_ID}: The id of the
* JobExecution.</li>
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_EXECUTION_ID}: The id of the
* StepExecution.</li>
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_NAME}: The id of the bean
* definition for the Step to execute. The id must be found within the provided
* {@link BeanFactory}</li>
* </ul>
*
* @author Michael Minella
@@ -65,7 +70,8 @@ public class DeployerStepExecutionHandler implements CommandLineRunner {
private StepLocator stepLocator;
public DeployerStepExecutionHandler(BeanFactory beanFactory, JobExplorer jobExplorer, JobRepository jobRepository) {
public DeployerStepExecutionHandler(BeanFactory beanFactory, JobExplorer jobExplorer,
JobRepository jobRepository) {
Assert.notNull(beanFactory, "A beanFactory is required");
Assert.notNull(jobExplorer, "A jobExplorer is required");
Assert.notNull(jobRepository, "A jobRepository is required");
@@ -82,38 +88,60 @@ public class DeployerStepExecutionHandler implements CommandLineRunner {
validateRequest();
Long jobExecutionId = Long.parseLong(environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID));
Long stepExecutionId = Long.parseLong(environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID));
StepExecution stepExecution = jobExplorer.getStepExecution(jobExecutionId, stepExecutionId);
Long jobExecutionId = Long.parseLong(this.environment.getProperty(
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID));
Long stepExecutionId = Long.parseLong(this.environment.getProperty(
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID));
StepExecution stepExecution = this.jobExplorer.getStepExecution(jobExecutionId,
stepExecutionId);
if (stepExecution == null) {
throw new NoSuchStepException(String.format("No StepExecution could be located for step execution id %s within job execution %s", stepExecutionId, jobExecutionId));
throw new NoSuchStepException(String.format(
"No StepExecution could be located for step execution id %s within job execution %s",
stepExecutionId, jobExecutionId));
}
String stepName = environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME);
Step step = stepLocator.getStep(stepName);
String stepName = this.environment
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME);
Step step = this.stepLocator.getStep(stepName);
try {
logger.debug(String.format("Executing step %s with step execution id %s and job execution id %s", stepExecution.getStepName(), stepExecutionId, jobExecutionId));
this.logger.debug(String.format(
"Executing step %s with step execution id %s and job execution id %s",
stepExecution.getStepName(), stepExecutionId, jobExecutionId));
step.execute(stepExecution);
}
catch (JobInterruptedException e) {
stepExecution.setStatus(BatchStatus.STOPPED);
jobRepository.update(stepExecution);
this.jobRepository.update(stepExecution);
}
catch (Throwable e) {
stepExecution.addFailureException(e);
stepExecution.setStatus(BatchStatus.FAILED);
jobRepository.update(stepExecution);
this.jobRepository.update(stepExecution);
}
}
private void validateRequest() {
Assert.isTrue(environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID), "A job execution id is required");
Assert.isTrue(environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID), "A step execution id is required");
Assert.isTrue(environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME), "A step name is required");
Assert.isTrue(
this.environment.containsProperty(
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID),
"A job execution id is required");
Assert.isTrue(
this.environment.containsProperty(
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID),
"A step execution id is required");
Assert.isTrue(
this.environment.containsProperty(
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME),
"A step name is required");
Assert.isTrue(this.stepLocator.getStepNames().contains(environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)), "The step requested cannot be found in the provided BeanFactory");
Assert.isTrue(
this.stepLocator.getStepNames()
.contains(this.environment.getProperty(
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)),
"The step requested cannot be found in the provided BeanFactory");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.Map;
@@ -24,19 +25,18 @@ import org.springframework.batch.item.ExecutionContext;
* each worker in a partitioned job.
*
* @author Michael Minella
*
* @since 1.0.2
*/
public interface EnvironmentVariablesProvider {
/**
* Provides a {@link Map} of Strings to be used as environment variables. This method
* will be called for each worker step. For example, if there are 5 partitions, this
* Provides a {@link Map} of Strings to be used as environment variables. This method
* will be called for each worker step. For example, if there are 5 partitions, this
* method will be called 5 times.
*
* @param executionContext the {@link ExecutionContext} associated with the worker's
* step
* step
* @return A {@link Map} of values to be used as environment variables
*/
Map<String, String> getEnvironmentVariables(ExecutionContext executionContext);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.Collections;
@@ -21,23 +22,23 @@ import java.util.Map;
import org.springframework.batch.item.ExecutionContext;
/**
* A simple no-op implementation of the {@link EnvironmentVariablesProvider}. It returns
* A simple no-op implementation of the {@link EnvironmentVariablesProvider}. It returns
* an empty {@link Map}.
*
* @author Michael Minella
*
* @since 1.0.2
*/
public class NoOpEnvironmentVariablesProvider implements EnvironmentVariablesProvider {
/**
*
* @param executionContext the {@link ExecutionContext} associated with the worker's
* step
* step
* @return an empty {@link Map}
*/
@Override
public Map<String, String> getEnvironmentVariables(ExecutionContext executionContext) {
public Map<String, String> getEnvironmentVariables(
ExecutionContext executionContext) {
return Collections.emptyMap();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.List;
@@ -38,6 +39,7 @@ public class PassThroughCommandLineArgsProvider implements CommandLineArgsProvid
@Override
public List<String> getCommandLineArgs(ExecutionContext executionContext) {
return commandLineArgs;
return this.commandLineArgs;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.ArrayList;
@@ -31,7 +32,8 @@ import org.springframework.util.Assert;
* @author Glenn Renfro
* @since 1.1.0
*/
public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport implements CommandLineArgsProvider {
public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport
implements CommandLineArgsProvider {
private TaskExecution taskExecution;
@@ -56,7 +58,6 @@ public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport
/**
* Additional command line args to be appended.
*
* @param appendedArgs list of arguments
* @since 1.2
*/
@@ -67,17 +68,18 @@ public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport
@Override
public List<String> getCommandLineArgs(ExecutionContext executionContext) {
int listSize = this.taskExecution.getArguments().size() +
(this.appendedArgs != null ? this.appendedArgs.size() : 0);
int listSize = this.taskExecution.getArguments().size()
+ (this.appendedArgs != null ? this.appendedArgs.size() : 0);
List<String> args = new ArrayList<>(listSize);
args.addAll(this.taskExecution.getArguments());
if(this.appendedArgs != null) {
if (this.appendedArgs != null) {
args.addAll(this.appendedArgs);
}
return args;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 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.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.batch.partition;
import java.util.Arrays;
@@ -29,12 +30,11 @@ import org.springframework.core.env.PropertySource;
/**
* Copies all existing environment variables as made available in the {@link Environment}
* only if includeCurrentEnvironment is set to true (default).
* The <code>environmentProperties</code> option provides the ability to override any
* specific values on an as needed basis.
* only if includeCurrentEnvironment is set to true (default). The
* <code>environmentProperties</code> option provides the ability to override any specific
* values on an as needed basis.
*
* @author Michael Minella
*
* @since 1.0.2
*/
public class SimpleEnvironmentVariablesProvider implements EnvironmentVariablesProvider {
@@ -53,28 +53,31 @@ public class SimpleEnvironmentVariablesProvider implements EnvironmentVariablesP
}
/**
* @param environmentProperties a {@link Map} of properties used to override any values
* configured in the current {@link Environment}
* @param environmentProperties a {@link Map} of properties used to override any
* values configured in the current {@link Environment}
*/
public void setEnvironmentProperties(Map<String, String> environmentProperties) {
this.environmentProperties = environmentProperties;
}
/**
* Establishes if current environment variables will be included as a part of the provider.
* @param includeCurrentEnvironment true(default) include local environment properties. False do not include
* current environment properties.
* Establishes if current environment variables will be included as a part of the
* provider.
* @param includeCurrentEnvironment true(default) include local environment
* properties. False do not include current environment properties.
*/
public void setIncludeCurrentEnvironment(boolean includeCurrentEnvironment) {
this.includeCurrentEnvironment = includeCurrentEnvironment;
}
@Override
public Map<String, String> getEnvironmentVariables(ExecutionContext executionContext) {
public Map<String, String> getEnvironmentVariables(
ExecutionContext executionContext) {
Map<String, String> environmentProperties = new HashMap<>(this.environmentProperties.size());
Map<String, String> environmentProperties = new HashMap<>(
this.environmentProperties.size());
if(includeCurrentEnvironment) {
if (this.includeCurrentEnvironment) {
environmentProperties.putAll(getCurrentEnvironmentProperties());
}
@@ -88,9 +91,11 @@ public class SimpleEnvironmentVariablesProvider implements EnvironmentVariablesP
Set<String> keys = new HashSet<>();
for (PropertySource<?> propertySource : ((AbstractEnvironment) this.environment).getPropertySources()) {
for (PropertySource<?> propertySource : ((AbstractEnvironment) this.environment)
.getPropertySources()) {
if (propertySource instanceof MapPropertySource) {
keys.addAll(Arrays.asList(((MapPropertySource) propertySource).getPropertyNames()));
keys.addAll(Arrays
.asList(((MapPropertySource) propertySource).getPropertyNames()));
}
}
@@ -100,4 +105,5 @@ public class SimpleEnvironmentVariablesProvider implements EnvironmentVariablesP
return currentEnvironment;
}
}

View File

@@ -1,64 +1,64 @@
{
"properties": [
{
"defaultValue": true,
"name": "spring.cloud.task.batch.listener.enabled",
"description": "This property is used to determine if a task will be linked to the batch jobs that are run.",
"type": "java.lang.Boolean"
},
{
"defaultValue": false,
"name": "spring.cloud.task.batch.fail-on-job-failure",
"description": "This property is used to determine if a task app should return with a non zero exit code if a batch job fails.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.enabled",
"description": "This property is used to determine if a task should listen for batch events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.chunk.enabled",
"description": "This property is used to determine if a task should listen for batch chunk events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.item-process.enabled",
"description": "This property is used to determine if a task should listen for batch item processed events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.item-read.enabled",
"description": "This property is used to determine if a task should listen for batch item read events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.item-write.enabled",
"description": "This property is used to determine if a task should listen for batch item write events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.job-execution.enabled",
"description": "This property is used to determine if a task should listen for batch job execution events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.skip.enabled",
"description": "This property is used to determine if a task should listen for batch skip events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.step-execution.enabled",
"description": "This property is used to determine if a task should listen for batch step execution events.",
"type": "java.lang.Boolean"
}
]
"properties": [
{
"defaultValue": true,
"name": "spring.cloud.task.batch.listener.enabled",
"description": "This property is used to determine if a task will be linked to the batch jobs that are run.",
"type": "java.lang.Boolean"
},
{
"defaultValue": false,
"name": "spring.cloud.task.batch.fail-on-job-failure",
"description": "This property is used to determine if a task app should return with a non zero exit code if a batch job fails.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.enabled",
"description": "This property is used to determine if a task should listen for batch events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.chunk.enabled",
"description": "This property is used to determine if a task should listen for batch chunk events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.item-process.enabled",
"description": "This property is used to determine if a task should listen for batch item processed events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.item-read.enabled",
"description": "This property is used to determine if a task should listen for batch item read events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.item-write.enabled",
"description": "This property is used to determine if a task should listen for batch item write events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.job-execution.enabled",
"description": "This property is used to determine if a task should listen for batch job execution events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.skip.enabled",
"description": "This property is used to determine if a task should listen for batch skip events.",
"type": "java.lang.Boolean"
},
{
"defaultValue": true,
"name": "spring.cloud.task.batch.events.step-execution.enabled",
"description": "This property is used to determine if a task should listen for batch step execution events.",
"type": "java.lang.Boolean"
}
]
}