Added checkstyle
This commit is contained in:
14
.editorconfig
Normal file
14
.editorconfig
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
# EditorConfig is awesome: http://EditorConfig.org
|
||||||
|
|
||||||
|
# top-most EditorConfig file
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
indent_style = tab
|
||||||
|
indent_size = 4
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
|
||||||
|
[*.yml]
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<!--
|
<!--
|
||||||
~ /*
|
~ /*
|
||||||
~ * Copyright 2015 the original author or authors.
|
~ * Copyright 2015-2019 the original author or authors.
|
||||||
~ *
|
~ *
|
||||||
~ * Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -34,7 +34,9 @@
|
|||||||
this settings file, or copy the profile into their ~/.m2/settings.xml.
|
this settings file, or copy the profile into their ~/.m2/settings.xml.
|
||||||
-->
|
-->
|
||||||
<id>spring</id>
|
<id>spring</id>
|
||||||
<activation><activeByDefault>true</activeByDefault></activation>
|
<activation>
|
||||||
|
<activeByDefault>true</activeByDefault>
|
||||||
|
</activation>
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>spring-snapshots</id>
|
<id>spring-snapshots</id>
|
||||||
|
|||||||
0
.springformat
Normal file
0
.springformat
Normal file
54
pom.xml
54
pom.xml
@@ -1,12 +1,14 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
<artifactId>spring-cloud-build</artifactId>
|
<artifactId>spring-cloud-build</artifactId>
|
||||||
<version>2.1.1.RELEASE</version>
|
<version>2.1.3.BUILD-SNAPSHOT</version>
|
||||||
<relativePath />
|
<relativePath/>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>org.springframework.cloud</groupId>
|
<groupId>org.springframework.cloud</groupId>
|
||||||
@@ -126,15 +128,24 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<spring-cloud-stream.version>2.1.0.RELEASE</spring-cloud-stream.version>
|
<spring-cloud-stream.version>2.1.0.RELEASE</spring-cloud-stream.version>
|
||||||
<spring-cloud-deployer.version>2.0.0.RELEASE</spring-cloud-deployer.version>
|
<spring-cloud-deployer.version>2.0.0.RELEASE</spring-cloud-deployer.version>
|
||||||
<spring-cloud-deployer-local.version>2.0.0.RELEASE</spring-cloud-deployer-local.version>
|
<spring-cloud-deployer-local.version>2.0.0.RELEASE
|
||||||
<spring-cloud-stream-binder-rabbit.version>2.1.0.RELEASE</spring-cloud-stream-binder-rabbit.version>
|
</spring-cloud-deployer-local.version>
|
||||||
|
<spring-cloud-stream-binder-rabbit.version>2.1.0.RELEASE
|
||||||
|
</spring-cloud-stream-binder-rabbit.version>
|
||||||
<spring-batch.version>4.1.1.RELEASE</spring-batch.version>
|
<spring-batch.version>4.1.1.RELEASE</spring-batch.version>
|
||||||
<commons-logging.version>1.1</commons-logging.version>
|
<commons-logging.version>1.1</commons-logging.version>
|
||||||
<java-ee-api.version>8.0</java-ee-api.version>
|
<java-ee-api.version>8.0</java-ee-api.version>
|
||||||
<junit.version>5.3.1</junit.version>
|
<junit.version>5.3.1</junit.version>
|
||||||
|
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<sonar.jacoco.reportPath>${project.build.directory}/coverage-reports/jacoco-ut.exec</sonar.jacoco.reportPath>
|
<sonar.jacoco.reportPath>
|
||||||
|
${project.build.directory}/coverage-reports/jacoco-ut.exec
|
||||||
|
</sonar.jacoco.reportPath>
|
||||||
|
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
|
||||||
|
<maven-checkstyle-plugin.failsOnViolation>true
|
||||||
|
</maven-checkstyle-plugin.failsOnViolation>
|
||||||
|
<maven-checkstyle-plugin.includeTestSourceDirectory>true
|
||||||
|
</maven-checkstyle-plugin.includeTestSourceDirectory>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
@@ -211,7 +222,9 @@
|
|||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- Sets the path to the file which contains the execution data. -->
|
<!-- Sets the path to the file which contains the execution data. -->
|
||||||
<destFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</destFile>
|
<destFile>
|
||||||
|
${project.build.directory}/coverage-reports/jacoco-ut.exec
|
||||||
|
</destFile>
|
||||||
<!--
|
<!--
|
||||||
Sets the name of the property containing the settings
|
Sets the name of the property containing the settings
|
||||||
for JaCoCo runtime agent.
|
for JaCoCo runtime agent.
|
||||||
@@ -231,15 +244,38 @@
|
|||||||
</goals>
|
</goals>
|
||||||
<configuration>
|
<configuration>
|
||||||
<!-- Sets the path to the file which contains the execution data. -->
|
<!-- Sets the path to the file which contains the execution data. -->
|
||||||
<dataFile>${project.build.directory}/coverage-reports/jacoco-ut.exec</dataFile>
|
<dataFile>
|
||||||
|
${project.build.directory}/coverage-reports/jacoco-ut.exec
|
||||||
|
</dataFile>
|
||||||
<!-- Sets the output directory for the code coverage report. -->
|
<!-- Sets the output directory for the code coverage report. -->
|
||||||
<outputDirectory>${project.reporting.outputDirectory}/jacoco-ut</outputDirectory>
|
<outputDirectory>
|
||||||
|
${project.reporting.outputDirectory}/jacoco-ut
|
||||||
|
</outputDirectory>
|
||||||
</configuration>
|
</configuration>
|
||||||
</execution>
|
</execution>
|
||||||
</executions>
|
</executions>
|
||||||
</plugin>
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>io.spring.javaformat</groupId>
|
||||||
|
<artifactId>spring-javaformat-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
<reporting>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</reporting>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>spring</id>
|
<id>spring</id>
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
@@ -12,7 +14,8 @@
|
|||||||
<artifactId>spring-cloud-task-batch</artifactId>
|
<artifactId>spring-cloud-task-batch</artifactId>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
<name>Spring Cloud Task Batch</name>
|
<name>Spring Cloud Task Batch</name>
|
||||||
<description>Module for use when combining Spring Cloud Task with Spring Batch</description>
|
<description>Module for use when combining Spring Cloud Task with Spring Batch
|
||||||
|
</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
@@ -79,7 +82,7 @@
|
|||||||
<groupId>org.assertj</groupId>
|
<groupId>org.assertj</groupId>
|
||||||
<artifactId>assertj-core</artifactId>
|
<artifactId>assertj-core</artifactId>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.junit.jupiter</groupId>
|
<groupId>org.junit.jupiter</groupId>
|
||||||
<artifactId>junit-jupiter-api</artifactId>
|
<artifactId>junit-jupiter-api</artifactId>
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
|
|
||||||
import org.springframework.batch.core.Job;
|
import org.springframework.batch.core.Job;
|
||||||
@@ -38,8 +39,9 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*/
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnBean({Job.class})
|
@ConditionalOnBean({ Job.class })
|
||||||
@ConditionalOnProperty(name = {"spring.cloud.task.batch.listener.enable", "spring.cloud.task.batch.listener.enabled"}, havingValue = "true", matchIfMissing = true)
|
@ConditionalOnProperty(name = { "spring.cloud.task.batch.listener.enable",
|
||||||
|
"spring.cloud.task.batch.listener.enabled" }, havingValue = "true", matchIfMissing = true)
|
||||||
public class TaskBatchAutoConfiguration {
|
public class TaskBatchAutoConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -48,6 +50,9 @@ public class TaskBatchAutoConfiguration {
|
|||||||
return new TaskBatchExecutionListenerBeanPostProcessor();
|
return new TaskBatchExecutionListenerBeanPostProcessor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Auto configuration for Task Batch Execution Listener.
|
||||||
|
*/
|
||||||
@Configuration
|
@Configuration
|
||||||
@ConditionalOnMissingBean(name = "taskBatchExecutionListener")
|
@ConditionalOnMissingBean(name = "taskBatchExecutionListener")
|
||||||
@EnableConfigurationProperties(TaskProperties.class)
|
@EnableConfigurationProperties(TaskProperties.class)
|
||||||
@@ -60,20 +65,23 @@ public class TaskBatchAutoConfiguration {
|
|||||||
private TaskProperties taskProperties;
|
private TaskProperties taskProperties;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskBatchExecutionListenerFactoryBean taskBatchExecutionListener(TaskExplorer taskExplorer) {
|
public TaskBatchExecutionListenerFactoryBean taskBatchExecutionListener(
|
||||||
|
TaskExplorer taskExplorer) {
|
||||||
TaskConfigurer taskConfigurer = null;
|
TaskConfigurer taskConfigurer = null;
|
||||||
if(!this.context.getBeansOfType(TaskConfigurer.class).isEmpty()) {
|
if (!this.context.getBeansOfType(TaskConfigurer.class).isEmpty()) {
|
||||||
taskConfigurer = this.context.getBean(TaskConfigurer.class);
|
taskConfigurer = this.context.getBean(TaskConfigurer.class);
|
||||||
}
|
}
|
||||||
if(taskConfigurer != null && taskConfigurer.getTaskDataSource() != null) {
|
if (taskConfigurer != null && taskConfigurer.getTaskDataSource() != null) {
|
||||||
return new TaskBatchExecutionListenerFactoryBean(
|
return new TaskBatchExecutionListenerFactoryBean(
|
||||||
taskConfigurer.getTaskDataSource(),
|
taskConfigurer.getTaskDataSource(), taskExplorer,
|
||||||
taskExplorer, taskProperties.getTablePrefix());
|
this.taskProperties.getTablePrefix());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new TaskBatchExecutionListenerFactoryBean(null,
|
return new TaskBatchExecutionListenerFactoryBean(null, taskExplorer,
|
||||||
taskExplorer, taskProperties.getTablePrefix());
|
this.taskProperties.getTablePrefix());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -28,7 +29,7 @@ import org.springframework.util.Assert;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects a configured {@link TaskBatchExecutionListener} into any batch jobs (beans
|
* 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
|
* context this is used within is expected to have only one bean of type
|
||||||
* {@link TaskBatchExecutionListener}.
|
* {@link TaskBatchExecutionListener}.
|
||||||
*
|
*
|
||||||
@@ -50,17 +51,17 @@ public class TaskBatchExecutionListenerBeanPostProcessor implements BeanPostProc
|
|||||||
@Override
|
@Override
|
||||||
public Object postProcessAfterInitialization(Object bean, String beanName)
|
public Object postProcessAfterInitialization(Object bean, String beanName)
|
||||||
throws BeansException {
|
throws BeansException {
|
||||||
if(jobNames.size() > 0 && !jobNames.contains(beanName)) {
|
if (this.jobNames.size() > 0 && !this.jobNames.contains(beanName)) {
|
||||||
return bean;
|
return bean;
|
||||||
}
|
}
|
||||||
int length = this.applicationContext
|
int length = this.applicationContext
|
||||||
.getBeanNamesForType(TaskBatchExecutionListener.class).length;
|
.getBeanNamesForType(TaskBatchExecutionListener.class).length;
|
||||||
|
|
||||||
if(bean instanceof AbstractJob) {
|
if (bean instanceof AbstractJob) {
|
||||||
if(length != 1) {
|
if (length != 1) {
|
||||||
throw new IllegalStateException("The application context is required to " +
|
throw new IllegalStateException("The application context is required to "
|
||||||
"have exactly 1 instance of the TaskBatchExecutionListener but has " +
|
+ "have exactly 1 instance of the TaskBatchExecutionListener but has "
|
||||||
length);
|
+ length);
|
||||||
}
|
}
|
||||||
((AbstractJob) bean).registerJobExecutionListener(
|
((AbstractJob) bean).registerJobExecutionListener(
|
||||||
this.applicationContext.getBean(TaskBatchExecutionListener.class));
|
this.applicationContext.getBean(TaskBatchExecutionListener.class));
|
||||||
@@ -73,4 +74,5 @@ public class TaskBatchExecutionListenerBeanPostProcessor implements BeanPostProc
|
|||||||
|
|
||||||
this.jobNames = jobNames;
|
this.jobNames = jobNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.springframework.aop.framework.Advised;
|
import org.springframework.aop.framework.Advised;
|
||||||
@@ -32,13 +34,14 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link FactoryBean} for a {@link TaskBatchExecutionListener}. Provides a jdbc based
|
* {@link FactoryBean} for a {@link TaskBatchExecutionListener}. Provides a jdbc based
|
||||||
* listener if there is a {@link DataSource} available. Otherwise, builds a listener that
|
* listener if there is a {@link DataSource} available. Otherwise, builds a listener that
|
||||||
* uses the map based implementation.
|
* uses the map based implementation.
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*/
|
*/
|
||||||
public class TaskBatchExecutionListenerFactoryBean implements FactoryBean<TaskBatchExecutionListener> {
|
public class TaskBatchExecutionListenerFactoryBean
|
||||||
|
implements FactoryBean<TaskBatchExecutionListener> {
|
||||||
|
|
||||||
private TaskBatchExecutionListener listener;
|
private TaskBatchExecutionListener listener;
|
||||||
|
|
||||||
@@ -49,45 +52,45 @@ public class TaskBatchExecutionListenerFactoryBean implements FactoryBean<TaskBa
|
|||||||
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the TaskBatchExecutionListenerFactoryBean and defaults the
|
* Initializes the TaskBatchExecutionListenerFactoryBean and defaults the tablePrefix
|
||||||
* tablePrefix to {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
|
* to {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
|
||||||
*
|
|
||||||
* @param dataSource the dataSource to use for the TaskBatchExecutionListener.
|
* @param dataSource the dataSource to use for the TaskBatchExecutionListener.
|
||||||
* @param taskExplorer the taskExplorer 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.dataSource = dataSource;
|
||||||
this.taskExplorer = taskExplorer;
|
this.taskExplorer = taskExplorer;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the TaskBatchExecutionListenerFactoryBean.
|
* Initializes the TaskBatchExecutionListenerFactoryBean.
|
||||||
*
|
|
||||||
* @param dataSource the dataSource to use for the TaskBatchExecutionListener.
|
* @param dataSource the dataSource to use for the TaskBatchExecutionListener.
|
||||||
* @param taskExplorer the taskExplorer 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
|
* @param tablePrefix the prefix for the task tables accessed by the
|
||||||
* TaskBatchExecutionListener.
|
* TaskBatchExecutionListener.
|
||||||
*/
|
*/
|
||||||
public TaskBatchExecutionListenerFactoryBean(DataSource dataSource, TaskExplorer taskExplorer, String tablePrefix) {
|
public TaskBatchExecutionListenerFactoryBean(DataSource dataSource,
|
||||||
this(dataSource,taskExplorer);
|
TaskExplorer taskExplorer, String tablePrefix) {
|
||||||
|
this(dataSource, taskExplorer);
|
||||||
Assert.hasText(tablePrefix, "tablePrefix must not be null nor empty.");
|
Assert.hasText(tablePrefix, "tablePrefix must not be null nor empty.");
|
||||||
this.tablePrefix = tablePrefix;
|
this.tablePrefix = tablePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskBatchExecutionListener getObject() throws Exception {
|
public TaskBatchExecutionListener getObject() throws Exception {
|
||||||
if(listener != null){
|
if (this.listener != null) {
|
||||||
return listener;
|
return this.listener;
|
||||||
}
|
}
|
||||||
if(this.dataSource == null) {
|
if (this.dataSource == null) {
|
||||||
this.listener = new TaskBatchExecutionListener(getMapTaskBatchDao());
|
this.listener = new TaskBatchExecutionListener(getMapTaskBatchDao());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.listener = new TaskBatchExecutionListener(
|
this.listener = new TaskBatchExecutionListener(
|
||||||
new JdbcTaskBatchDao(this.dataSource, tablePrefix));
|
new JdbcTaskBatchDao(this.dataSource, this.tablePrefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
return listener;
|
return this.listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -101,22 +104,25 @@ public class TaskBatchExecutionListenerFactoryBean implements FactoryBean<TaskBa
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MapTaskBatchDao getMapTaskBatchDao() throws Exception {
|
private MapTaskBatchDao getMapTaskBatchDao() throws Exception {
|
||||||
Field taskExecutionDaoField = ReflectionUtils.findField(SimpleTaskExplorer.class, "taskExecutionDao");
|
Field taskExecutionDaoField = ReflectionUtils.findField(SimpleTaskExplorer.class,
|
||||||
|
"taskExecutionDao");
|
||||||
taskExecutionDaoField.setAccessible(true);
|
taskExecutionDaoField.setAccessible(true);
|
||||||
|
|
||||||
MapTaskExecutionDao taskExecutionDao;
|
MapTaskExecutionDao taskExecutionDao;
|
||||||
|
|
||||||
if(AopUtils.isJdkDynamicProxy(this.taskExplorer)) {
|
if (AopUtils.isJdkDynamicProxy(this.taskExplorer)) {
|
||||||
SimpleTaskExplorer dereferencedTaskRepository = (SimpleTaskExplorer) ((Advised) this.taskExplorer).getTargetSource().getTarget();
|
SimpleTaskExplorer dereferencedTaskRepository = (SimpleTaskExplorer) ((Advised) this.taskExplorer)
|
||||||
|
.getTargetSource().getTarget();
|
||||||
|
|
||||||
taskExecutionDao =
|
taskExecutionDao = (MapTaskExecutionDao) ReflectionUtils
|
||||||
(MapTaskExecutionDao) ReflectionUtils.getField(taskExecutionDaoField, dereferencedTaskRepository);
|
.getField(taskExecutionDaoField, dereferencedTaskRepository);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
taskExecutionDao =
|
taskExecutionDao = (MapTaskExecutionDao) ReflectionUtils
|
||||||
(MapTaskExecutionDao) ReflectionUtils.getField(taskExecutionDaoField, this.taskExplorer);
|
.getField(taskExecutionDaoField, this.taskExplorer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new MapTaskBatchDao(taskExecutionDao.getBatchJobAssociations());
|
return new MapTaskBatchDao(taskExecutionDao.getBatchJobAssociations());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
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;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establish properties to be used for how Tasks work with
|
* Establish properties to be used for how Tasks work with Spring Batch.
|
||||||
* Spring Batch.
|
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*
|
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties(prefix = "spring.cloud.task.batch")
|
@ConfigurationProperties(prefix = "spring.cloud.task.batch")
|
||||||
public class TaskBatchProperties {
|
public class TaskBatchProperties {
|
||||||
|
|
||||||
private static final long DEFAULT_POLL_INTERVAL = 5000L;
|
private static final long DEFAULT_POLL_INTERVAL = 5000L;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Comma-separated list of job names to execute on startup (for instance,
|
* Comma-separated list of job names to execute on startup (for instance,
|
||||||
* `job1,job2`). By default, all Jobs found in the context are executed.
|
* `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
|
* 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}).
|
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner}).
|
||||||
*/
|
*/
|
||||||
private int commandLineRunnerOrder = 0;
|
private int commandLineRunnerOrder = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fixed delay in milliseconds that Spring Cloud Task will wait when checking if
|
* Fixed delay in milliseconds that Spring Cloud Task will wait when checking if
|
||||||
* {@link org.springframework.batch.core.JobExecution}s have completed,
|
* {@link org.springframework.batch.core.JobExecution}s have completed, when
|
||||||
* when spring.cloud.task.batch.failOnJobFailure is set to true. Defaults
|
* spring.cloud.task.batch.failOnJobFailure is set to true. Defaults to 5000.
|
||||||
* to 5000.
|
|
||||||
*/
|
*/
|
||||||
private long failOnJobFailurePollInterval = DEFAULT_POLL_INTERVAL;
|
private long failOnJobFailurePollInterval = DEFAULT_POLL_INTERVAL;
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@ public class TaskBatchProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getCommandLineRunnerOrder() {
|
public int getCommandLineRunnerOrder() {
|
||||||
return commandLineRunnerOrder;
|
return this.commandLineRunnerOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCommandLineRunnerOrder(int commandLineRunnerOrder) {
|
public void setCommandLineRunnerOrder(int commandLineRunnerOrder) {
|
||||||
@@ -69,10 +68,11 @@ public class TaskBatchProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public long getFailOnJobFailurePollInterval() {
|
public long getFailOnJobFailurePollInterval() {
|
||||||
return failOnJobFailurePollInterval;
|
return this.failOnJobFailurePollInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFailOnJobFailurePollInterval(long failOnJobFailurePollInterval) {
|
public void setFailOnJobFailurePollInterval(long failOnJobFailurePollInterval) {
|
||||||
this.failOnJobFailurePollInterval = failOnJobFailurePollInterval;
|
this.failOnJobFailurePollInterval = failOnJobFailurePollInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* you may not use this file except in compliance with the License.
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* You may obtain a copy of the License at
|
||||||
* See the License for the specific language governing permissions and
|
*
|
||||||
* limitations under the License.
|
* 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;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
@@ -47,16 +47,15 @@ public class TaskJobLauncherAutoConfiguration {
|
|||||||
private TaskBatchProperties properties;
|
private TaskBatchProperties properties;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(JobLauncher jobLauncher,
|
public TaskJobLauncherCommandLineRunnerFactoryBean jobLauncherCommandLineRunner(
|
||||||
JobExplorer jobExplorer, List<Job> jobs, JobRegistry jobRegistry, JobRepository jobRepository) {
|
JobLauncher jobLauncher, JobExplorer jobExplorer, List<Job> jobs,
|
||||||
TaskJobLauncherCommandLineRunnerFactoryBean taskJobLauncherCommandLineRunnerFactoryBean =
|
JobRegistry jobRegistry, JobRepository jobRepository) {
|
||||||
new TaskJobLauncherCommandLineRunnerFactoryBean(jobLauncher,
|
TaskJobLauncherCommandLineRunnerFactoryBean taskJobLauncherCommandLineRunnerFactoryBean;
|
||||||
jobExplorer,
|
taskJobLauncherCommandLineRunnerFactoryBean = new TaskJobLauncherCommandLineRunnerFactoryBean(
|
||||||
jobs,
|
jobLauncher, jobExplorer, jobs, this.properties, jobRegistry,
|
||||||
this.properties,
|
jobRepository);
|
||||||
jobRegistry,
|
|
||||||
jobRepository);
|
|
||||||
|
|
||||||
return taskJobLauncherCommandLineRunnerFactoryBean;
|
return taskJobLauncherCommandLineRunnerFactoryBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
@@ -33,7 +33,8 @@ import org.springframework.util.StringUtils;
|
|||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<TaskJobLauncherCommandLineRunner> {
|
public class TaskJobLauncherCommandLineRunnerFactoryBean
|
||||||
|
implements FactoryBean<TaskJobLauncherCommandLineRunner> {
|
||||||
|
|
||||||
private JobLauncher jobLauncher;
|
private JobLauncher jobLauncher;
|
||||||
|
|
||||||
@@ -52,8 +53,9 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
|
|||||||
private JobRepository jobRepository;
|
private JobRepository jobRepository;
|
||||||
|
|
||||||
public TaskJobLauncherCommandLineRunnerFactoryBean(JobLauncher jobLauncher,
|
public TaskJobLauncherCommandLineRunnerFactoryBean(JobLauncher jobLauncher,
|
||||||
JobExplorer jobExplorer, List<Job> jobs, TaskBatchProperties taskBatchProperties,
|
JobExplorer jobExplorer, List<Job> jobs,
|
||||||
JobRegistry jobRegistry, JobRepository jobRepository) {
|
TaskBatchProperties taskBatchProperties, JobRegistry jobRegistry,
|
||||||
|
JobRepository jobRepository) {
|
||||||
Assert.notNull(taskBatchProperties, "properties must not be null");
|
Assert.notNull(taskBatchProperties, "properties must not be null");
|
||||||
this.jobLauncher = jobLauncher;
|
this.jobLauncher = jobLauncher;
|
||||||
this.jobExplorer = jobExplorer;
|
this.jobExplorer = jobExplorer;
|
||||||
@@ -72,15 +74,16 @@ public class TaskJobLauncherCommandLineRunnerFactoryBean implements FactoryBean<
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskJobLauncherCommandLineRunner getObject() {
|
public TaskJobLauncherCommandLineRunner getObject() {
|
||||||
TaskJobLauncherCommandLineRunner taskJobLauncherCommandLineRunner =
|
TaskJobLauncherCommandLineRunner taskJobLauncherCommandLineRunner = new TaskJobLauncherCommandLineRunner(
|
||||||
new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer, this.jobRepository, this.taskBatchProperties);
|
this.jobLauncher, this.jobExplorer, this.jobRepository,
|
||||||
|
this.taskBatchProperties);
|
||||||
taskJobLauncherCommandLineRunner.setJobs(this.jobs);
|
taskJobLauncherCommandLineRunner.setJobs(this.jobs);
|
||||||
if(StringUtils.hasText(this.jobNames)) {
|
if (StringUtils.hasText(this.jobNames)) {
|
||||||
taskJobLauncherCommandLineRunner.setJobNames(this.jobNames);
|
taskJobLauncherCommandLineRunner.setJobNames(this.jobNames);
|
||||||
}
|
}
|
||||||
taskJobLauncherCommandLineRunner.setJobRegistry(this.jobRegistry);
|
taskJobLauncherCommandLineRunner.setJobRegistry(this.jobRegistry);
|
||||||
|
|
||||||
if(this.order != null) {
|
if (this.order != null) {
|
||||||
taskJobLauncherCommandLineRunner.setOrder(this.order);
|
taskJobLauncherCommandLineRunner.setOrder(this.order);
|
||||||
}
|
}
|
||||||
return taskJobLauncherCommandLineRunner;
|
return taskJobLauncherCommandLineRunner;
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.handler;
|
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
|
* {@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
|
* 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
|
* that returns an {@link BatchStatus} of FAILED if a {@link TaskExecutor} in the
|
||||||
* {@link JobLauncher} is not specified. If a {@link TaskExecutor} is specified
|
* {@link JobLauncher} is not specified. If a {@link TaskExecutor} is specified in the
|
||||||
* in the {@link JobLauncher} then all Jobs are launched and an
|
* {@link JobLauncher} then all Jobs are launched and an exception is thrown if one or
|
||||||
* exception is thrown if one or more of the jobs has an {@link BatchStatus} of FAILED.
|
* more of the jobs has an {@link BatchStatus} of FAILED. TaskJobLauncherCommandLineRunner
|
||||||
* TaskJobLauncherCommandLineRunner can also be used to launch a specific job by
|
* can also be used to launch a specific job by providing a jobName. The
|
||||||
* providing a jobName. The TaskJobLaunchercommandLineRunner takes the place of the
|
* TaskJobLaunchercommandLineRunner takes the place of the
|
||||||
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner} when
|
* {@link org.springframework.boot.autoconfigure.batch.JobLauncherCommandLineRunner} when
|
||||||
* it is in use.
|
* it is in use.
|
||||||
*
|
*
|
||||||
@@ -70,15 +70,15 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunner {
|
public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunner {
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory
|
||||||
|
.getLog(TaskJobLauncherCommandLineRunner.class);
|
||||||
|
|
||||||
private JobLauncher taskJobLauncher;
|
private JobLauncher taskJobLauncher;
|
||||||
|
|
||||||
private JobExplorer taskJobExplorer;
|
private JobExplorer taskJobExplorer;
|
||||||
|
|
||||||
private JobRepository taskJobRepository;
|
private JobRepository taskJobRepository;
|
||||||
|
|
||||||
private static final Log logger = LogFactory
|
|
||||||
.getLog(TaskJobLauncherCommandLineRunner.class);
|
|
||||||
|
|
||||||
private List<JobExecution> jobExecutionList = new ArrayList<>();
|
private List<JobExecution> jobExecutionList = new ArrayList<>();
|
||||||
|
|
||||||
private ApplicationEventPublisher taskApplicationEventPublisher;
|
private ApplicationEventPublisher taskApplicationEventPublisher;
|
||||||
@@ -91,10 +91,12 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
* @param jobExplorer to check the job repository for previous executions
|
* @param jobExplorer to check the job repository for previous executions
|
||||||
* @param jobRepository to check if a job instance exists with the given parameters
|
* @param jobRepository to check if a job instance exists with the given parameters
|
||||||
* when running a job
|
* 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,
|
public TaskJobLauncherCommandLineRunner(JobLauncher jobLauncher,
|
||||||
JobRepository jobRepository, TaskBatchProperties taskBatchProperties) {
|
JobExplorer jobExplorer, JobRepository jobRepository,
|
||||||
|
TaskBatchProperties taskBatchProperties) {
|
||||||
super(jobLauncher, jobExplorer, jobRepository);
|
super(jobLauncher, jobExplorer, jobRepository);
|
||||||
this.taskJobLauncher = jobLauncher;
|
this.taskJobLauncher = jobLauncher;
|
||||||
this.taskJobExplorer = jobExplorer;
|
this.taskJobExplorer = jobExplorer;
|
||||||
@@ -151,7 +153,8 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
}
|
}
|
||||||
JobExecution execution = this.taskJobLauncher.run(job, parameters);
|
JobExecution execution = this.taskJobLauncher.run(job, parameters);
|
||||||
if (this.taskApplicationEventPublisher != null) {
|
if (this.taskApplicationEventPublisher != null) {
|
||||||
this.taskApplicationEventPublisher.publishEvent(new JobExecutionEvent(execution));
|
this.taskApplicationEventPublisher
|
||||||
|
.publishEvent(new JobExecutionEvent(execution));
|
||||||
}
|
}
|
||||||
this.jobExecutionList.add(execution);
|
this.jobExecutionList.add(execution);
|
||||||
if (execution.getStatus().equals(BatchStatus.FAILED)) {
|
if (execution.getStatus().equals(BatchStatus.FAILED)) {
|
||||||
@@ -168,8 +171,9 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
|
|
||||||
List<JobExecution> failedJobExecutions = new ArrayList<>();
|
List<JobExecution> failedJobExecutions = new ArrayList<>();
|
||||||
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
|
RepeatStatus repeatStatus = RepeatStatus.FINISHED;
|
||||||
for (JobExecution jobExecution : jobExecutionList) {
|
for (JobExecution jobExecution : this.jobExecutionList) {
|
||||||
JobExecution currentJobExecution = taskJobExplorer.getJobExecution(jobExecution.getId());
|
JobExecution currentJobExecution = this.taskJobExplorer
|
||||||
|
.getJobExecution(jobExecution.getId());
|
||||||
BatchStatus batchStatus = currentJobExecution.getStatus();
|
BatchStatus batchStatus = currentJobExecution.getStatus();
|
||||||
if (batchStatus.isRunning()) {
|
if (batchStatus.isRunning()) {
|
||||||
repeatStatus = RepeatStatus.CONTINUABLE;
|
repeatStatus = RepeatStatus.CONTINUABLE;
|
||||||
@@ -178,9 +182,10 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
failedJobExecutions.add(jobExecution);
|
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);
|
throwJobFailedException(failedJobExecutions);
|
||||||
}
|
}
|
||||||
return repeatStatus;
|
return repeatStatus;
|
||||||
@@ -190,8 +195,8 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
private void throwJobFailedException(List<JobExecution> failedJobExecutions) {
|
private void throwJobFailedException(List<JobExecution> failedJobExecutions) {
|
||||||
StringBuilder message = new StringBuilder("The following Jobs have failed: \n");
|
StringBuilder message = new StringBuilder("The following Jobs have failed: \n");
|
||||||
for (JobExecution failedJobExecution : failedJobExecutions) {
|
for (JobExecution failedJobExecution : failedJobExecutions) {
|
||||||
message.append(String.format("Job %s failed during " +
|
message.append(String.format("Job %s failed during "
|
||||||
"execution for job instance id %s with jobExecutionId of %s \n",
|
+ "execution for job instance id %s with jobExecutionId of %s \n",
|
||||||
failedJobExecution.getJobInstance().getJobName(),
|
failedJobExecution.getJobInstance().getJobName(),
|
||||||
failedJobExecution.getJobId(), failedJobExecution.getId()));
|
failedJobExecution.getJobId(), failedJobExecution.getId()));
|
||||||
}
|
}
|
||||||
@@ -201,6 +206,7 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
throw new TaskException(message.toString());
|
throw new TaskException(message.toString());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private JobParameters removeNonIdentifying(JobParameters parameters) {
|
private JobParameters removeNonIdentifying(JobParameters parameters) {
|
||||||
Map<String, JobParameter> parameterMap = parameters.getParameters();
|
Map<String, JobParameter> parameterMap = parameters.getParameters();
|
||||||
HashMap<String, JobParameter> copy = new HashMap<>(parameterMap);
|
HashMap<String, JobParameter> copy = new HashMap<>(parameterMap);
|
||||||
@@ -225,4 +231,5 @@ public class TaskJobLauncherCommandLineRunner extends JobLauncherCommandLineRunn
|
|||||||
merged.putAll(additionals.getParameters());
|
merged.putAll(additionals.getParameters());
|
||||||
return new JobParameters(merged);
|
return new JobParameters(merged);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.listener;
|
package org.springframework.cloud.task.batch.listener;
|
||||||
|
|
||||||
import org.springframework.batch.core.JobExecution;
|
import org.springframework.batch.core.JobExecution;
|
||||||
@@ -28,9 +29,9 @@ public interface TaskBatchDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the relationship between a task execution and a job execution.
|
* Saves the relationship between a task execution and a job execution.
|
||||||
*
|
|
||||||
* @param taskExecution task execution
|
* @param taskExecution task execution
|
||||||
* @param jobExecution job execution
|
* @param jobExecution job execution
|
||||||
*/
|
*/
|
||||||
void saveRelationship(TaskExecution taskExecution, JobExecution jobExecution);
|
void saveRelationship(TaskExecution taskExecution, JobExecution jobExecution);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.listener;
|
package org.springframework.cloud.task.batch.listener;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
import org.springframework.batch.core.JobExecution;
|
import org.springframework.batch.core.JobExecution;
|
||||||
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
|
import org.springframework.batch.core.listener.JobExecutionListenerSupport;
|
||||||
import org.springframework.cloud.task.listener.annotation.BeforeTask;
|
import org.springframework.cloud.task.listener.annotation.BeforeTask;
|
||||||
@@ -31,14 +33,14 @@ import org.springframework.util.Assert;
|
|||||||
*/
|
*/
|
||||||
public class TaskBatchExecutionListener extends JobExecutionListenerSupport {
|
public class TaskBatchExecutionListener extends JobExecutionListenerSupport {
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(TaskBatchExecutionListener.class);
|
||||||
|
|
||||||
private TaskExecution taskExecution;
|
private TaskExecution taskExecution;
|
||||||
|
|
||||||
private TaskBatchDao taskBatchDao;
|
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) {
|
public TaskBatchExecutionListener(TaskBatchDao taskBatchDao) {
|
||||||
Assert.notNull(taskBatchDao, "A TaskBatchDao is required");
|
Assert.notNull(taskBatchDao, "A TaskBatchDao is required");
|
||||||
@@ -53,14 +55,16 @@ public class TaskBatchExecutionListener extends JobExecutionListenerSupport {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void beforeJob(JobExecution jobExecution) {
|
public void beforeJob(JobExecution jobExecution) {
|
||||||
if(this.taskExecution == null) {
|
if (this.taskExecution == null) {
|
||||||
logger.warn("This job was executed outside the scope of a task but still used the task listener.");
|
logger.warn(
|
||||||
|
"This job was executed outside the scope of a task but still used the task listener.");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.info(String.format("The job execution id %s was run within the task execution %s",
|
logger.info(String.format(
|
||||||
jobExecution.getId(),
|
"The job execution id %s was run within the task execution %s",
|
||||||
this.taskExecution.getExecutionId()));
|
jobExecution.getId(), this.taskExecution.getExecutionId()));
|
||||||
taskBatchDao.saveRelationship(taskExecution, jobExecution);
|
this.taskBatchDao.saveRelationship(this.taskExecution, jobExecution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.listener.support;
|
package org.springframework.cloud.task.batch.listener.support;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
@@ -27,7 +28,7 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.StringUtils;
|
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
|
* conjunction with the JDBC based
|
||||||
* {@link org.springframework.cloud.task.repository.TaskRepository}
|
* {@link org.springframework.cloud.task.repository.TaskRepository}
|
||||||
*
|
*
|
||||||
@@ -36,10 +37,10 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class JdbcTaskBatchDao implements TaskBatchDao {
|
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 static final String INSERT_STATEMENT = "INSERT INTO %PREFIX%TASK_BATCH VALUES(?, ?)";
|
||||||
|
|
||||||
|
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
||||||
|
|
||||||
private JdbcOperations jdbcTemplate;
|
private JdbcOperations jdbcTemplate;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -68,10 +69,12 @@ public class JdbcTaskBatchDao implements TaskBatchDao {
|
|||||||
public void saveRelationship(TaskExecution taskExecution, JobExecution jobExecution) {
|
public void saveRelationship(TaskExecution taskExecution, JobExecution jobExecution) {
|
||||||
Assert.notNull(taskExecution, "A taskExecution is required");
|
Assert.notNull(taskExecution, "A taskExecution is required");
|
||||||
Assert.notNull(jobExecution, "A jobExecution 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) {
|
private String getQuery(String base) {
|
||||||
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
|
return StringUtils.replace(base, "%PREFIX%", this.tablePrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.listener.support;
|
package org.springframework.cloud.task.batch.listener.support;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -25,8 +26,10 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
|||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Map implementation of the {@link TaskBatchDao}. <p> This is intended for
|
* Map implementation of the {@link TaskBatchDao}.
|
||||||
* testing purposes only!</p>
|
* <p>
|
||||||
|
* This is intended for testing purposes only!
|
||||||
|
* </p>
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*/
|
*/
|
||||||
@@ -44,8 +47,9 @@ public class MapTaskBatchDao implements TaskBatchDao {
|
|||||||
Assert.notNull(taskExecution, "A taskExecution is required");
|
Assert.notNull(taskExecution, "A taskExecution is required");
|
||||||
Assert.notNull(jobExecution, "A jobExecution is required");
|
Assert.notNull(jobExecution, "A jobExecution is required");
|
||||||
|
|
||||||
if(this.relationships.containsKey(taskExecution.getExecutionId())) {
|
if (this.relationships.containsKey(taskExecution.getExecutionId())) {
|
||||||
this.relationships.get(taskExecution.getExecutionId()).add(jobExecution.getId());
|
this.relationships.get(taskExecution.getExecutionId())
|
||||||
|
.add(jobExecution.getId());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TreeSet<Long> jobExecutionIds = new TreeSet<>();
|
TreeSet<Long> jobExecutionIds = new TreeSet<>();
|
||||||
@@ -54,4 +58,5 @@ public class MapTaskBatchDao implements TaskBatchDao {
|
|||||||
this.relationships.put(taskExecution.getExecutionId(), jobExecutionIds);
|
this.relationships.put(taskExecution.getExecutionId(), jobExecutionIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -33,10 +34,10 @@ public interface CommandLineArgsProvider {
|
|||||||
* worker for the specified {@link ExecutionContext}.
|
* worker for the specified {@link ExecutionContext}.
|
||||||
*
|
*
|
||||||
* Note: This method is called once per partition.
|
* Note: This method is called once per partition.
|
||||||
*
|
|
||||||
* @param executionContext the unique state for the step to be executed.
|
* @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
|
* @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);
|
List<String> getCommandLineArgs(ExecutionContext executionContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -51,39 +52,57 @@ import org.springframework.util.CollectionUtils;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A {@link PartitionHandler} implementation that delegates to a {@link TaskLauncher} for
|
* <p>
|
||||||
* each of the workers. The id of the worker's StepExecution is passed as an environment
|
* A {@link PartitionHandler} implementation that delegates to a {@link TaskLauncher} for
|
||||||
* variable to the worker. The worker, bootstrapped by the
|
* 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
|
* {@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
|
* 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
|
* <p>
|
||||||
* data store (aka point the same database).</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
|
* @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;
|
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 maxWorkers = -1;
|
||||||
|
|
||||||
private int gridSize = 1;
|
private int gridSize = 1;
|
||||||
@@ -118,10 +137,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
|
|
||||||
private boolean defaultArgsAsEnvironmentVars = false;
|
private boolean defaultArgsAsEnvironmentVars = false;
|
||||||
|
|
||||||
public DeployerPartitionHandler(TaskLauncher taskLauncher,
|
public DeployerPartitionHandler(TaskLauncher taskLauncher, JobExplorer jobExplorer,
|
||||||
JobExplorer jobExplorer,
|
Resource resource, String stepName) {
|
||||||
Resource resource,
|
|
||||||
String stepName) {
|
|
||||||
Assert.notNull(taskLauncher, "A taskLauncher is required");
|
Assert.notNull(taskLauncher, "A taskLauncher is required");
|
||||||
Assert.notNull(jobExplorer, "A jobExplorer is required");
|
Assert.notNull(jobExplorer, "A jobExplorer is required");
|
||||||
Assert.notNull(resource, "A resource 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.
|
* Used to provide any environment variables to be set on each worker launched.
|
||||||
*
|
|
||||||
* @param environmentVariablesProvider an {@link EnvironmentVariablesProvider}
|
* @param environmentVariablesProvider an {@link EnvironmentVariablesProvider}
|
||||||
*/
|
*/
|
||||||
public void setEnvironmentVariablesProvider(EnvironmentVariablesProvider environmentVariablesProvider) {
|
public void setEnvironmentVariablesProvider(
|
||||||
|
EnvironmentVariablesProvider environmentVariablesProvider) {
|
||||||
this.environmentVariablesProvider = environmentVariablesProvider;
|
this.environmentVariablesProvider = environmentVariablesProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If set to true, the default args that are used internally by Spring Cloud Task and
|
* 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.
|
* Spring Batch are passed as environment variables instead of command line arguments.
|
||||||
*
|
|
||||||
* @param defaultArgsAsEnvironmentVars defaults to false
|
* @param defaultArgsAsEnvironmentVars defaults to false
|
||||||
*/
|
*/
|
||||||
public void setDefaultArgsAsEnvironmentVars(boolean defaultArgsAsEnvironmentVars) {
|
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.
|
* Used to provide any command line arguements to be passed to each worker launched.
|
||||||
*
|
|
||||||
* @param commandLineArgsProvider {@link CommandLineArgsProvider}
|
* @param commandLineArgsProvider {@link CommandLineArgsProvider}
|
||||||
*/
|
*/
|
||||||
public void setCommandLineArgsProvider(CommandLineArgsProvider commandLineArgsProvider) {
|
public void setCommandLineArgsProvider(
|
||||||
|
CommandLineArgsProvider commandLineArgsProvider) {
|
||||||
this.commandLineArgsProvider = commandLineArgsProvider;
|
this.commandLineArgsProvider = commandLineArgsProvider;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of workers to be executing at once.
|
* 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) {
|
public void setMaxWorkers(int maxWorkers) {
|
||||||
Assert.isTrue(maxWorkers != 0, "maxWorkers cannot be 0");
|
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
|
* {@link StepExecutionSplitter} to determine how many partitions to create (at the
|
||||||
* discretion of the {@link org.springframework.batch.core.partition.support.Partitioner}).
|
* discretion of the
|
||||||
*
|
* {@link org.springframework.batch.core.partition.support.Partitioner}).
|
||||||
* @param gridSize size of grid. Defaults to 1
|
* @param gridSize size of grid. Defaults to 1
|
||||||
*/
|
*/
|
||||||
public void setGridSize(int gridSize) {
|
public void setGridSize(int gridSize) {
|
||||||
this.gridSize = gridSize;
|
this.gridSize = gridSize;
|
||||||
@@ -184,25 +199,22 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The interval to check the job repository for completed steps.
|
* 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) {
|
public void setPollInterval(long pollInterval) {
|
||||||
this.pollInterval = pollInterval;
|
this.pollInterval = pollInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Timeout for the master step. This is a timeout for all workers to complete.
|
* Timeout for the master step. This is a timeout for all workers to complete.
|
||||||
*
|
* @param timeout timeout. Defaults to none (-1).
|
||||||
* @param timeout timeout. Defaults to none (-1).
|
|
||||||
*/
|
*/
|
||||||
public void setTimeout(long timeout) {
|
public void setTimeout(long timeout) {
|
||||||
this.timeout = 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}
|
* @param deploymentProperties properties to be used by the {@link TaskLauncher}
|
||||||
*/
|
*/
|
||||||
public void setDeploymentProperties(Map<String, String> deploymentProperties) {
|
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).
|
* application deployments are reused (such as CloudFoundry).
|
||||||
*
|
|
||||||
* @param applicationName The name of the application to be launched
|
* @param applicationName The name of the application to be launched
|
||||||
*/
|
*/
|
||||||
public void setApplicationName(String applicationName) {
|
public void setApplicationName(String applicationName) {
|
||||||
@@ -223,9 +234,9 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
public void beforeTask(TaskExecution taskExecution) {
|
public void beforeTask(TaskExecution taskExecution) {
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
|
|
||||||
if(this.commandLineArgsProvider == null) {
|
if (this.commandLineArgsProvider == null) {
|
||||||
SimpleCommandLineArgsProvider provider = new
|
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(
|
||||||
SimpleCommandLineArgsProvider(taskExecution);
|
taskExecution);
|
||||||
this.commandLineArgsProvider = provider;
|
this.commandLineArgsProvider = provider;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -235,8 +246,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter,
|
public Collection<StepExecution> handle(StepExecutionSplitter stepSplitter,
|
||||||
StepExecution stepExecution) throws Exception {
|
StepExecution stepExecution) throws Exception {
|
||||||
|
|
||||||
final Set<StepExecution> tempCandidates =
|
final Set<StepExecution> tempCandidates = stepSplitter.split(stepExecution,
|
||||||
stepSplitter.split(stepExecution, this.gridSize);
|
this.gridSize);
|
||||||
|
|
||||||
// Following two lines due to https://jira.spring.io/browse/BATCH-2490
|
// Following two lines due to https://jira.spring.io/browse/BATCH-2490
|
||||||
final Set<StepExecution> candidates = new HashSet<>(tempCandidates.size());
|
final Set<StepExecution> candidates = new HashSet<>(tempCandidates.size());
|
||||||
@@ -244,7 +255,7 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
|
|
||||||
int partitions = candidates.size();
|
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());
|
final Set<StepExecution> executed = new HashSet<>(candidates.size());
|
||||||
|
|
||||||
@@ -259,7 +270,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
return pollReplies(stepExecution, executed, candidates, partitions);
|
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) {
|
for (StepExecution execution : candidates) {
|
||||||
if (this.currentWorkers < this.maxWorkers || this.maxWorkers < 0) {
|
if (this.currentWorkers < this.maxWorkers || this.maxWorkers < 0) {
|
||||||
launchWorker(execution);
|
launchWorker(execution);
|
||||||
@@ -273,59 +285,59 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
private void launchWorker(StepExecution workerStepExecution) {
|
private void launchWorker(StepExecution workerStepExecution) {
|
||||||
List<String> arguments = new ArrayList<>();
|
List<String> arguments = new ArrayList<>();
|
||||||
|
|
||||||
ExecutionContext copyContext = new ExecutionContext(workerStepExecution.getExecutionContext());
|
ExecutionContext copyContext = new ExecutionContext(
|
||||||
|
workerStepExecution.getExecutionContext());
|
||||||
|
|
||||||
arguments.addAll(
|
arguments.addAll(this.commandLineArgsProvider.getCommandLineArgs(copyContext));
|
||||||
this.commandLineArgsProvider
|
|
||||||
.getCommandLineArgs(copyContext));
|
|
||||||
|
|
||||||
if(!this.defaultArgsAsEnvironmentVars) {
|
if (!this.defaultArgsAsEnvironmentVars) {
|
||||||
arguments.add(formatArgument(SPRING_CLOUD_TASK_JOB_EXECUTION_ID,
|
arguments.add(formatArgument(SPRING_CLOUD_TASK_JOB_EXECUTION_ID,
|
||||||
String.valueOf(workerStepExecution.getJobExecution().getId())));
|
String.valueOf(workerStepExecution.getJobExecution().getId())));
|
||||||
arguments.add(formatArgument(SPRING_CLOUD_TASK_STEP_EXECUTION_ID,
|
arguments.add(formatArgument(SPRING_CLOUD_TASK_STEP_EXECUTION_ID,
|
||||||
String.valueOf(workerStepExecution.getId())));
|
String.valueOf(workerStepExecution.getId())));
|
||||||
arguments.add(formatArgument(SPRING_CLOUD_TASK_STEP_NAME, this.stepName));
|
arguments.add(formatArgument(SPRING_CLOUD_TASK_STEP_NAME, this.stepName));
|
||||||
arguments.add(formatArgument(SPRING_CLOUD_TASK_NAME, String.format("%s_%s_%s",
|
arguments
|
||||||
taskExecution.getTaskName(),
|
.add(formatArgument(SPRING_CLOUD_TASK_NAME,
|
||||||
workerStepExecution.getJobExecution().getJobInstance().getJobName(),
|
String.format("%s_%s_%s", this.taskExecution.getTaskName(),
|
||||||
workerStepExecution.getStepName())));
|
workerStepExecution.getJobExecution().getJobInstance()
|
||||||
|
.getJobName(),
|
||||||
|
workerStepExecution.getStepName())));
|
||||||
arguments.add(formatArgument(SPRING_CLOUD_TASK_PARENT_EXECUTION_ID,
|
arguments.add(formatArgument(SPRING_CLOUD_TASK_PARENT_EXECUTION_ID,
|
||||||
String.valueOf(taskExecution.getExecutionId())));
|
String.valueOf(this.taskExecution.getExecutionId())));
|
||||||
}
|
}
|
||||||
|
|
||||||
copyContext = new ExecutionContext(workerStepExecution.getExecutionContext());
|
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,
|
environmentVariables.put(SPRING_CLOUD_TASK_JOB_EXECUTION_ID,
|
||||||
String.valueOf(workerStepExecution.getJobExecution().getId()));
|
String.valueOf(workerStepExecution.getJobExecution().getId()));
|
||||||
environmentVariables.put(SPRING_CLOUD_TASK_STEP_EXECUTION_ID,
|
environmentVariables.put(SPRING_CLOUD_TASK_STEP_EXECUTION_ID,
|
||||||
String.valueOf(workerStepExecution.getId()));
|
String.valueOf(workerStepExecution.getId()));
|
||||||
environmentVariables.put(SPRING_CLOUD_TASK_STEP_NAME, this.stepName);
|
environmentVariables.put(SPRING_CLOUD_TASK_STEP_NAME, this.stepName);
|
||||||
environmentVariables.put(SPRING_CLOUD_TASK_NAME, String.format("%s_%s_%s",
|
environmentVariables
|
||||||
taskExecution.getTaskName(),
|
.put(SPRING_CLOUD_TASK_NAME,
|
||||||
workerStepExecution.getJobExecution().getJobInstance().getJobName(),
|
String.format("%s_%s_%s", this.taskExecution.getTaskName(),
|
||||||
workerStepExecution.getStepName()));
|
workerStepExecution.getJobExecution().getJobInstance()
|
||||||
|
.getJobName(),
|
||||||
|
workerStepExecution.getStepName()));
|
||||||
environmentVariables.put(SPRING_CLOUD_TASK_PARENT_EXECUTION_ID,
|
environmentVariables.put(SPRING_CLOUD_TASK_PARENT_EXECUTION_ID,
|
||||||
String.valueOf(taskExecution.getExecutionId()));
|
String.valueOf(this.taskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
AppDefinition definition =
|
AppDefinition definition = new AppDefinition(resolveApplicationName(),
|
||||||
new AppDefinition(resolveApplicationName(),
|
environmentVariables);
|
||||||
environmentVariables);
|
|
||||||
|
|
||||||
AppDeploymentRequest request =
|
AppDeploymentRequest request = new AppDeploymentRequest(definition, this.resource,
|
||||||
new AppDeploymentRequest(definition,
|
this.deploymentProperties, arguments);
|
||||||
this.resource,
|
|
||||||
this.deploymentProperties,
|
|
||||||
arguments);
|
|
||||||
|
|
||||||
taskLauncher.launch(request);
|
this.taskLauncher.launch(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String resolveApplicationName() {
|
private String resolveApplicationName() {
|
||||||
if(StringUtils.hasText(this.applicationName)) {
|
if (StringUtils.hasText(this.applicationName)) {
|
||||||
return this.applicationName;
|
return this.applicationName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -338,8 +350,7 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Collection<StepExecution> pollReplies(final StepExecution masterStepExecution,
|
private Collection<StepExecution> pollReplies(final StepExecution masterStepExecution,
|
||||||
final Set<StepExecution> executed,
|
final Set<StepExecution> executed, final Set<StepExecution> candidates,
|
||||||
final Set<StepExecution> candidates,
|
|
||||||
final int size) throws Exception {
|
final int size) throws Exception {
|
||||||
|
|
||||||
final Collection<StepExecution> result = new ArrayList<>(executed.size());
|
final Collection<StepExecution> result = new ArrayList<>(executed.size());
|
||||||
@@ -351,13 +362,14 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
|
|
||||||
for (StepExecution curStepExecution : executed) {
|
for (StepExecution curStepExecution : executed) {
|
||||||
if (!result.contains(curStepExecution)) {
|
if (!result.contains(curStepExecution)) {
|
||||||
StepExecution partitionStepExecution =
|
StepExecution partitionStepExecution = DeployerPartitionHandler.this.jobExplorer
|
||||||
jobExplorer.getStepExecution(masterStepExecution.getJobExecutionId(), curStepExecution.getId());
|
.getStepExecution(masterStepExecution.getJobExecutionId(),
|
||||||
|
curStepExecution.getId());
|
||||||
|
|
||||||
BatchStatus batchStatus = partitionStepExecution.getStatus();
|
BatchStatus batchStatus = partitionStepExecution.getStatus();
|
||||||
if (batchStatus != null && isComplete(batchStatus)) {
|
if (batchStatus != null && isComplete(batchStatus)) {
|
||||||
result.add(partitionStepExecution);
|
result.add(partitionStepExecution);
|
||||||
currentWorkers--;
|
DeployerPartitionHandler.this.currentWorkers--;
|
||||||
|
|
||||||
if (!candidates.isEmpty()) {
|
if (!candidates.isEmpty()) {
|
||||||
|
|
||||||
@@ -382,8 +394,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
Poller<Collection<StepExecution>> poller = new DirectPoller<>(this.pollInterval);
|
Poller<Collection<StepExecution>> poller = new DirectPoller<>(this.pollInterval);
|
||||||
Future<Collection<StepExecution>> resultsFuture = poller.poll(callback);
|
Future<Collection<StepExecution>> resultsFuture = poller.poll(callback);
|
||||||
|
|
||||||
if (timeout >= 0) {
|
if (this.timeout >= 0) {
|
||||||
return resultsFuture.get(timeout, TimeUnit.MILLISECONDS);
|
return resultsFuture.get(this.timeout, TimeUnit.MILLISECONDS);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return resultsFuture.get();
|
return resultsFuture.get();
|
||||||
@@ -391,7 +403,8 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isComplete(BatchStatus status) {
|
private boolean isComplete(BatchStatus status) {
|
||||||
return status.equals(BatchStatus.COMPLETED) || status.isGreaterThan(BatchStatus.STARTED);
|
return status.equals(BatchStatus.COMPLETED)
|
||||||
|
|| status.isGreaterThan(BatchStatus.STARTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -401,10 +414,11 @@ public class DeployerPartitionHandler implements PartitionHandler, EnvironmentAw
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
if(this.environmentVariablesProvider == null) {
|
if (this.environmentVariablesProvider == null) {
|
||||||
this.environmentVariablesProvider =
|
this.environmentVariablesProvider = new SimpleEnvironmentVariablesProvider(
|
||||||
new SimpleEnvironmentVariablesProvider(this.environment);
|
this.environment);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
@@ -34,20 +35,24 @@ import org.springframework.core.env.Environment;
|
|||||||
import org.springframework.util.Assert;
|
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
|
* 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.
|
* <p>
|
||||||
* Specifically, the following variables are required:</p>
|
* The {@link StepExecution} is rehydrated based on the environment variables provided.
|
||||||
|
* Specifically, the following variables are required:
|
||||||
|
* </p>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_JOB_EXECUTION_ID}: The id of
|
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_JOB_EXECUTION_ID}: The id of the
|
||||||
* the JobExecution.</li>
|
* JobExecution.</li>
|
||||||
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_EXECUTION_ID}: The id of
|
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_EXECUTION_ID}: The id of the
|
||||||
* the StepExecution.</li>
|
* StepExecution.</li>
|
||||||
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_NAME}: The id of the
|
* <li>{@link DeployerPartitionHandler#SPRING_CLOUD_TASK_STEP_NAME}: The id of the bean
|
||||||
* bean definition for the Step to execute. The id must be found within the provided
|
* definition for the Step to execute. The id must be found within the provided
|
||||||
* {@link BeanFactory}</li>
|
* {@link BeanFactory}</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
@@ -65,7 +70,8 @@ public class DeployerStepExecutionHandler implements CommandLineRunner {
|
|||||||
|
|
||||||
private StepLocator stepLocator;
|
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(beanFactory, "A beanFactory is required");
|
||||||
Assert.notNull(jobExplorer, "A jobExplorer is required");
|
Assert.notNull(jobExplorer, "A jobExplorer is required");
|
||||||
Assert.notNull(jobRepository, "A jobRepository is required");
|
Assert.notNull(jobRepository, "A jobRepository is required");
|
||||||
@@ -82,38 +88,60 @@ public class DeployerStepExecutionHandler implements CommandLineRunner {
|
|||||||
|
|
||||||
validateRequest();
|
validateRequest();
|
||||||
|
|
||||||
Long jobExecutionId = Long.parseLong(environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID));
|
Long jobExecutionId = Long.parseLong(this.environment.getProperty(
|
||||||
Long stepExecutionId = Long.parseLong(environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID));
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID));
|
||||||
StepExecution stepExecution = jobExplorer.getStepExecution(jobExecutionId, stepExecutionId);
|
Long stepExecutionId = Long.parseLong(this.environment.getProperty(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID));
|
||||||
|
StepExecution stepExecution = this.jobExplorer.getStepExecution(jobExecutionId,
|
||||||
|
stepExecutionId);
|
||||||
|
|
||||||
if (stepExecution == null) {
|
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);
|
String stepName = this.environment
|
||||||
Step step = stepLocator.getStep(stepName);
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME);
|
||||||
|
Step step = this.stepLocator.getStep(stepName);
|
||||||
|
|
||||||
try {
|
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);
|
step.execute(stepExecution);
|
||||||
}
|
}
|
||||||
catch (JobInterruptedException e) {
|
catch (JobInterruptedException e) {
|
||||||
stepExecution.setStatus(BatchStatus.STOPPED);
|
stepExecution.setStatus(BatchStatus.STOPPED);
|
||||||
jobRepository.update(stepExecution);
|
this.jobRepository.update(stepExecution);
|
||||||
}
|
}
|
||||||
catch (Throwable e) {
|
catch (Throwable e) {
|
||||||
stepExecution.addFailureException(e);
|
stepExecution.addFailureException(e);
|
||||||
stepExecution.setStatus(BatchStatus.FAILED);
|
stepExecution.setStatus(BatchStatus.FAILED);
|
||||||
jobRepository.update(stepExecution);
|
this.jobRepository.update(stepExecution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateRequest() {
|
private void validateRequest() {
|
||||||
Assert.isTrue(environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID), "A job execution id is required");
|
Assert.isTrue(
|
||||||
Assert.isTrue(environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID), "A step execution id is required");
|
this.environment.containsProperty(
|
||||||
Assert.isTrue(environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME), "A step name is required");
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -24,19 +25,18 @@ import org.springframework.batch.item.ExecutionContext;
|
|||||||
* each worker in a partitioned job.
|
* each worker in a partitioned job.
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*
|
|
||||||
* @since 1.0.2
|
* @since 1.0.2
|
||||||
*/
|
*/
|
||||||
public interface EnvironmentVariablesProvider {
|
public interface EnvironmentVariablesProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a {@link Map} of Strings to be used as environment variables. This method
|
* 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
|
* will be called for each worker step. For example, if there are 5 partitions, this
|
||||||
* method will be called 5 times.
|
* method will be called 5 times.
|
||||||
*
|
|
||||||
* @param executionContext the {@link ExecutionContext} associated with the worker's
|
* @param executionContext the {@link ExecutionContext} associated with the worker's
|
||||||
* step
|
* step
|
||||||
* @return A {@link Map} of values to be used as environment variables
|
* @return A {@link Map} of values to be used as environment variables
|
||||||
*/
|
*/
|
||||||
Map<String, String> getEnvironmentVariables(ExecutionContext executionContext);
|
Map<String, String> getEnvironmentVariables(ExecutionContext executionContext);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -21,23 +22,23 @@ import java.util.Map;
|
|||||||
import org.springframework.batch.item.ExecutionContext;
|
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}.
|
* an empty {@link Map}.
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*
|
|
||||||
* @since 1.0.2
|
* @since 1.0.2
|
||||||
*/
|
*/
|
||||||
public class NoOpEnvironmentVariablesProvider implements EnvironmentVariablesProvider {
|
public class NoOpEnvironmentVariablesProvider implements EnvironmentVariablesProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @param executionContext the {@link ExecutionContext} associated with the worker's
|
* @param executionContext the {@link ExecutionContext} associated with the worker's
|
||||||
* step
|
* step
|
||||||
* @return an empty {@link Map}
|
* @return an empty {@link Map}
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, String> getEnvironmentVariables(ExecutionContext executionContext) {
|
public Map<String, String> getEnvironmentVariables(
|
||||||
|
ExecutionContext executionContext) {
|
||||||
return Collections.emptyMap();
|
return Collections.emptyMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -38,6 +39,7 @@ public class PassThroughCommandLineArgsProvider implements CommandLineArgsProvid
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getCommandLineArgs(ExecutionContext executionContext) {
|
public List<String> getCommandLineArgs(ExecutionContext executionContext) {
|
||||||
return commandLineArgs;
|
return this.commandLineArgs;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -31,7 +32,8 @@ import org.springframework.util.Assert;
|
|||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport implements CommandLineArgsProvider {
|
public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport
|
||||||
|
implements CommandLineArgsProvider {
|
||||||
|
|
||||||
private TaskExecution taskExecution;
|
private TaskExecution taskExecution;
|
||||||
|
|
||||||
@@ -56,7 +58,6 @@ public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Additional command line args to be appended.
|
* Additional command line args to be appended.
|
||||||
*
|
|
||||||
* @param appendedArgs list of arguments
|
* @param appendedArgs list of arguments
|
||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
@@ -67,17 +68,18 @@ public class SimpleCommandLineArgsProvider extends TaskExecutionListenerSupport
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getCommandLineArgs(ExecutionContext executionContext) {
|
public List<String> getCommandLineArgs(ExecutionContext executionContext) {
|
||||||
|
|
||||||
int listSize = this.taskExecution.getArguments().size() +
|
int listSize = this.taskExecution.getArguments().size()
|
||||||
(this.appendedArgs != null ? this.appendedArgs.size() : 0);
|
+ (this.appendedArgs != null ? this.appendedArgs.size() : 0);
|
||||||
|
|
||||||
List<String> args = new ArrayList<>(listSize);
|
List<String> args = new ArrayList<>(listSize);
|
||||||
|
|
||||||
args.addAll(this.taskExecution.getArguments());
|
args.addAll(this.taskExecution.getArguments());
|
||||||
|
|
||||||
if(this.appendedArgs != null) {
|
if (this.appendedArgs != null) {
|
||||||
args.addAll(this.appendedArgs);
|
args.addAll(this.appendedArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.Arrays;
|
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}
|
* Copies all existing environment variables as made available in the {@link Environment}
|
||||||
* only if includeCurrentEnvironment is set to true (default).
|
* only if includeCurrentEnvironment is set to true (default). The
|
||||||
* The <code>environmentProperties</code> option provides the ability to override any
|
* <code>environmentProperties</code> option provides the ability to override any specific
|
||||||
* specific values on an as needed basis.
|
* values on an as needed basis.
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*
|
|
||||||
* @since 1.0.2
|
* @since 1.0.2
|
||||||
*/
|
*/
|
||||||
public class SimpleEnvironmentVariablesProvider implements EnvironmentVariablesProvider {
|
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
|
* @param environmentProperties a {@link Map} of properties used to override any
|
||||||
* configured in the current {@link Environment}
|
* values configured in the current {@link Environment}
|
||||||
*/
|
*/
|
||||||
public void setEnvironmentProperties(Map<String, String> environmentProperties) {
|
public void setEnvironmentProperties(Map<String, String> environmentProperties) {
|
||||||
this.environmentProperties = environmentProperties;
|
this.environmentProperties = environmentProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Establishes if current environment variables will be included as a part of the provider.
|
* Establishes if current environment variables will be included as a part of the
|
||||||
* @param includeCurrentEnvironment true(default) include local environment properties. False do not include
|
* provider.
|
||||||
* current environment properties.
|
* @param includeCurrentEnvironment true(default) include local environment
|
||||||
|
* properties. False do not include current environment properties.
|
||||||
*/
|
*/
|
||||||
public void setIncludeCurrentEnvironment(boolean includeCurrentEnvironment) {
|
public void setIncludeCurrentEnvironment(boolean includeCurrentEnvironment) {
|
||||||
this.includeCurrentEnvironment = includeCurrentEnvironment;
|
this.includeCurrentEnvironment = includeCurrentEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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());
|
environmentProperties.putAll(getCurrentEnvironmentProperties());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,9 +91,11 @@ public class SimpleEnvironmentVariablesProvider implements EnvironmentVariablesP
|
|||||||
|
|
||||||
Set<String> keys = new HashSet<>();
|
Set<String> keys = new HashSet<>();
|
||||||
|
|
||||||
for (PropertySource<?> propertySource : ((AbstractEnvironment) this.environment).getPropertySources()) {
|
for (PropertySource<?> propertySource : ((AbstractEnvironment) this.environment)
|
||||||
|
.getPropertySources()) {
|
||||||
if (propertySource instanceof MapPropertySource) {
|
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;
|
return currentEnvironment;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,64 +1,64 @@
|
|||||||
{
|
{
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.listener.enabled",
|
"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.",
|
"description": "This property is used to determine if a task will be linked to the batch jobs that are run.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"name": "spring.cloud.task.batch.fail-on-job-failure",
|
"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.",
|
"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"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.enabled",
|
"name": "spring.cloud.task.batch.events.enabled",
|
||||||
"description": "This property is used to determine if a task should listen for batch events.",
|
"description": "This property is used to determine if a task should listen for batch events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.chunk.enabled",
|
"name": "spring.cloud.task.batch.events.chunk.enabled",
|
||||||
"description": "This property is used to determine if a task should listen for batch chunk events.",
|
"description": "This property is used to determine if a task should listen for batch chunk events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.item-process.enabled",
|
"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.",
|
"description": "This property is used to determine if a task should listen for batch item processed events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.item-read.enabled",
|
"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.",
|
"description": "This property is used to determine if a task should listen for batch item read events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.item-write.enabled",
|
"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.",
|
"description": "This property is used to determine if a task should listen for batch item write events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.job-execution.enabled",
|
"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.",
|
"description": "This property is used to determine if a task should listen for batch job execution events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.skip.enabled",
|
"name": "spring.cloud.task.batch.events.skip.enabled",
|
||||||
"description": "This property is used to determine if a task should listen for batch skip events.",
|
"description": "This property is used to determine if a task should listen for batch skip events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"defaultValue": true,
|
"defaultValue": true,
|
||||||
"name": "spring.cloud.task.batch.events.step-execution.enabled",
|
"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.",
|
"description": "This property is used to determine if a task should listen for batch step execution events.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
@@ -35,4 +35,5 @@ import org.springframework.boot.autoconfigure.ImportAutoConfiguration;
|
|||||||
@Documented
|
@Documented
|
||||||
@ImportAutoConfiguration
|
@ImportAutoConfiguration
|
||||||
public @interface TaskBatchTest {
|
public @interface TaskBatchTest {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.configuration;
|
package org.springframework.cloud.task.batch.configuration;
|
||||||
@@ -33,33 +33,33 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
*/
|
*/
|
||||||
public class TaskJobLauncherAutoConfigurationTests {
|
public class TaskJobLauncherAutoConfigurationTests {
|
||||||
|
|
||||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner().
|
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||||
withUserConfiguration(TaskBatchExecutionListenerTests.JobConfiguration.class,
|
.withUserConfiguration(TaskBatchExecutionListenerTests.JobConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class,
|
EmbeddedDataSourceConfiguration.class, BatchAutoConfiguration.class,
|
||||||
BatchAutoConfiguration.class,
|
|
||||||
TaskJobLauncherAutoConfiguration.class);
|
TaskJobLauncherAutoConfiguration.class);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoBuiltDataSourceWithTaskJobLauncherCLR() {
|
public void testAutoBuiltDataSourceWithTaskJobLauncherCLR() {
|
||||||
this.contextRunner.withPropertyValues("spring.cloud.task.batch.fail-on-job-failure=true").run(context -> {
|
this.contextRunner
|
||||||
assertThat(context).hasSingleBean(TaskJobLauncherCommandLineRunner.class);
|
.withPropertyValues("spring.cloud.task.batch.fail-on-job-failure=true")
|
||||||
assertThat(context.getBean(TaskJobLauncherCommandLineRunner.class)
|
.run(context -> {
|
||||||
.getOrder())
|
assertThat(context)
|
||||||
.isEqualTo(0);
|
.hasSingleBean(TaskJobLauncherCommandLineRunner.class);
|
||||||
});
|
assertThat(context.getBean(TaskJobLauncherCommandLineRunner.class)
|
||||||
|
.getOrder()).isEqualTo(0);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoBuiltDataSourceWithTaskJobLauncherCLROrder() {
|
public void testAutoBuiltDataSourceWithTaskJobLauncherCLROrder() {
|
||||||
this.contextRunner.
|
this.contextRunner
|
||||||
withPropertyValues("spring.cloud.task.batch.fail-on-job-failure=true",
|
.withPropertyValues("spring.cloud.task.batch.fail-on-job-failure=true",
|
||||||
"spring.cloud.task.batch.commandLineRunnerOrder=100").
|
"spring.cloud.task.batch.commandLineRunnerOrder=100")
|
||||||
run(context -> {
|
.run(context -> {
|
||||||
assertThat(context.getBean(TaskJobLauncherCommandLineRunner.class)
|
assertThat(context.getBean(TaskJobLauncherCommandLineRunner.class)
|
||||||
.getOrder())
|
.getOrder()).isEqualTo(100);
|
||||||
.isEqualTo(100);
|
});
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -69,5 +69,5 @@ public class TaskJobLauncherAutoConfigurationTests {
|
|||||||
assertThat(context).doesNotHaveBean(TaskJobLauncherCommandLineRunner.class);
|
assertThat(context).doesNotHaveBean(TaskJobLauncherCommandLineRunner.class);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.handler;
|
package org.springframework.cloud.task.batch.handler;
|
||||||
|
|
||||||
|
|
||||||
import org.assertj.core.api.AssertionsForClassTypes;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.jupiter.api.function.Executable;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
@@ -55,13 +53,14 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = {TaskJobLauncherCommandLineRunnerCoreTests.BatchConfiguration.class})
|
@ContextConfiguration(classes = {
|
||||||
|
TaskJobLauncherCommandLineRunnerCoreTests.BatchConfiguration.class })
|
||||||
public class TaskJobLauncherCommandLineRunnerCoreTests {
|
public class TaskJobLauncherCommandLineRunnerCoreTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -93,11 +92,11 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
Tasklet tasklet = (contribution, chunkContext) -> RepeatStatus.FINISHED;
|
Tasklet tasklet = (contribution, chunkContext) -> RepeatStatus.FINISHED;
|
||||||
this.step = this.steps.get("step").tasklet(tasklet).build();
|
this.step = this.steps.get("step").tasklet(tasklet).build();
|
||||||
this.job = this.jobs.get("job").start(this.step).build();
|
this.job = this.jobs.get("job").start(this.step).build();
|
||||||
this.runner = new TaskJobLauncherCommandLineRunner(this.jobLauncher, this.jobExplorer, jobRepository, new TaskBatchProperties());
|
this.runner = new TaskJobLauncherCommandLineRunner(this.jobLauncher,
|
||||||
|
this.jobExplorer, this.jobRepository, new TaskBatchProperties());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@Test
|
@Test
|
||||||
public void basicExecution() throws Exception {
|
public void basicExecution() throws Exception {
|
||||||
@@ -146,7 +145,6 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
|
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@Test
|
@Test
|
||||||
public void retryFailedExecutionOnNonRestartableJob() throws Exception {
|
public void retryFailedExecutionOnNonRestartableJob() throws Exception {
|
||||||
@@ -162,9 +160,9 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
// try to re-run a failed execution
|
// try to re-run a failed execution
|
||||||
Executable executable = () -> this.runner.execute(this.job,
|
Executable executable = () -> this.runner.execute(this.job,
|
||||||
new JobParametersBuilder().addLong("run.id", 1L).toJobParameters());
|
new JobParametersBuilder().addLong("run.id", 1L).toJobParameters());
|
||||||
Throwable exception = assertThrows(JobRestartException.class, executable);
|
assertThatExceptionOfType(JobRestartException.class)
|
||||||
AssertionsForClassTypes.assertThat(exception.getMessage())
|
.isThrownBy(executable::execute)
|
||||||
.isEqualTo("JobInstance already exists and is not restartable");
|
.withMessage("JobInstance already exists and is not restartable");
|
||||||
}
|
}
|
||||||
|
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@@ -177,12 +175,11 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
.addLong("foo", 2L, false).toJobParameters();
|
.addLong("foo", 2L, false).toJobParameters();
|
||||||
runFailedJob(jobParameters);
|
runFailedJob(jobParameters);
|
||||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||||
runFailedJob(new JobParametersBuilder(jobParameters)
|
runFailedJob(new JobParametersBuilder(jobParameters).addLong("run.id", 1L)
|
||||||
.addLong("run.id", 1L).toJobParameters());
|
.toJobParameters());
|
||||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
@Test
|
@Test
|
||||||
public void retryFailedExecutionWithDifferentNonIdentifyingParametersFromPreviousExecution()
|
public void retryFailedExecutionWithDifferentNonIdentifyingParametersFromPreviousExecution()
|
||||||
@@ -195,7 +192,7 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
runFailedJob(jobParameters);
|
runFailedJob(jobParameters);
|
||||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||||
// try to re-run a failed execution with non identifying parameters
|
// try to re-run a failed execution with non identifying parameters
|
||||||
runFailedJob( new JobParametersBuilder().addLong("run.id", 1L)
|
runFailedJob(new JobParametersBuilder().addLong("run.id", 1L)
|
||||||
.addLong("id", 2L, false).addLong("foo", 3L, false).toJobParameters());
|
.addLong("id", 2L, false).addLong("foo", 3L, false).toJobParameters());
|
||||||
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
assertThat(this.jobExplorer.getJobInstances("job", 0, 100)).hasSize(1);
|
||||||
JobInstance jobInstance = this.jobExplorer.getJobInstance(0L);
|
JobInstance jobInstance = this.jobExplorer.getJobInstance(0L);
|
||||||
@@ -216,7 +213,6 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
assertThat(parameters.getLong("foo")).isEqualTo(3L);
|
assertThat(parameters.getLong("foo")).isEqualTo(3L);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Tasklet throwingTasklet() {
|
private Tasklet throwingTasklet() {
|
||||||
return (contribution, chunkContext) -> {
|
return (contribution, chunkContext) -> {
|
||||||
throw new RuntimeException("Planned");
|
throw new RuntimeException("Planned");
|
||||||
@@ -238,13 +234,11 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
@EnableBatchProcessing
|
@EnableBatchProcessing
|
||||||
protected static class BatchConfiguration implements BatchConfigurer {
|
protected static class BatchConfiguration implements BatchConfigurer {
|
||||||
|
|
||||||
private ResourcelessTransactionManager transactionManager =
|
private ResourcelessTransactionManager transactionManager = new ResourcelessTransactionManager();
|
||||||
new ResourcelessTransactionManager();
|
|
||||||
|
|
||||||
private JobRepository jobRepository;
|
private JobRepository jobRepository;
|
||||||
|
|
||||||
private MapJobRepositoryFactoryBean jobRepositoryFactory =
|
private MapJobRepositoryFactoryBean jobRepositoryFactory = new MapJobRepositoryFactoryBean(
|
||||||
new MapJobRepositoryFactoryBean(
|
|
||||||
this.transactionManager);
|
this.transactionManager);
|
||||||
|
|
||||||
public BatchConfiguration() throws Exception {
|
public BatchConfiguration() throws Exception {
|
||||||
@@ -275,4 +269,5 @@ public class TaskJobLauncherCommandLineRunnerCoreTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.handler;
|
package org.springframework.cloud.task.batch.handler;
|
||||||
@@ -20,6 +20,7 @@ import java.util.Set;
|
|||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.assertj.core.api.Condition;
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.jupiter.api.function.Executable;
|
import org.junit.jupiter.api.function.Executable;
|
||||||
@@ -59,18 +60,18 @@ import org.springframework.data.domain.Page;
|
|||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
||||||
|
|
||||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class TaskJobLauncherCommandLineRunnerTests {
|
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 job instance id 1 with jobExecutionId of 1 \n";
|
||||||
|
|
||||||
private static final String DEFAULT_ERROR_MESSAGE = "The following Jobs have failed: \n" +
|
private ConfigurableApplicationContext applicationContext;
|
||||||
"Job jobA failed during execution for job instance id 1 with jobExecutionId of 1 \n";
|
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
@@ -82,20 +83,22 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testTaskJobLauncherCLRSuccessFail() {
|
public void testTaskJobLauncherCLRSuccessFail() {
|
||||||
String[] enabledArgs = new String[] {
|
String[] enabledArgs = new String[] {
|
||||||
"--spring.cloud.task.batch.failOnJobFailure=true"};
|
"--spring.cloud.task.batch.failOnJobFailure=true" };
|
||||||
validateForFail(DEFAULT_ERROR_MESSAGE, TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class,
|
validateForFail(DEFAULT_ERROR_MESSAGE,
|
||||||
|
TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class,
|
||||||
enabledArgs);
|
enabledArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the task will return an exit code other than zero if the
|
* Verifies that the task will return an exit code other than zero if the job fails
|
||||||
* job fails with the deprecated EnableTask annotation.
|
* with the deprecated EnableTask annotation.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTaskJobLauncherCLRSuccessFailWithAnnotation() {
|
public void testTaskJobLauncherCLRSuccessFailWithAnnotation() {
|
||||||
String[] enabledArgs = new String[] {
|
String[] enabledArgs = new String[] {
|
||||||
"--spring.cloud.task.batch.failOnJobFailure=true"};
|
"--spring.cloud.task.batch.failOnJobFailure=true" };
|
||||||
validateForFail(DEFAULT_ERROR_MESSAGE, TaskJobLauncherCommandLineRunnerTests.JobWithFailureAnnotatedConfiguration.class,
|
validateForFail(DEFAULT_ERROR_MESSAGE,
|
||||||
|
TaskJobLauncherCommandLineRunnerTests.JobWithFailureAnnotatedConfiguration.class,
|
||||||
enabledArgs);
|
enabledArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -103,8 +106,9 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
public void testTaskJobLauncherCLRSuccessFailWithTaskExecutor() {
|
public void testTaskJobLauncherCLRSuccessFailWithTaskExecutor() {
|
||||||
String[] enabledArgs = new String[] {
|
String[] enabledArgs = new String[] {
|
||||||
"--spring.cloud.task.batch.failOnJobFailure=true",
|
"--spring.cloud.task.batch.failOnJobFailure=true",
|
||||||
"--spring.cloud.task.batch.failOnJobFailurePollInterval=500"};
|
"--spring.cloud.task.batch.failOnJobFailurePollInterval=500" };
|
||||||
validateForFail(DEFAULT_ERROR_MESSAGE, TaskJobLauncherCommandLineRunnerTests.JobWithFailureTaskExecutorConfiguration.class,
|
validateForFail(DEFAULT_ERROR_MESSAGE,
|
||||||
|
TaskJobLauncherCommandLineRunnerTests.JobWithFailureTaskExecutorConfiguration.class,
|
||||||
enabledArgs);
|
enabledArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,11 +116,12 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
public void testTaskJobLauncherPickOneJob() {
|
public void testTaskJobLauncherPickOneJob() {
|
||||||
String[] enabledArgs = new String[] {
|
String[] enabledArgs = new String[] {
|
||||||
"--spring.cloud.task.batch.fail-on-job-failure=true",
|
"--spring.cloud.task.batch.fail-on-job-failure=true",
|
||||||
"--spring.cloud.task.batch.jobNames=jobSucceed"};
|
"--spring.cloud.task.batch.jobNames=jobSucceed" };
|
||||||
boolean isExceptionThrown = false;
|
boolean isExceptionThrown = false;
|
||||||
try {
|
try {
|
||||||
this.applicationContext = SpringApplication
|
this.applicationContext = SpringApplication.run(new Class[] {
|
||||||
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class }, enabledArgs);
|
TaskJobLauncherCommandLineRunnerTests.JobWithFailureConfiguration.class },
|
||||||
|
enabledArgs);
|
||||||
}
|
}
|
||||||
catch (IllegalStateException exception) {
|
catch (IllegalStateException exception) {
|
||||||
isExceptionThrown = true;
|
isExceptionThrown = true;
|
||||||
@@ -128,40 +133,51 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testCommandLineRunnerSetToFalse() {
|
public void testCommandLineRunnerSetToFalse() {
|
||||||
String[] enabledArgs = new String[] {};
|
String[] enabledArgs = new String[] {};
|
||||||
this.applicationContext = SpringApplication
|
this.applicationContext = SpringApplication.run(
|
||||||
.run(new Class[] { TaskJobLauncherCommandLineRunnerTests.JobConfiguration.class }, enabledArgs);
|
new Class[] {
|
||||||
|
TaskJobLauncherCommandLineRunnerTests.JobConfiguration.class },
|
||||||
|
enabledArgs);
|
||||||
validateContext();
|
validateContext();
|
||||||
assertThat(applicationContext.getBean(JobLauncherCommandLineRunner.class)).isNotNull();
|
assertThat(this.applicationContext.getBean(JobLauncherCommandLineRunner.class))
|
||||||
|
.isNotNull();
|
||||||
|
|
||||||
Executable executable = () -> applicationContext.getBean(TaskJobLauncherCommandLineRunner.class);
|
Executable executable = () -> this.applicationContext
|
||||||
|
.getBean(TaskJobLauncherCommandLineRunner.class);
|
||||||
|
|
||||||
Throwable exception = assertThrows(NoSuchBeanDefinitionException.class, executable);
|
assertThatExceptionOfType(NoSuchBeanDefinitionException.class)
|
||||||
assertThat(exception.getMessage()).isEqualTo("No qualifying bean of type " +
|
.isThrownBy(executable::execute).withMessage("No qualifying bean of type "
|
||||||
"'org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner' available");
|
+ "'org.springframework.cloud.task.batch.handler.TaskJobLauncherCommandLineRunner' available");
|
||||||
validateContext();
|
validateContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateContext() {
|
private void validateContext() {
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application", PageRequest.of(0, 1));
|
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application",
|
||||||
|
PageRequest.of(0, 1));
|
||||||
|
|
||||||
Set<Long> jobExecutionIds = taskExplorer
|
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(
|
||||||
.getJobExecutionIdsByTaskExecutionId(page.iterator().next().getExecutionId());
|
page.iterator().next().getExecutionId());
|
||||||
|
|
||||||
assertThat(jobExecutionIds.size()).isEqualTo(1);
|
assertThat(jobExecutionIds.size()).isEqualTo(1);
|
||||||
assertThat(taskExplorer.getTaskExecution(jobExecutionIds.iterator().next()).getExecutionId()).isEqualTo(1);
|
assertThat(taskExplorer.getTaskExecution(jobExecutionIds.iterator().next())
|
||||||
|
.getExecutionId()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateForFail(String errorMessage, Class clazz, String [] enabledArgs) {
|
private void validateForFail(String errorMessage, Class clazz, String[] enabledArgs) {
|
||||||
Executable executable = () -> this.applicationContext = SpringApplication
|
Executable executable = () -> this.applicationContext = SpringApplication.run(
|
||||||
.run(new Class[] { clazz,PropertyPlaceholderAutoConfiguration.class}, enabledArgs);
|
new Class[] { clazz, PropertyPlaceholderAutoConfiguration.class },
|
||||||
|
enabledArgs);
|
||||||
|
|
||||||
Throwable exception = assertThrows(IllegalStateException.class, executable);
|
assertThatExceptionOfType(IllegalStateException.class)
|
||||||
assertThat(exception.getCause().getMessage()).isEqualTo(errorMessage);
|
.isThrownBy(executable::execute).has(new Condition<Throwable>() {
|
||||||
|
@Override
|
||||||
|
public boolean matches(Throwable value) {
|
||||||
|
return errorMessage.equals(value.getCause().getMessage());
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@EnableBatchProcessing
|
@EnableBatchProcessing
|
||||||
@TaskBatchTest
|
@TaskBatchTest
|
||||||
@Import(EmbeddedDataSourceConfiguration.class)
|
@Import(EmbeddedDataSourceConfiguration.class)
|
||||||
@@ -176,25 +192,23 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job job() {
|
public Job job() {
|
||||||
return jobBuilderFactory.get("job")
|
return this.jobBuilderFactory.get("job")
|
||||||
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
.start(this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
|
ChunkContext chunkContext) {
|
||||||
System.out.println("Executed");
|
System.out.println("Executed");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableBatchProcessing
|
@EnableBatchProcessing
|
||||||
@ImportAutoConfiguration({
|
@ImportAutoConfiguration({ PropertyPlaceholderAutoConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
BatchAutoConfiguration.class, TaskBatchAutoConfiguration.class,
|
||||||
BatchAutoConfiguration.class,
|
TaskJobLauncherAutoConfiguration.class, SingleTaskConfiguration.class,
|
||||||
TaskBatchAutoConfiguration.class,
|
|
||||||
TaskJobLauncherAutoConfiguration.class,
|
|
||||||
SingleTaskConfiguration.class,
|
|
||||||
SimpleTaskAutoConfiguration.class })
|
SimpleTaskAutoConfiguration.class })
|
||||||
@Import(EmbeddedDataSourceConfiguration.class)
|
@Import(EmbeddedDataSourceConfiguration.class)
|
||||||
@EnableTask
|
@EnableTask
|
||||||
@@ -208,50 +222,54 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job jobFail() {
|
public Job jobFail() {
|
||||||
return jobBuilderFactory.get("jobA")
|
return this.jobBuilderFactory.get("jobA")
|
||||||
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
.start(this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution,
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
ChunkContext chunkContext)
|
ChunkContext chunkContext) throws Exception {
|
||||||
throws Exception {
|
|
||||||
System.out.println("Executed");
|
System.out.println("Executed");
|
||||||
throw new IllegalStateException("WHOOPS");
|
throw new IllegalStateException("WHOOPS");
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job jobFun() {
|
public Job jobFun() {
|
||||||
return jobBuilderFactory.get("jobSucceed")
|
return this.jobBuilderFactory.get("jobSucceed").start(
|
||||||
.start(stepBuilderFactory.get("step1Succeed").tasklet(new Tasklet() {
|
this.stepBuilderFactory.get("step1Succeed").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution,
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
ChunkContext chunkContext) {
|
ChunkContext chunkContext) {
|
||||||
System.out.println("Executed");
|
System.out.println("Executed");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
@EnableTask
|
||||||
public static class JobWithFailureAnnotatedConfiguration extends JobWithFailureConfiguration{
|
public static class JobWithFailureAnnotatedConfiguration
|
||||||
|
extends JobWithFailureConfiguration {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class JobWithFailureTaskExecutorConfiguration extends JobWithFailureConfiguration{
|
public static class JobWithFailureTaskExecutorConfiguration
|
||||||
|
extends JobWithFailureConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public BatchConfigurer batchConfigurer(DataSource dataSource) {
|
public BatchConfigurer batchConfigurer(DataSource dataSource) {
|
||||||
return new TestBatchConfigurer(dataSource);
|
return new TestBatchConfigurer(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestBatchConfigurer extends DefaultBatchConfigurer{
|
private static class TestBatchConfigurer extends DefaultBatchConfigurer {
|
||||||
public TestBatchConfigurer(DataSource dataSource) {
|
|
||||||
|
TestBatchConfigurer(DataSource dataSource) {
|
||||||
super(dataSource);
|
super(dataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JobLauncher createJobLauncher() throws Exception {
|
protected JobLauncher createJobLauncher() throws Exception {
|
||||||
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
|
||||||
jobLauncher.setJobRepository(getJobRepository());
|
jobLauncher.setJobRepository(getJobRepository());
|
||||||
@@ -259,5 +277,7 @@ public class TaskJobLauncherCommandLineRunnerTests {
|
|||||||
jobLauncher.afterPropertiesSet();
|
jobLauncher.afterPropertiesSet();
|
||||||
return jobLauncher;
|
return jobLauncher;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,23 @@
|
|||||||
/*
|
/*
|
||||||
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.listener;
|
package org.springframework.cloud.task.batch.listener;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.junit.After;
|
import org.junit.After;
|
||||||
@@ -56,8 +57,8 @@ public class PrefixTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testPrefix() {
|
public void testPrefix() {
|
||||||
this.applicationContext = SpringApplication.run(
|
this.applicationContext = SpringApplication.run(JobConfiguration.class,
|
||||||
JobConfiguration.class, "--spring.cloud.task.tablePrefix=FOO_");
|
"--spring.cloud.task.tablePrefix=FOO_");
|
||||||
|
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
@@ -80,22 +81,19 @@ public class PrefixTests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job job() {
|
public Job job() {
|
||||||
return jobBuilderFactory.get("job")
|
return this.jobBuilderFactory.get("job").start(this.stepBuilderFactory
|
||||||
.start(stepBuilderFactory.get("step1")
|
.get("step1").tasklet((contribution, chunkContext) -> {
|
||||||
.tasklet((contribution, chunkContext) -> {
|
|
||||||
System.out.println("Executed");
|
System.out.println("Executed");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public DataSource dataSource() {
|
public DataSource dataSource() {
|
||||||
return new EmbeddedDatabaseBuilder()
|
return new EmbeddedDatabaseBuilder().addScript("classpath:schema-h2.sql")
|
||||||
.addScript("classpath:schema-h2.sql")
|
.setType(EmbeddedDatabaseType.H2).build();
|
||||||
.setType(EmbeddedDatabaseType.H2)
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.listener;
|
package org.springframework.cloud.task.batch.listener;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -61,7 +62,7 @@ import org.springframework.data.domain.PageRequest;
|
|||||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
@@ -75,15 +76,14 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
if(this.applicationContext != null && this.applicationContext.isActive()) {
|
if (this.applicationContext != null && this.applicationContext.isActive()) {
|
||||||
this.applicationContext.close();
|
this.applicationContext.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutobuiltDataSource() {
|
public void testAutobuiltDataSource() {
|
||||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
this.applicationContext = SpringApplication.run(JobConfiguration.class, ARGS);
|
||||||
ARGS);
|
|
||||||
validateContext();
|
validateContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,28 +96,28 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test(expected = AssertionError.class)
|
||||||
public void testNoAutoConfigurationEnable() {
|
public void testNoAutoConfigurationEnable() {
|
||||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
this.applicationContext = SpringApplication.run(JobConfiguration.class,
|
||||||
"--spring.cloud.task.batch.listener.enable=false");
|
"--spring.cloud.task.batch.listener.enable=false");
|
||||||
validateContext();
|
validateContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = AssertionError.class)
|
@Test(expected = AssertionError.class)
|
||||||
public void testNoAutoConfigurationBothDisabled() {
|
public void testNoAutoConfigurationBothDisabled() {
|
||||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
this.applicationContext = SpringApplication.run(JobConfiguration.class,
|
||||||
"--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();
|
validateContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoConfigurationEnable() {
|
public void testAutoConfigurationEnable() {
|
||||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
this.applicationContext = SpringApplication.run(JobConfiguration.class,
|
||||||
"--spring.cloud.task.batch.listener.enable=true");
|
"--spring.cloud.task.batch.listener.enable=true");
|
||||||
validateContext();
|
validateContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testAutoConfigurationEnabled() {
|
public void testAutoConfigurationEnabled() {
|
||||||
this.applicationContext = SpringApplication.run(JobConfiguration.class ,
|
this.applicationContext = SpringApplication.run(JobConfiguration.class,
|
||||||
"--spring.cloud.task.batch.listener.enabled=true");
|
"--spring.cloud.task.batch.listener.enabled=true");
|
||||||
validateContext();
|
validateContext();
|
||||||
}
|
}
|
||||||
@@ -132,26 +132,34 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
private void validateContext() {
|
private void validateContext() {
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application", PageRequest.of(0, 1));
|
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application",
|
||||||
|
PageRequest.of(0, 1));
|
||||||
|
|
||||||
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(page.iterator().next().getExecutionId());
|
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(
|
||||||
|
page.iterator().next().getExecutionId());
|
||||||
|
|
||||||
assertEquals(1, jobExecutionIds.size());
|
assertThat(jobExecutionIds.size()).isEqualTo(1);
|
||||||
assertEquals(1, taskExplorer.getTaskExecution(jobExecutionIds.iterator().next()).getExecutionId());
|
assertThat(taskExplorer.getTaskExecution(jobExecutionIds.iterator().next())
|
||||||
|
.getExecutionId()).isEqualTo(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultipleDataSources() {
|
public void testMultipleDataSources() {
|
||||||
this.applicationContext = SpringApplication.run(JobConfigurationMultipleDataSources.class, ARGS);
|
this.applicationContext = SpringApplication
|
||||||
|
.run(JobConfigurationMultipleDataSources.class, ARGS);
|
||||||
|
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application", PageRequest.of(0, 1));
|
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application",
|
||||||
|
PageRequest.of(0, 1));
|
||||||
|
|
||||||
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(page.iterator().next().getExecutionId());
|
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(
|
||||||
|
page.iterator().next().getExecutionId());
|
||||||
|
|
||||||
assertEquals(1, jobExecutionIds.size());
|
assertThat(jobExecutionIds.size()).isEqualTo(1);
|
||||||
assertEquals(1, taskExplorer.getTaskExecution(jobExecutionIds.iterator().next()).getExecutionId());
|
assertThat(taskExplorer.getTaskExecution(jobExecutionIds.iterator().next())
|
||||||
|
.getExecutionId()).isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -160,11 +168,13 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application", PageRequest.of(0, 1));
|
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application",
|
||||||
|
PageRequest.of(0, 1));
|
||||||
|
|
||||||
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(page.iterator().next().getExecutionId());
|
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(
|
||||||
|
page.iterator().next().getExecutionId());
|
||||||
|
|
||||||
assertEquals(0, jobExecutionIds.size());
|
assertThat(jobExecutionIds.size()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -173,28 +183,39 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application", PageRequest.of(0, 1));
|
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application",
|
||||||
|
PageRequest.of(0, 1));
|
||||||
|
|
||||||
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(page.iterator().next().getExecutionId());
|
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(
|
||||||
|
page.iterator().next().getExecutionId());
|
||||||
|
|
||||||
assertEquals(1, jobExecutionIds.size());
|
assertThat(jobExecutionIds.size()).isEqualTo(1);
|
||||||
assertEquals(1, (long) taskExplorer.getTaskExecutionIdByJobExecutionId(jobExecutionIds.iterator().next()));
|
assertThat((long) taskExplorer
|
||||||
|
.getTaskExecutionIdByJobExecutionId(jobExecutionIds.iterator().next()))
|
||||||
|
.isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultipleJobs() {
|
public void testMultipleJobs() {
|
||||||
this.applicationContext = SpringApplication.run(MultipleJobConfiguration.class, ARGS);
|
this.applicationContext = SpringApplication.run(MultipleJobConfiguration.class,
|
||||||
|
ARGS);
|
||||||
|
|
||||||
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = this.applicationContext.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application", PageRequest.of(0, 1));
|
Page<TaskExecution> page = taskExplorer.findTaskExecutionsByName("application",
|
||||||
|
PageRequest.of(0, 1));
|
||||||
|
|
||||||
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(page.iterator().next().getExecutionId());
|
Set<Long> jobExecutionIds = taskExplorer.getJobExecutionIdsByTaskExecutionId(
|
||||||
|
page.iterator().next().getExecutionId());
|
||||||
|
|
||||||
assertEquals(2, jobExecutionIds.size());
|
assertThat(jobExecutionIds.size()).isEqualTo(2);
|
||||||
Iterator<Long> jobExecutionIdsIterator = jobExecutionIds.iterator();
|
Iterator<Long> jobExecutionIdsIterator = jobExecutionIds.iterator();
|
||||||
assertEquals(1, (long) taskExplorer.getTaskExecutionIdByJobExecutionId(jobExecutionIdsIterator.next()));
|
assertThat((long) taskExplorer
|
||||||
assertEquals(1, (long) taskExplorer.getTaskExecutionIdByJobExecutionId(jobExecutionIdsIterator.next()));
|
.getTaskExecutionIdByJobExecutionId(jobExecutionIdsIterator.next()))
|
||||||
|
.isEqualTo(1);
|
||||||
|
assertThat((long) taskExplorer
|
||||||
|
.getTaskExecutionIdByJobExecutionId(jobExecutionIdsIterator.next()))
|
||||||
|
.isEqualTo(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -204,27 +225,26 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
jobNames.add("job2");
|
jobNames.add("job2");
|
||||||
jobNames.add("TESTOBJECT");
|
jobNames.add("TESTOBJECT");
|
||||||
|
|
||||||
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor =
|
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor = beanPostProcessor(
|
||||||
beanPostProcessor(jobNames);
|
jobNames);
|
||||||
|
|
||||||
SimpleJob testObject = new SimpleJob();
|
SimpleJob testObject = new SimpleJob();
|
||||||
SimpleJob bean = (SimpleJob) beanPostProcessor.
|
SimpleJob bean = (SimpleJob) beanPostProcessor
|
||||||
postProcessBeforeInitialization(testObject,"TESTOBJECT");
|
.postProcessBeforeInitialization(testObject, "TESTOBJECT");
|
||||||
assertEquals(testObject,bean);
|
assertThat(bean).isEqualTo(testObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBatchExecutionListenerBeanPostProcessorWithEmptyJobNames() {
|
public void testBatchExecutionListenerBeanPostProcessorWithEmptyJobNames() {
|
||||||
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor =
|
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor = beanPostProcessor(
|
||||||
beanPostProcessor(Collections.emptyList());
|
Collections.emptyList());
|
||||||
|
|
||||||
SimpleJob testObject = new SimpleJob();
|
SimpleJob testObject = new SimpleJob();
|
||||||
SimpleJob bean = (SimpleJob) beanPostProcessor.
|
SimpleJob bean = (SimpleJob) beanPostProcessor
|
||||||
postProcessBeforeInitialization(testObject,"TESTOBJECT");
|
.postProcessBeforeInitialization(testObject, "TESTOBJECT");
|
||||||
assertEquals(testObject,bean);
|
assertThat(bean).isEqualTo(testObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test(expected = IllegalArgumentException.class)
|
@Test(expected = IllegalArgumentException.class)
|
||||||
public void testBatchExecutionListenerBeanPostProcessorNullJobNames() {
|
public void testBatchExecutionListenerBeanPostProcessorNullJobNames() {
|
||||||
beanPostProcessor(null);
|
beanPostProcessor(null);
|
||||||
@@ -232,16 +252,14 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
private TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor(
|
private TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor(
|
||||||
List<String> jobNames) {
|
List<String> jobNames) {
|
||||||
this.applicationContext = SpringApplication.run(new Class[] {JobConfiguration.class,
|
this.applicationContext = SpringApplication.run(new Class[] {
|
||||||
PropertyPlaceholderAutoConfiguration.class, EmbeddedDataSourceConfiguration.class,
|
JobConfiguration.class, PropertyPlaceholderAutoConfiguration.class,
|
||||||
BatchAutoConfiguration.class,
|
EmbeddedDataSourceConfiguration.class, BatchAutoConfiguration.class,
|
||||||
TaskBatchAutoConfiguration.class,
|
TaskBatchAutoConfiguration.class, SimpleTaskAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
|
||||||
SingleTaskConfiguration.class }, ARGS);
|
SingleTaskConfiguration.class }, ARGS);
|
||||||
|
|
||||||
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor =
|
TaskBatchExecutionListenerBeanPostProcessor beanPostProcessor = this.applicationContext
|
||||||
this.applicationContext.getBean(
|
.getBean(TaskBatchExecutionListenerBeanPostProcessor.class);
|
||||||
TaskBatchExecutionListenerBeanPostProcessor.class);
|
|
||||||
|
|
||||||
beanPostProcessor.setJobNames(jobNames);
|
beanPostProcessor.setJobNames(jobNames);
|
||||||
return beanPostProcessor;
|
return beanPostProcessor;
|
||||||
@@ -269,16 +287,17 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job job() {
|
public Job job() {
|
||||||
return jobBuilderFactory.get("job")
|
return this.jobBuilderFactory.get("job")
|
||||||
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
.start(this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
|
ChunkContext chunkContext) throws Exception {
|
||||||
System.out.println("Executed");
|
System.out.println("Executed");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableBatchProcessing
|
@EnableBatchProcessing
|
||||||
@@ -298,14 +317,18 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
return new FactoryBean<Job>() {
|
return new FactoryBean<Job>() {
|
||||||
@Override
|
@Override
|
||||||
public Job getObject() throws Exception {
|
public Job getObject() throws Exception {
|
||||||
return jobBuilderFactory.get("job")
|
return JobFactoryBeanConfiguration.this.jobBuilderFactory.get("job")
|
||||||
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
.start(JobFactoryBeanConfiguration.this.stepBuilderFactory
|
||||||
@Override
|
.get("step1").tasklet(new Tasklet() {
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
@Override
|
||||||
System.out.println("Executed");
|
public RepeatStatus execute(
|
||||||
return RepeatStatus.FINISHED;
|
StepContribution contribution,
|
||||||
}
|
ChunkContext chunkContext)
|
||||||
}).build())
|
throws Exception {
|
||||||
|
System.out.println("Executed");
|
||||||
|
return RepeatStatus.FINISHED;
|
||||||
|
}
|
||||||
|
}).build())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,6 +343,7 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableBatchProcessing
|
@EnableBatchProcessing
|
||||||
@@ -336,34 +360,31 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job job() {
|
public Job job() {
|
||||||
return jobBuilderFactory.get("job")
|
return this.jobBuilderFactory.get("job")
|
||||||
.start(stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
.start(this.stepBuilderFactory.get("step1").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
|
ChunkContext chunkContext) throws Exception {
|
||||||
System.out.println("Executed");
|
System.out.println("Executed");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@Primary
|
@Primary
|
||||||
public DataSource myDataSource() {
|
public DataSource myDataSource() {
|
||||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
|
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
|
||||||
.setType(EmbeddedDatabaseType.H2)
|
.setType(EmbeddedDatabaseType.H2).setName("myDataSource");
|
||||||
.setName("myDataSource");
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public DataSource incorrectDataSource() {
|
public DataSource incorrectDataSource() {
|
||||||
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
|
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
|
||||||
.setType(EmbeddedDatabaseType.H2)
|
.setType(EmbeddedDatabaseType.H2).setName("incorrectDataSource");
|
||||||
.setName("incorrectDataSource");
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskConfigurer taskConfigurer() {
|
public TaskConfigurer taskConfigurer() {
|
||||||
@@ -374,6 +395,7 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
public DefaultBatchConfigurer batchConfigurer() {
|
public DefaultBatchConfigurer batchConfigurer() {
|
||||||
return new DefaultBatchConfigurer(myDataSource());
|
return new DefaultBatchConfigurer(myDataSource());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableBatchProcessing
|
@EnableBatchProcessing
|
||||||
@@ -390,28 +412,30 @@ public class TaskBatchExecutionListenerTests {
|
|||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job job1() {
|
public Job job1() {
|
||||||
return jobBuilderFactory.get("job1")
|
return this.jobBuilderFactory.get("job1").start(
|
||||||
.start(stepBuilderFactory.get("job1step1").tasklet(new Tasklet() {
|
this.stepBuilderFactory.get("job1step1").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
|
ChunkContext chunkContext) throws Exception {
|
||||||
System.out.println("Executed job1");
|
System.out.println("Executed job1");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public Job job2() {
|
public Job job2() {
|
||||||
return jobBuilderFactory.get("job2")
|
return this.jobBuilderFactory.get("job2").start(
|
||||||
.start(stepBuilderFactory.get("job2step1").tasklet(new Tasklet() {
|
this.stepBuilderFactory.get("job2step1").tasklet(new Tasklet() {
|
||||||
@Override
|
@Override
|
||||||
public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) throws Exception {
|
public RepeatStatus execute(StepContribution contribution,
|
||||||
|
ChunkContext chunkContext) throws Exception {
|
||||||
System.out.println("Executed job2");
|
System.out.println("Executed job2");
|
||||||
return RepeatStatus.FINISHED;
|
return RepeatStatus.FINISHED;
|
||||||
}
|
}
|
||||||
}).build())
|
}).build()).build();
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2016-2017 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -50,9 +51,7 @@ import org.springframework.core.env.Environment;
|
|||||||
import org.springframework.core.io.Resource;
|
import org.springframework.core.io.Resource;
|
||||||
import org.springframework.mock.env.MockEnvironment;
|
import org.springframework.mock.env.MockEnvironment;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.mockito.Mockito.any;
|
import static org.mockito.Mockito.any;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
@@ -64,6 +63,9 @@ import static org.mockito.Mockito.when;
|
|||||||
*/
|
*/
|
||||||
public class DeployerPartitionHandlerTests {
|
public class DeployerPartitionHandlerTests {
|
||||||
|
|
||||||
|
@Captor
|
||||||
|
ArgumentCaptor<AppDeploymentRequest> appDeploymentRequestArgumentCaptor;
|
||||||
|
|
||||||
@Mock
|
@Mock
|
||||||
private TaskLauncher taskLauncher;
|
private TaskLauncher taskLauncher;
|
||||||
|
|
||||||
@@ -81,8 +83,6 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
private Environment environment;
|
private Environment environment;
|
||||||
|
|
||||||
@Captor ArgumentCaptor<AppDeploymentRequest> appDeploymentRequestArgumentCaptor;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
@@ -91,27 +91,33 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConstructorValidation() {
|
public void testConstructorValidation() {
|
||||||
validateConstructorValidation(null, null, null, null, "A taskLauncher is required");
|
validateConstructorValidation(null, null, null, null,
|
||||||
validateConstructorValidation(this.taskLauncher, null, null, null, "A jobExplorer is required");
|
"A taskLauncher is required");
|
||||||
validateConstructorValidation(this.taskLauncher, this.jobExplorer, null, null, "A resource is required");
|
validateConstructorValidation(this.taskLauncher, null, null, null,
|
||||||
validateConstructorValidation(this.taskLauncher, this.jobExplorer, this.resource, null, "A step name is required");
|
"A jobExplorer is required");
|
||||||
|
validateConstructorValidation(this.taskLauncher, this.jobExplorer, null, null,
|
||||||
|
"A resource is required");
|
||||||
|
validateConstructorValidation(this.taskLauncher, this.jobExplorer, this.resource,
|
||||||
|
null, "A step name is required");
|
||||||
|
|
||||||
new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step-name");
|
new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource,
|
||||||
|
"step-name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoPartitions() throws Exception {
|
public void testNoPartitions() throws Exception {
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
StepExecution stepExecution = new StepExecution("step1", new JobExecution(1L));
|
StepExecution stepExecution = new StepExecution("step1", new JobExecution(1L));
|
||||||
|
|
||||||
when(this.splitter.split(stepExecution, 1)).thenReturn(new HashSet<StepExecution>());
|
when(this.splitter.split(stepExecution, 1)).thenReturn(new HashSet<>());
|
||||||
|
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, stepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter, stepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher, never()).launch((AppDeploymentRequest) any());
|
verify(this.taskLauncher, never()).launch((AppDeploymentRequest) any());
|
||||||
assertTrue(results.isEmpty());
|
assertThat(results.isEmpty()).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -121,9 +127,11 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish = getStepExecutionFinish(workerStepExecutionStart, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution();
|
TaskExecution taskExecution = new TaskExecution();
|
||||||
@@ -133,32 +141,40 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart);
|
stepExecutions.add(workerStepExecutionStart);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
|
.thenReturn(workerStepExecutionFinish);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
|
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher)
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
||||||
|
|
||||||
assertEquals(this.resource, request.getResource());
|
assertThat(request.getResource()).isEqualTo(this.resource);
|
||||||
assertEquals(0, request.getDeploymentProperties().size());
|
assertThat(request.getDeploymentProperties().size()).isEqualTo(0);
|
||||||
|
|
||||||
AppDefinition appDefinition = request.getDefinition();
|
AppDefinition appDefinition = request.getDefinition();
|
||||||
|
|
||||||
assertEquals("partitionedJobTask", appDefinition.getName());
|
assertThat(appDefinition.getName()).isEqualTo("partitionedJobTask");
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")));
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")));
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")))
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1")));
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1"))).isTrue();
|
||||||
|
|
||||||
assertEquals(1, results.size());
|
assertThat(results.size()).isEqualTo(1);
|
||||||
StepExecution resultStepExecution = results.iterator().next();
|
StepExecution resultStepExecution = results.iterator().next();
|
||||||
assertEquals(BatchStatus.COMPLETED, resultStepExecution.getStatus());
|
assertThat(resultStepExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
assertEquals("step1:partition1", resultStepExecution.getStepName());
|
assertThat(resultStepExecution.getStepName()).isEqualTo("step1:partition1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -168,49 +184,64 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish = getStepExecutionFinish(workerStepExecutionStart, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
handler.setDefaultArgsAsEnvironmentVars(true);
|
handler.setDefaultArgsAsEnvironmentVars(true);
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(55, null, null, null,
|
TaskExecution taskExecution = new TaskExecution(55, null, null, null, null, null,
|
||||||
null, null, new ArrayList<String>(), null, null);
|
new ArrayList<>(), null, null);
|
||||||
taskExecution.setTaskName("partitionedJobTask");
|
taskExecution.setTaskName("partitionedJobTask");
|
||||||
|
|
||||||
Set<StepExecution> stepExecutions = new HashSet<>();
|
Set<StepExecution> stepExecutions = new HashSet<>();
|
||||||
stepExecutions.add(workerStepExecutionStart);
|
stepExecutions.add(workerStepExecutionStart);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
|
.thenReturn(workerStepExecutionFinish);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
|
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher)
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
||||||
|
|
||||||
assertEquals(this.resource, request.getResource());
|
assertThat(request.getResource()).isEqualTo(this.resource);
|
||||||
assertEquals(0, request.getDeploymentProperties().size());
|
assertThat(request.getDeploymentProperties().size()).isEqualTo(0);
|
||||||
|
|
||||||
AppDefinition appDefinition = request.getDefinition();
|
AppDefinition appDefinition = request.getDefinition();
|
||||||
|
|
||||||
assertEquals("partitionedJobTask", appDefinition.getName());
|
assertThat(appDefinition.getName()).isEqualTo("partitionedJobTask");
|
||||||
assertTrue(request.getCommandlineArguments().isEmpty());
|
assertThat(request.getCommandlineArguments().isEmpty()).isTrue();
|
||||||
assertEquals("1", request.getDefinition().getProperties().get(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID));
|
assertThat(request.getDefinition().getProperties()
|
||||||
assertEquals("4", request.getDefinition().getProperties().get(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID));
|
.get(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
assertEquals("step1", request.getDefinition().getProperties().get(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME));
|
.isEqualTo("1");
|
||||||
assertEquals("partitionedJobTask_partitionedJob_step1:partition1", request.getDefinition().getProperties().get(DeployerPartitionHandler.SPRING_CLOUD_TASK_NAME));
|
assertThat(request.getDefinition().getProperties()
|
||||||
assertEquals("55", request.getDefinition().getProperties().get(DeployerPartitionHandler.SPRING_CLOUD_TASK_PARENT_EXECUTION_ID));
|
.get(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
|
.isEqualTo("4");
|
||||||
|
assertThat(request.getDefinition().getProperties()
|
||||||
|
.get(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.isEqualTo("step1");
|
||||||
|
assertThat(request.getDefinition().getProperties()
|
||||||
|
.get(DeployerPartitionHandler.SPRING_CLOUD_TASK_NAME))
|
||||||
|
.isEqualTo("partitionedJobTask_partitionedJob_step1:partition1");
|
||||||
|
assertThat(request.getDefinition().getProperties()
|
||||||
|
.get(DeployerPartitionHandler.SPRING_CLOUD_TASK_PARENT_EXECUTION_ID))
|
||||||
|
.isEqualTo("55");
|
||||||
|
|
||||||
assertEquals(1, results.size());
|
assertThat(results.size()).isEqualTo(1);
|
||||||
StepExecution resultStepExecution = results.iterator().next();
|
StepExecution resultStepExecution = results.iterator().next();
|
||||||
assertEquals(BatchStatus.COMPLETED, resultStepExecution.getStatus());
|
assertThat(resultStepExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
assertEquals("step1:partition1", resultStepExecution.getStepName());
|
assertThat(resultStepExecution.getStepName()).isEqualTo("step1:partition1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -220,13 +251,15 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish = getStepExecutionFinish(workerStepExecutionStart, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(55, null, null, null,
|
TaskExecution taskExecution = new TaskExecution(55, null, null, null, null, null,
|
||||||
null, null, new ArrayList<String>(), null, null);
|
new ArrayList<>(), null, null);
|
||||||
|
|
||||||
taskExecution.setTaskName("partitionedJobTask");
|
taskExecution.setTaskName("partitionedJobTask");
|
||||||
|
|
||||||
@@ -234,7 +267,8 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart);
|
stepExecutions.add(workerStepExecutionStart);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
|
.thenReturn(workerStepExecutionFinish);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
@@ -242,10 +276,13 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
handler.handle(this.splitter, masterStepExecution);
|
handler.handle(this.splitter, masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher)
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_PARENT_EXECUTION_ID, "55")));
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_PARENT_EXECUTION_ID, "55")))
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -255,15 +292,19 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(workerStepExecutionStart1, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart1, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
||||||
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(workerStepExecutionStart2, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart2, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart3 = getStepExecutionStart(jobExecution, 6L);
|
StepExecution workerStepExecutionStart3 = getStepExecutionStart(jobExecution, 6L);
|
||||||
StepExecution workerStepExecutionFinish3 = getStepExecutionFinish(workerStepExecutionStart3, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish3 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart3, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution();
|
TaskExecution taskExecution = new TaskExecution();
|
||||||
@@ -277,18 +318,24 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish1);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
when(this.jobExplorer.getStepExecution(1L, 5L)).thenReturn(workerStepExecutionFinish2);
|
.thenReturn(workerStepExecutionFinish1);
|
||||||
when(this.jobExplorer.getStepExecution(1L, 6L)).thenReturn(workerStepExecutionFinish3);
|
when(this.jobExplorer.getStepExecution(1L, 5L))
|
||||||
|
.thenReturn(workerStepExecutionFinish2);
|
||||||
|
when(this.jobExplorer.getStepExecution(1L, 6L))
|
||||||
|
.thenReturn(workerStepExecutionFinish3);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher, times(3)).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher, times(3))
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
List<AppDeploymentRequest> allValues = this.appDeploymentRequestArgumentCaptor.getAllValues();
|
List<AppDeploymentRequest> allValues = this.appDeploymentRequestArgumentCaptor
|
||||||
|
.getAllValues();
|
||||||
|
|
||||||
validateAppDeploymentRequests(allValues, 3);
|
validateAppDeploymentRequests(allValues, 3);
|
||||||
|
|
||||||
@@ -302,15 +349,19 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(workerStepExecutionStart1, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart1, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
||||||
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(workerStepExecutionStart2, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart2, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart3 = getStepExecutionStart(jobExecution, 6L);
|
StepExecution workerStepExecutionStart3 = getStepExecutionStart(jobExecution, 6L);
|
||||||
StepExecution workerStepExecutionFinish3 = getStepExecutionFinish(workerStepExecutionStart3, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish3 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart3, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
handler.setMaxWorkers(2);
|
handler.setMaxWorkers(2);
|
||||||
|
|
||||||
@@ -325,18 +376,24 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish1);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
when(this.jobExplorer.getStepExecution(1L, 5L)).thenReturn(workerStepExecutionFinish2);
|
.thenReturn(workerStepExecutionFinish1);
|
||||||
when(this.jobExplorer.getStepExecution(1L, 6L)).thenReturn(workerStepExecutionFinish3);
|
when(this.jobExplorer.getStepExecution(1L, 5L))
|
||||||
|
.thenReturn(workerStepExecutionFinish2);
|
||||||
|
when(this.jobExplorer.getStepExecution(1L, 6L))
|
||||||
|
.thenReturn(workerStepExecutionFinish3);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher, times(3)).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher, times(3))
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
List<AppDeploymentRequest> allValues = this.appDeploymentRequestArgumentCaptor.getAllValues();
|
List<AppDeploymentRequest> allValues = this.appDeploymentRequestArgumentCaptor
|
||||||
|
.getAllValues();
|
||||||
|
|
||||||
validateAppDeploymentRequests(allValues, 3);
|
validateAppDeploymentRequests(allValues, 3);
|
||||||
|
|
||||||
@@ -350,15 +407,19 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(workerStepExecutionStart1, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart1, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
||||||
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(workerStepExecutionStart2, BatchStatus.FAILED);
|
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart2, BatchStatus.FAILED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart3 = getStepExecutionStart(jobExecution, 6L);
|
StepExecution workerStepExecutionStart3 = getStepExecutionStart(jobExecution, 6L);
|
||||||
StepExecution workerStepExecutionFinish3 = getStepExecutionFinish(workerStepExecutionStart3, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish3 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart3, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
handler.setMaxWorkers(2);
|
handler.setMaxWorkers(2);
|
||||||
|
|
||||||
@@ -373,18 +434,24 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish1);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
when(this.jobExplorer.getStepExecution(1L, 5L)).thenReturn(workerStepExecutionFinish2);
|
.thenReturn(workerStepExecutionFinish1);
|
||||||
when(this.jobExplorer.getStepExecution(1L, 6L)).thenReturn(workerStepExecutionFinish3);
|
when(this.jobExplorer.getStepExecution(1L, 5L))
|
||||||
|
.thenReturn(workerStepExecutionFinish2);
|
||||||
|
when(this.jobExplorer.getStepExecution(1L, 6L))
|
||||||
|
.thenReturn(workerStepExecutionFinish3);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher, times(3)).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher, times(3))
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
List<AppDeploymentRequest> allValues = this.appDeploymentRequestArgumentCaptor.getAllValues();
|
List<AppDeploymentRequest> allValues = this.appDeploymentRequestArgumentCaptor
|
||||||
|
.getAllValues();
|
||||||
|
|
||||||
validateAppDeploymentRequests(allValues, 3);
|
validateAppDeploymentRequests(allValues, 3);
|
||||||
|
|
||||||
@@ -395,13 +462,13 @@ public class DeployerPartitionHandlerTests {
|
|||||||
StepExecution curResult = resultsIterator.next();
|
StepExecution curResult = resultsIterator.next();
|
||||||
|
|
||||||
if (curResult.getStepName().equals("step1:partition2")) {
|
if (curResult.getStepName().equals("step1:partition2")) {
|
||||||
assertEquals(BatchStatus.FAILED, curResult.getStatus());
|
assertThat(curResult.getStatus()).isEqualTo(BatchStatus.FAILED);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assertEquals(BatchStatus.COMPLETED, curResult.getStatus());
|
assertThat(curResult.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue(!names.contains(curResult.getStepName()));
|
assertThat(!names.contains(curResult.getStepName())).isTrue();
|
||||||
names.add(curResult.getStepName());
|
names.add(curResult.getStepName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -413,15 +480,18 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish = getStepExecutionFinish(workerStepExecutionStart, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
|
|
||||||
Map<String, String> environmentParameters = new HashMap<>(2);
|
Map<String, String> environmentParameters = new HashMap<>(2);
|
||||||
environmentParameters.put("foo", "bar");
|
environmentParameters.put("foo", "bar");
|
||||||
environmentParameters.put("baz", "qux");
|
environmentParameters.put("baz", "qux");
|
||||||
|
|
||||||
SimpleEnvironmentVariablesProvider environmentVariablesProvider = new SimpleEnvironmentVariablesProvider(this.environment);
|
SimpleEnvironmentVariablesProvider environmentVariablesProvider = new SimpleEnvironmentVariablesProvider(
|
||||||
|
this.environment);
|
||||||
environmentVariablesProvider.setEnvironmentProperties(environmentParameters);
|
environmentVariablesProvider.setEnvironmentProperties(environmentParameters);
|
||||||
handler.setEnvironmentVariablesProvider(environmentVariablesProvider);
|
handler.setEnvironmentVariablesProvider(environmentVariablesProvider);
|
||||||
|
|
||||||
@@ -432,33 +502,41 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart);
|
stepExecutions.add(workerStepExecutionStart);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
|
.thenReturn(workerStepExecutionFinish);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher)
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
||||||
|
|
||||||
assertEquals(this.resource, request.getResource());
|
assertThat(request.getResource()).isEqualTo(this.resource);
|
||||||
assertEquals(2, request.getDefinition().getProperties().size());
|
assertThat(request.getDefinition().getProperties().size()).isEqualTo(2);
|
||||||
assertEquals("bar", request.getDefinition().getProperties().get("foo"));
|
assertThat(request.getDefinition().getProperties().get("foo")).isEqualTo("bar");
|
||||||
assertEquals("qux", request.getDefinition().getProperties().get("baz"));
|
assertThat(request.getDefinition().getProperties().get("baz")).isEqualTo("qux");
|
||||||
|
|
||||||
AppDefinition appDefinition = request.getDefinition();
|
AppDefinition appDefinition = request.getDefinition();
|
||||||
|
|
||||||
assertEquals("partitionedJobTask", appDefinition.getName());
|
assertThat(appDefinition.getName()).isEqualTo("partitionedJobTask");
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")));
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")));
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")))
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1")));
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1"))).isTrue();
|
||||||
|
|
||||||
assertEquals(1, results.size());
|
assertThat(results.size()).isEqualTo(1);
|
||||||
StepExecution resultStepExecution = results.iterator().next();
|
StepExecution resultStepExecution = results.iterator().next();
|
||||||
assertEquals(BatchStatus.COMPLETED, resultStepExecution.getStatus());
|
assertThat(resultStepExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
assertEquals("step1:partition1", resultStepExecution.getStepName());
|
assertThat(resultStepExecution.getStepName()).isEqualTo("step1:partition1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -471,16 +549,19 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish = getStepExecutionFinish(workerStepExecutionStart, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
Map<String, String> environmentParameters = new HashMap<>(2);
|
Map<String, String> environmentParameters = new HashMap<>(2);
|
||||||
environmentParameters.put("foo", "bar");
|
environmentParameters.put("foo", "bar");
|
||||||
environmentParameters.put("baz", "qux");
|
environmentParameters.put("baz", "qux");
|
||||||
|
|
||||||
SimpleEnvironmentVariablesProvider environmentVariablesProvider = new SimpleEnvironmentVariablesProvider(this.environment);
|
SimpleEnvironmentVariablesProvider environmentVariablesProvider = new SimpleEnvironmentVariablesProvider(
|
||||||
|
this.environment);
|
||||||
environmentVariablesProvider.setEnvironmentProperties(environmentParameters);
|
environmentVariablesProvider.setEnvironmentProperties(environmentParameters);
|
||||||
handler.setEnvironmentVariablesProvider(environmentVariablesProvider);
|
handler.setEnvironmentVariablesProvider(environmentVariablesProvider);
|
||||||
|
|
||||||
@@ -491,34 +572,43 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart);
|
stepExecutions.add(workerStepExecutionStart);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
|
.thenReturn(workerStepExecutionFinish);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher)
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
||||||
|
|
||||||
assertEquals(this.resource, request.getResource());
|
assertThat(request.getResource()).isEqualTo(this.resource);
|
||||||
assertEquals(3, request.getDefinition().getProperties().size());
|
assertThat(request.getDefinition().getProperties().size()).isEqualTo(3);
|
||||||
assertEquals("bar", request.getDefinition().getProperties().get("foo"));
|
assertThat(request.getDefinition().getProperties().get("foo")).isEqualTo("bar");
|
||||||
assertEquals("qux", request.getDefinition().getProperties().get("baz"));
|
assertThat(request.getDefinition().getProperties().get("baz")).isEqualTo("qux");
|
||||||
assertEquals("batch", request.getDefinition().getProperties().get("task"));
|
assertThat(request.getDefinition().getProperties().get("task"))
|
||||||
|
.isEqualTo("batch");
|
||||||
|
|
||||||
AppDefinition appDefinition = request.getDefinition();
|
AppDefinition appDefinition = request.getDefinition();
|
||||||
|
|
||||||
assertEquals("partitionedJobTask", appDefinition.getName());
|
assertThat(appDefinition.getName()).isEqualTo("partitionedJobTask");
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")));
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")));
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")))
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1")));
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1"))).isTrue();
|
||||||
|
|
||||||
assertEquals(1, results.size());
|
assertThat(results.size()).isEqualTo(1);
|
||||||
StepExecution resultStepExecution = results.iterator().next();
|
StepExecution resultStepExecution = results.iterator().next();
|
||||||
assertEquals(BatchStatus.COMPLETED, resultStepExecution.getStatus());
|
assertThat(resultStepExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
assertEquals("step1:partition1", resultStepExecution.getStepName());
|
assertThat(resultStepExecution.getStepName()).isEqualTo("step1:partition1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -528,12 +618,15 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(workerStepExecutionStart1, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart1, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
||||||
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(workerStepExecutionStart2, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart2, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
handler.setPollInterval(20000L);
|
handler.setPollInterval(20000L);
|
||||||
@@ -547,26 +640,33 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart2);
|
stepExecutions.add(workerStepExecutionStart2);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish1);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
when(this.jobExplorer.getStepExecution(1L, 5L)).thenReturn(workerStepExecutionFinish2);
|
.thenReturn(workerStepExecutionFinish1);
|
||||||
|
when(this.jobExplorer.getStepExecution(1L, 5L))
|
||||||
|
.thenReturn(workerStepExecutionFinish2);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
|
|
||||||
Date startTime = new Date();
|
Date startTime = new Date();
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
Date endTime = new Date();
|
Date endTime = new Date();
|
||||||
verify(this.taskLauncher, times(2)).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher, times(2))
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
List<AppDeploymentRequest> allRequests = this.appDeploymentRequestArgumentCaptor.getAllValues();
|
List<AppDeploymentRequest> allRequests = this.appDeploymentRequestArgumentCaptor
|
||||||
|
.getAllValues();
|
||||||
|
|
||||||
validateAppDeploymentRequests(allRequests, 2);
|
validateAppDeploymentRequests(allRequests, 2);
|
||||||
|
|
||||||
validateStepExecutionResults(results);
|
validateStepExecutionResults(results);
|
||||||
|
|
||||||
assertTrue("Time difference was too small: " + (endTime.getTime() - startTime.getTime()),
|
assertThat(endTime.getTime() - startTime.getTime() >= 19999)
|
||||||
endTime.getTime() - startTime.getTime() >= 19999);
|
.as("Time difference was too small: "
|
||||||
|
+ (endTime.getTime() - startTime.getTime()))
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = TimeoutException.class)
|
@Test(expected = TimeoutException.class)
|
||||||
@@ -576,12 +676,15 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(workerStepExecutionStart1, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart1, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
||||||
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(workerStepExecutionStart2, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart2, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
handler.setPollInterval(20000L);
|
handler.setPollInterval(20000L);
|
||||||
@@ -596,8 +699,10 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart2);
|
stepExecutions.add(workerStepExecutionStart2);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish1);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
when(this.jobExplorer.getStepExecution(1L, 5L)).thenReturn(workerStepExecutionFinish2);
|
.thenReturn(workerStepExecutionFinish1);
|
||||||
|
when(this.jobExplorer.getStepExecution(1L, 5L))
|
||||||
|
.thenReturn(workerStepExecutionFinish2);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
@@ -613,12 +718,15 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart1 = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(workerStepExecutionStart1, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish1 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart1, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
StepExecution workerStepExecutionStart2 = getStepExecutionStart(jobExecution, 5L);
|
||||||
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(workerStepExecutionStart2, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish2 = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart2, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
handler.setGridSize(2);
|
handler.setGridSize(2);
|
||||||
@@ -631,18 +739,23 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart2);
|
stepExecutions.add(workerStepExecutionStart2);
|
||||||
when(this.splitter.split(masterStepExecution, 2)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 2)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish1);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
when(this.jobExplorer.getStepExecution(1L, 5L)).thenReturn(workerStepExecutionFinish2);
|
.thenReturn(workerStepExecutionFinish1);
|
||||||
|
when(this.jobExplorer.getStepExecution(1L, 5L))
|
||||||
|
.thenReturn(workerStepExecutionFinish2);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
|
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher, times(2)).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher, times(2))
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
List<AppDeploymentRequest> allRequests = this.appDeploymentRequestArgumentCaptor.getAllValues();
|
List<AppDeploymentRequest> allRequests = this.appDeploymentRequestArgumentCaptor
|
||||||
|
.getAllValues();
|
||||||
|
|
||||||
validateAppDeploymentRequests(allRequests, 2);
|
validateAppDeploymentRequests(allRequests, 2);
|
||||||
|
|
||||||
@@ -656,9 +769,11 @@ public class DeployerPartitionHandlerTests {
|
|||||||
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
JobExecution jobExecution = masterStepExecution.getJobExecution();
|
||||||
|
|
||||||
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
StepExecution workerStepExecutionStart = getStepExecutionStart(jobExecution, 4L);
|
||||||
StepExecution workerStepExecutionFinish = getStepExecutionFinish(workerStepExecutionStart, BatchStatus.COMPLETED);
|
StepExecution workerStepExecutionFinish = getStepExecutionFinish(
|
||||||
|
workerStepExecutionStart, BatchStatus.COMPLETED);
|
||||||
|
|
||||||
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher, this.jobExplorer, this.resource, "step1");
|
DeployerPartitionHandler handler = new DeployerPartitionHandler(this.taskLauncher,
|
||||||
|
this.jobExplorer, this.resource, "step1");
|
||||||
handler.setEnvironment(this.environment);
|
handler.setEnvironment(this.environment);
|
||||||
|
|
||||||
Map<String, String> deploymentProperties = new HashMap<>(2);
|
Map<String, String> deploymentProperties = new HashMap<>(2);
|
||||||
@@ -674,48 +789,59 @@ public class DeployerPartitionHandlerTests {
|
|||||||
stepExecutions.add(workerStepExecutionStart);
|
stepExecutions.add(workerStepExecutionStart);
|
||||||
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
when(this.splitter.split(masterStepExecution, 1)).thenReturn(stepExecutions);
|
||||||
|
|
||||||
when(this.jobExplorer.getStepExecution(1L, 4L)).thenReturn(workerStepExecutionFinish);
|
when(this.jobExplorer.getStepExecution(1L, 4L))
|
||||||
|
.thenReturn(workerStepExecutionFinish);
|
||||||
|
|
||||||
handler.afterPropertiesSet();
|
handler.afterPropertiesSet();
|
||||||
|
|
||||||
handler.beforeTask(taskExecution);
|
handler.beforeTask(taskExecution);
|
||||||
Collection<StepExecution> results = handler.handle(this.splitter, masterStepExecution);
|
Collection<StepExecution> results = handler.handle(this.splitter,
|
||||||
|
masterStepExecution);
|
||||||
|
|
||||||
verify(this.taskLauncher).launch(this.appDeploymentRequestArgumentCaptor.capture());
|
verify(this.taskLauncher)
|
||||||
|
.launch(this.appDeploymentRequestArgumentCaptor.capture());
|
||||||
|
|
||||||
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
AppDeploymentRequest request = this.appDeploymentRequestArgumentCaptor.getValue();
|
||||||
|
|
||||||
assertEquals(this.resource, request.getResource());
|
assertThat(request.getResource()).isEqualTo(this.resource);
|
||||||
assertEquals(2, request.getDeploymentProperties().size());
|
assertThat(request.getDeploymentProperties().size()).isEqualTo(2);
|
||||||
assertEquals("bar", request.getDeploymentProperties().get("foo"));
|
assertThat(request.getDeploymentProperties().get("foo")).isEqualTo("bar");
|
||||||
assertEquals("qux", request.getDeploymentProperties().get("baz"));
|
assertThat(request.getDeploymentProperties().get("baz")).isEqualTo("qux");
|
||||||
|
|
||||||
AppDefinition appDefinition = request.getDefinition();
|
AppDefinition appDefinition = request.getDefinition();
|
||||||
|
|
||||||
assertEquals("partitionedJobTask", appDefinition.getName());
|
assertThat(appDefinition.getName()).isEqualTo("partitionedJobTask");
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")));
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")));
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")))
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1")));
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, "4")))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1"))).isTrue();
|
||||||
|
|
||||||
assertEquals(1, results.size());
|
assertThat(results.size()).isEqualTo(1);
|
||||||
StepExecution resultStepExecution = results.iterator().next();
|
StepExecution resultStepExecution = results.iterator().next();
|
||||||
assertEquals(BatchStatus.COMPLETED, resultStepExecution.getStatus());
|
assertThat(resultStepExecution.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
assertEquals("step1:partition1", resultStepExecution.getStepName());
|
assertThat(resultStepExecution.getStepName()).isEqualTo("step1:partition1");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String formatArgs(String key, String value) {
|
private String formatArgs(String key, String value) {
|
||||||
return String.format("--%s=%s", key, value);
|
return String.format("--%s=%s", key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StepExecution getStepExecutionFinish(StepExecution stepExecutionStart, BatchStatus status) {
|
private StepExecution getStepExecutionFinish(StepExecution stepExecutionStart,
|
||||||
StepExecution workerStepExecutionFinish = new StepExecution(stepExecutionStart.getStepName(), stepExecutionStart.getJobExecution());
|
BatchStatus status) {
|
||||||
|
StepExecution workerStepExecutionFinish = new StepExecution(
|
||||||
|
stepExecutionStart.getStepName(), stepExecutionStart.getJobExecution());
|
||||||
workerStepExecutionFinish.setId(stepExecutionStart.getId());
|
workerStepExecutionFinish.setId(stepExecutionStart.getId());
|
||||||
workerStepExecutionFinish.setStatus(status);
|
workerStepExecutionFinish.setStatus(status);
|
||||||
return workerStepExecutionFinish;
|
return workerStepExecutionFinish;
|
||||||
}
|
}
|
||||||
|
|
||||||
private StepExecution getStepExecutionStart(JobExecution jobExecution, long id) {
|
private StepExecution getStepExecutionStart(JobExecution jobExecution, long id) {
|
||||||
StepExecution workerStepExecutionStart = new StepExecution("step1:partition" + (id - 3), jobExecution);
|
StepExecution workerStepExecutionStart = new StepExecution(
|
||||||
|
"step1:partition" + (id - 3), jobExecution);
|
||||||
workerStepExecutionStart.setId(id);
|
workerStepExecutionStart.setId(id);
|
||||||
return workerStepExecutionStart;
|
return workerStepExecutionStart;
|
||||||
}
|
}
|
||||||
@@ -738,14 +864,15 @@ public class DeployerPartitionHandlerTests {
|
|||||||
while (resultsIterator.hasNext()) {
|
while (resultsIterator.hasNext()) {
|
||||||
StepExecution curResult = resultsIterator.next();
|
StepExecution curResult = resultsIterator.next();
|
||||||
|
|
||||||
assertEquals(BatchStatus.COMPLETED, curResult.getStatus());
|
assertThat(curResult.getStatus()).isEqualTo(BatchStatus.COMPLETED);
|
||||||
|
|
||||||
assertTrue(!names.contains(curResult.getStepName()));
|
assertThat(!names.contains(curResult.getStepName())).isTrue();
|
||||||
names.add(curResult.getStepName());
|
names.add(curResult.getStepName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateAppDeploymentRequests(List<AppDeploymentRequest> allRequests, int numberOfPartitions) {
|
private void validateAppDeploymentRequests(List<AppDeploymentRequest> allRequests,
|
||||||
|
int numberOfPartitions) {
|
||||||
Collections.sort(allRequests, new Comparator<AppDeploymentRequest>() {
|
Collections.sort(allRequests, new Comparator<AppDeploymentRequest>() {
|
||||||
@Override
|
@Override
|
||||||
public int compare(AppDeploymentRequest o1, AppDeploymentRequest o2) {
|
public int compare(AppDeploymentRequest o1, AppDeploymentRequest o2) {
|
||||||
@@ -753,7 +880,8 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
String o1Command = "";
|
String o1Command = "";
|
||||||
for (String commandlineArgument : commandlineArguments) {
|
for (String commandlineArgument : commandlineArguments) {
|
||||||
if(commandlineArgument.contains(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)) {
|
if (commandlineArgument.contains(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)) {
|
||||||
o1Command = commandlineArgument;
|
o1Command = commandlineArgument;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -763,7 +891,8 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
String o2Command = "";
|
String o2Command = "";
|
||||||
for (String commandlineArgument : commandlineArguments) {
|
for (String commandlineArgument : commandlineArguments) {
|
||||||
if(commandlineArgument.contains(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)) {
|
if (commandlineArgument.contains(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)) {
|
||||||
o2Command = commandlineArgument;
|
o2Command = commandlineArgument;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -775,23 +904,33 @@ public class DeployerPartitionHandlerTests {
|
|||||||
|
|
||||||
for (int i = 4; i < (numberOfPartitions + 4); i++) {
|
for (int i = 4; i < (numberOfPartitions + 4); i++) {
|
||||||
AppDeploymentRequest request = allRequests.get(i - 4);
|
AppDeploymentRequest request = allRequests.get(i - 4);
|
||||||
assertEquals(this.resource, request.getResource());
|
assertThat(request.getResource()).isEqualTo(this.resource);
|
||||||
assertEquals(0, request.getDeploymentProperties().size());
|
assertThat(request.getDeploymentProperties().size()).isEqualTo(0);
|
||||||
|
|
||||||
AppDefinition appDefinition = request.getDefinition();
|
AppDefinition appDefinition = request.getDefinition();
|
||||||
assertEquals("partitionedJobTask", appDefinition.getName());
|
assertThat(appDefinition.getName()).isEqualTo("partitionedJobTask");
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")));
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID, String.valueOf(i))));
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, "1")))
|
||||||
assertTrue(request.getCommandlineArguments().contains(formatArgs(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1")));
|
.isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments()
|
||||||
|
.contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID,
|
||||||
|
String.valueOf(i)))).isTrue();
|
||||||
|
assertThat(request.getCommandlineArguments().contains(formatArgs(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME, "step1")))
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateConstructorValidation(TaskLauncher taskLauncher, JobExplorer jobExplorer, Resource resource, String stepName, String expectedMessage) {
|
private void validateConstructorValidation(TaskLauncher taskLauncher,
|
||||||
|
JobExplorer jobExplorer, Resource resource, String stepName,
|
||||||
|
String expectedMessage) {
|
||||||
try {
|
try {
|
||||||
new DeployerPartitionHandler(taskLauncher, jobExplorer, resource, stepName);
|
new DeployerPartitionHandler(taskLauncher, jobExplorer, resource, stepName);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
assertEquals(expectedMessage, iae.getMessage());
|
assertThat(iae.getMessage()).isEqualTo(expectedMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
@@ -35,7 +36,7 @@ import org.springframework.beans.factory.ListableBeanFactory;
|
|||||||
import org.springframework.core.env.Environment;
|
import org.springframework.core.env.Environment;
|
||||||
import org.springframework.test.util.ReflectionTestUtils;
|
import org.springframework.test.util.ReflectionTestUtils;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.mockito.Mockito.doThrow;
|
import static org.mockito.Mockito.doThrow;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||||
@@ -70,7 +71,8 @@ public class DeployerStepExecutionHandlerTests {
|
|||||||
public void setUp() {
|
public void setUp() {
|
||||||
MockitoAnnotations.initMocks(this);
|
MockitoAnnotations.initMocks(this);
|
||||||
|
|
||||||
this.handler = new DeployerStepExecutionHandler(this.beanFactory, this.jobExplorer, this.jobRepository);
|
this.handler = new DeployerStepExecutionHandler(this.beanFactory,
|
||||||
|
this.jobExplorer, this.jobRepository);
|
||||||
|
|
||||||
ReflectionTestUtils.setField(this.handler, "environment", this.environment);
|
ReflectionTestUtils.setField(this.handler, "environment", this.environment);
|
||||||
}
|
}
|
||||||
@@ -78,69 +80,116 @@ public class DeployerStepExecutionHandlerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testConstructorValidation() {
|
public void testConstructorValidation() {
|
||||||
validateConstructorValidation(null, null, null, "A beanFactory is required");
|
validateConstructorValidation(null, null, null, "A beanFactory is required");
|
||||||
validateConstructorValidation(this.beanFactory, null, null, "A jobExplorer is required");
|
validateConstructorValidation(this.beanFactory, null, null,
|
||||||
validateConstructorValidation(this.beanFactory, this.jobExplorer, null, "A jobRepository is required");
|
"A jobExplorer is required");
|
||||||
|
validateConstructorValidation(this.beanFactory, this.jobExplorer, null,
|
||||||
|
"A jobRepository is required");
|
||||||
|
|
||||||
new DeployerStepExecutionHandler(this.beanFactory, this.jobExplorer, this.jobRepository);
|
new DeployerStepExecutionHandler(this.beanFactory, this.jobExplorer,
|
||||||
|
this.jobRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidationOfRequestValuesExist() throws Exception {
|
public void testValidationOfRequestValuesExist() throws Exception {
|
||||||
validateEnvironmentConfiguration("A job execution id is required", new String[0]);
|
validateEnvironmentConfiguration("A job execution id is required", new String[0]);
|
||||||
validateEnvironmentConfiguration("A step execution id is required", new String[] {DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID});
|
validateEnvironmentConfiguration("A step execution id is required", new String[] {
|
||||||
validateEnvironmentConfiguration("A step name is required", new String[] {DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID, DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID});
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID });
|
||||||
|
validateEnvironmentConfiguration("A step name is required",
|
||||||
|
new String[] {
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID,
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID });
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValidationOfRequestStepFound() throws Exception {
|
public void testValidationOfRequestStepFound() throws Exception {
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn(true);
|
when(this.environment.containsProperty(
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn(true);
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn(true);
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("foo");
|
when(this.environment.containsProperty(
|
||||||
when(this.beanFactory.getBeanNamesForType(Step.class)).thenReturn(new String[] {"bar", "baz"});
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(this.environment
|
||||||
|
.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("foo");
|
||||||
|
when(this.beanFactory.getBeanNamesForType(Step.class))
|
||||||
|
.thenReturn(new String[] { "bar", "baz" });
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.handler.run();
|
this.handler.run();
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
assertEquals("The step requested cannot be found in the provided BeanFactory", iae.getMessage());
|
assertThat(iae.getMessage()).isEqualTo(
|
||||||
|
"The step requested cannot be found in the provided BeanFactory");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMissingStepExecution() throws Exception {
|
public void testMissingStepExecution() throws Exception {
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn(true);
|
when(this.environment.containsProperty(
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn(true);
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn(true);
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("foo");
|
when(this.environment.containsProperty(
|
||||||
when(this.beanFactory.getBeanNamesForType(Step.class)).thenReturn(new String[] {"foo", "bar", "baz"});
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn("2");
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn("1");
|
when(this.environment
|
||||||
|
.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("foo");
|
||||||
|
when(this.beanFactory.getBeanNamesForType(Step.class))
|
||||||
|
.thenReturn(new String[] { "foo", "bar", "baz" });
|
||||||
|
when(this.environment.getProperty(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
|
.thenReturn("2");
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
|
.thenReturn("1");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.handler.run();
|
this.handler.run();
|
||||||
}
|
}
|
||||||
catch (NoSuchStepException nsse) {
|
catch (NoSuchStepException nsse) {
|
||||||
assertEquals("No StepExecution could be located for step execution id 2 within job execution 1", nsse.getMessage());
|
assertThat(nsse.getMessage()).isEqualTo(
|
||||||
|
"No StepExecution could be located for step execution id 2 within job execution 1");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRunSuccessful() throws Exception {
|
public void testRunSuccessful() throws Exception {
|
||||||
StepExecution workerStep = new StepExecution("workerStep", new JobExecution(1L), 2L);
|
StepExecution workerStep = new StepExecution("workerStep", new JobExecution(1L),
|
||||||
|
2L);
|
||||||
|
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn(true);
|
when(this.environment.containsProperty(
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn(true);
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn(true);
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("workerStep");
|
when(this.environment.containsProperty(
|
||||||
when(this.beanFactory.getBeanNamesForType(Step.class)).thenReturn(new String[] {"workerStep", "foo", "bar"});
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn("2");
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn("1");
|
when(this.environment
|
||||||
|
.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("workerStep");
|
||||||
|
when(this.beanFactory.getBeanNamesForType(Step.class))
|
||||||
|
.thenReturn(new String[] { "workerStep", "foo", "bar" });
|
||||||
|
when(this.environment.getProperty(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
|
.thenReturn("2");
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
|
.thenReturn("1");
|
||||||
when(this.jobExplorer.getStepExecution(1L, 2L)).thenReturn(workerStep);
|
when(this.jobExplorer.getStepExecution(1L, 2L)).thenReturn(workerStep);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("workerStep");
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("workerStep");
|
||||||
when(this.beanFactory.getBean("workerStep", Step.class)).thenReturn(this.step);
|
when(this.beanFactory.getBean("workerStep", Step.class)).thenReturn(this.step);
|
||||||
|
|
||||||
handler.run();
|
this.handler.run();
|
||||||
|
|
||||||
verify(this.step).execute(workerStep);
|
verify(this.step).execute(workerStep);
|
||||||
verifyZeroInteractions(this.jobRepository);
|
verifyZeroInteractions(this.jobRepository);
|
||||||
@@ -148,51 +197,87 @@ public class DeployerStepExecutionHandlerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testJobInterruptedException() throws Exception {
|
public void testJobInterruptedException() throws Exception {
|
||||||
StepExecution workerStep = new StepExecution("workerStep", new JobExecution(1L), 2L);
|
StepExecution workerStep = new StepExecution("workerStep", new JobExecution(1L),
|
||||||
|
2L);
|
||||||
|
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn(true);
|
when(this.environment.containsProperty(
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn(true);
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn(true);
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("workerStep");
|
when(this.environment.containsProperty(
|
||||||
when(this.beanFactory.getBeanNamesForType(Step.class)).thenReturn(new String[] {"workerStep", "foo", "bar"});
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn("2");
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn("1");
|
when(this.environment
|
||||||
|
.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("workerStep");
|
||||||
|
when(this.beanFactory.getBeanNamesForType(Step.class))
|
||||||
|
.thenReturn(new String[] { "workerStep", "foo", "bar" });
|
||||||
|
when(this.environment.getProperty(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
|
.thenReturn("2");
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
|
.thenReturn("1");
|
||||||
when(this.jobExplorer.getStepExecution(1L, 2L)).thenReturn(workerStep);
|
when(this.jobExplorer.getStepExecution(1L, 2L)).thenReturn(workerStep);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("workerStep");
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("workerStep");
|
||||||
when(this.beanFactory.getBean("workerStep", Step.class)).thenReturn(this.step);
|
when(this.beanFactory.getBean("workerStep", Step.class)).thenReturn(this.step);
|
||||||
doThrow(new JobInterruptedException("expected")).when(this.step).execute(workerStep);
|
doThrow(new JobInterruptedException("expected")).when(this.step)
|
||||||
|
.execute(workerStep);
|
||||||
|
|
||||||
handler.run();
|
this.handler.run();
|
||||||
|
|
||||||
verify(this.jobRepository).update(this.stepExecutionArgumentCaptor.capture());
|
verify(this.jobRepository).update(this.stepExecutionArgumentCaptor.capture());
|
||||||
|
|
||||||
assertEquals(BatchStatus.STOPPED, this.stepExecutionArgumentCaptor.getValue().getStatus());
|
assertThat(this.stepExecutionArgumentCaptor.getValue().getStatus())
|
||||||
|
.isEqualTo(BatchStatus.STOPPED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRuntimeException() throws Exception {
|
public void testRuntimeException() throws Exception {
|
||||||
StepExecution workerStep = new StepExecution("workerStep", new JobExecution(1L), 2L);
|
StepExecution workerStep = new StepExecution("workerStep", new JobExecution(1L),
|
||||||
|
2L);
|
||||||
|
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn(true);
|
when(this.environment.containsProperty(
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn(true);
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
when(this.environment.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn(true);
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("workerStep");
|
when(this.environment.containsProperty(
|
||||||
when(this.beanFactory.getBeanNamesForType(Step.class)).thenReturn(new String[] {"workerStep", "foo", "bar"});
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID)).thenReturn("2");
|
.thenReturn(true);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID)).thenReturn("1");
|
when(this.environment
|
||||||
|
.containsProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn(true);
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("workerStep");
|
||||||
|
when(this.beanFactory.getBeanNamesForType(Step.class))
|
||||||
|
.thenReturn(new String[] { "workerStep", "foo", "bar" });
|
||||||
|
when(this.environment.getProperty(
|
||||||
|
DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_EXECUTION_ID))
|
||||||
|
.thenReturn("2");
|
||||||
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_JOB_EXECUTION_ID))
|
||||||
|
.thenReturn("1");
|
||||||
when(this.jobExplorer.getStepExecution(1L, 2L)).thenReturn(workerStep);
|
when(this.jobExplorer.getStepExecution(1L, 2L)).thenReturn(workerStep);
|
||||||
when(this.environment.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME)).thenReturn("workerStep");
|
when(this.environment
|
||||||
|
.getProperty(DeployerPartitionHandler.SPRING_CLOUD_TASK_STEP_NAME))
|
||||||
|
.thenReturn("workerStep");
|
||||||
when(this.beanFactory.getBean("workerStep", Step.class)).thenReturn(this.step);
|
when(this.beanFactory.getBean("workerStep", Step.class)).thenReturn(this.step);
|
||||||
doThrow(new RuntimeException("expected")).when(this.step).execute(workerStep);
|
doThrow(new RuntimeException("expected")).when(this.step).execute(workerStep);
|
||||||
|
|
||||||
handler.run();
|
this.handler.run();
|
||||||
|
|
||||||
verify(this.jobRepository).update(this.stepExecutionArgumentCaptor.capture());
|
verify(this.jobRepository).update(this.stepExecutionArgumentCaptor.capture());
|
||||||
|
|
||||||
assertEquals(BatchStatus.FAILED, this.stepExecutionArgumentCaptor.getValue().getStatus());
|
assertThat(this.stepExecutionArgumentCaptor.getValue().getStatus())
|
||||||
|
.isEqualTo(BatchStatus.FAILED);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateEnvironmentConfiguration(String errorMessage, String[] properties) throws Exception {
|
private void validateEnvironmentConfiguration(String errorMessage,
|
||||||
|
String[] properties) throws Exception {
|
||||||
|
|
||||||
for (String property : properties) {
|
for (String property : properties) {
|
||||||
when(this.environment.containsProperty(property)).thenReturn(true);
|
when(this.environment.containsProperty(property)).thenReturn(true);
|
||||||
@@ -202,17 +287,18 @@ public class DeployerStepExecutionHandlerTests {
|
|||||||
this.handler.run();
|
this.handler.run();
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
assertEquals(errorMessage, iae.getMessage());
|
assertThat(iae.getMessage()).isEqualTo(errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateConstructorValidation(BeanFactory beanFactory,
|
||||||
private void validateConstructorValidation(BeanFactory beanFactory, JobExplorer jobExplorer, JobRepository jobRepository, String message) {
|
JobExplorer jobExplorer, JobRepository jobRepository, String message) {
|
||||||
try {
|
try {
|
||||||
new DeployerStepExecutionHandler(beanFactory, jobExplorer, jobRepository);
|
new DeployerStepExecutionHandler(beanFactory, jobExplorer, jobRepository);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException iae) {
|
catch (IllegalArgumentException iae) {
|
||||||
assertEquals(message, iae.getMessage());
|
assertThat(iae.getMessage()).isEqualTo(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,13 +13,15 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
@@ -35,11 +37,14 @@ public class NoOpEnvironmentVariablesProviderTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
Map<String, String> environmentVariables = this.provider.getEnvironmentVariables(null);
|
Map<String, String> environmentVariables = this.provider
|
||||||
assertNotNull(environmentVariables);
|
.getEnvironmentVariables(null);
|
||||||
assertTrue(environmentVariables.isEmpty());
|
assertThat(environmentVariables).isNotNull();
|
||||||
|
assertThat(environmentVariables.isEmpty()).isTrue();
|
||||||
|
|
||||||
Map<String, String> environmentVariables2 = this.provider.getEnvironmentVariables(null);
|
Map<String, String> environmentVariables2 = this.provider
|
||||||
assertTrue(environmentVariables == environmentVariables2);
|
.getEnvironmentVariables(null);
|
||||||
|
assertThat(environmentVariables == environmentVariables2).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,13 +13,15 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
@@ -39,8 +41,9 @@ public class PassThroughCommandLineArgsProviderTests {
|
|||||||
|
|
||||||
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
||||||
|
|
||||||
assertEquals("foo", commandLineArgs.get(0));
|
assertThat(commandLineArgs.get(0)).isEqualTo("foo");
|
||||||
assertEquals("bar", commandLineArgs.get(1));
|
assertThat(commandLineArgs.get(1)).isEqualTo("bar");
|
||||||
assertEquals("baz", commandLineArgs.get(2));
|
assertThat(commandLineArgs.get(2)).isEqualTo("baz");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.batch.partition;
|
package org.springframework.cloud.task.batch.partition;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -23,7 +24,7 @@ import org.junit.Test;
|
|||||||
|
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
@@ -35,13 +36,14 @@ public class SimpleCommandLineArgsProviderTests {
|
|||||||
TaskExecution taskExecution = new TaskExecution();
|
TaskExecution taskExecution = new TaskExecution();
|
||||||
taskExecution.setArguments(Arrays.asList("foo", "bar", "baz"));
|
taskExecution.setArguments(Arrays.asList("foo", "bar", "baz"));
|
||||||
|
|
||||||
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(taskExecution);
|
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(
|
||||||
|
taskExecution);
|
||||||
|
|
||||||
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
||||||
|
|
||||||
assertEquals("foo", commandLineArgs.get(0));
|
assertThat(commandLineArgs.get(0)).isEqualTo("foo");
|
||||||
assertEquals("bar", commandLineArgs.get(1));
|
assertThat(commandLineArgs.get(1)).isEqualTo("bar");
|
||||||
assertEquals("baz", commandLineArgs.get(2));
|
assertThat(commandLineArgs.get(2)).isEqualTo("baz");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -54,17 +56,18 @@ public class SimpleCommandLineArgsProviderTests {
|
|||||||
TaskExecution taskExecution = new TaskExecution();
|
TaskExecution taskExecution = new TaskExecution();
|
||||||
taskExecution.setArguments(Arrays.asList("foo", "bar", "baz"));
|
taskExecution.setArguments(Arrays.asList("foo", "bar", "baz"));
|
||||||
|
|
||||||
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(taskExecution);
|
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(
|
||||||
|
taskExecution);
|
||||||
provider.setAppendedArgs(appendedValues);
|
provider.setAppendedArgs(appendedValues);
|
||||||
|
|
||||||
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
||||||
|
|
||||||
assertEquals("foo", commandLineArgs.get(0));
|
assertThat(commandLineArgs.get(0)).isEqualTo("foo");
|
||||||
assertEquals("bar", commandLineArgs.get(1));
|
assertThat(commandLineArgs.get(1)).isEqualTo("bar");
|
||||||
assertEquals("baz", commandLineArgs.get(2));
|
assertThat(commandLineArgs.get(2)).isEqualTo("baz");
|
||||||
assertEquals("one", commandLineArgs.get(3));
|
assertThat(commandLineArgs.get(3)).isEqualTo("one");
|
||||||
assertEquals("two", commandLineArgs.get(4));
|
assertThat(commandLineArgs.get(4)).isEqualTo("two");
|
||||||
assertEquals("three", commandLineArgs.get(5));
|
assertThat(commandLineArgs.get(5)).isEqualTo("three");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -73,14 +76,16 @@ public class SimpleCommandLineArgsProviderTests {
|
|||||||
TaskExecution taskExecution = new TaskExecution();
|
TaskExecution taskExecution = new TaskExecution();
|
||||||
taskExecution.setArguments(Arrays.asList("foo", "bar", "baz"));
|
taskExecution.setArguments(Arrays.asList("foo", "bar", "baz"));
|
||||||
|
|
||||||
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(taskExecution);
|
SimpleCommandLineArgsProvider provider = new SimpleCommandLineArgsProvider(
|
||||||
|
taskExecution);
|
||||||
provider.setAppendedArgs(null);
|
provider.setAppendedArgs(null);
|
||||||
|
|
||||||
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
List<String> commandLineArgs = provider.getCommandLineArgs(null);
|
||||||
|
|
||||||
assertEquals(3, commandLineArgs.size());
|
assertThat(commandLineArgs.size()).isEqualTo(3);
|
||||||
assertEquals("foo", commandLineArgs.get(0));
|
assertThat(commandLineArgs.get(0)).isEqualTo("foo");
|
||||||
assertEquals("bar", commandLineArgs.get(1));
|
assertThat(commandLineArgs.get(1)).isEqualTo("bar");
|
||||||
assertEquals("baz", commandLineArgs.get(2));
|
assertThat(commandLineArgs.get(2)).isEqualTo("baz");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -36,13 +36,14 @@ import org.springframework.orm.jpa.JpaTransactionManager;
|
|||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default implementation of the TaskConfigurer interface. If no {@link TaskConfigurer}
|
* Default implementation of the TaskConfigurer interface. If no {@link TaskConfigurer}
|
||||||
* implementation is present, then this configuration will be used.
|
* implementation is present, then this configuration will be used. The following defaults
|
||||||
* The following defaults will be used:
|
* will be used:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link SimpleTaskRepository} is the default {@link TaskRepository} returned.
|
* <li>{@link SimpleTaskRepository} is the default {@link TaskRepository} returned. If a
|
||||||
* If a data source is present then a data will be stored in the database {@link JdbcTaskExecutionDao} else it will
|
* data source is present then a data will be stored in the database
|
||||||
* be stored in a map {@link MapTaskExecutionDao}.
|
* {@link JdbcTaskExecutionDao} else it will be stored in a map
|
||||||
|
* {@link MapTaskExecutionDao}.
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
@@ -67,12 +68,11 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the DefaultTaskConfigurer and sets the default table prefix
|
* Initializes the DefaultTaskConfigurer and sets the default table prefix to
|
||||||
* to {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
|
* {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
|
||||||
*
|
|
||||||
* @param dataSource references the {@link DataSource} to be used as the Task
|
* @param dataSource references the {@link DataSource} to be used as the Task
|
||||||
* repository. If none is provided, a Map will be used (not recommended for
|
* repository. If none is provided, a Map will be used (not recommended for production
|
||||||
* production use.
|
* use.
|
||||||
*/
|
*/
|
||||||
public DefaultTaskConfigurer(DataSource dataSource) {
|
public DefaultTaskConfigurer(DataSource dataSource) {
|
||||||
this(dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, null);
|
this(dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, null);
|
||||||
@@ -80,9 +80,8 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the DefaultTaskConfigurer.
|
* Initializes the DefaultTaskConfigurer.
|
||||||
*
|
* @param tablePrefix the prefix to apply to the task table names used by task
|
||||||
* @param tablePrefix the prefix to apply to the task table names used by
|
* infrastructure.
|
||||||
* task infrastructure.
|
|
||||||
*/
|
*/
|
||||||
public DefaultTaskConfigurer(String tablePrefix) {
|
public DefaultTaskConfigurer(String tablePrefix) {
|
||||||
this(null, tablePrefix, null);
|
this(null, tablePrefix, null);
|
||||||
@@ -90,23 +89,23 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the DefaultTaskConfigurer.
|
* Initializes the DefaultTaskConfigurer.
|
||||||
*
|
|
||||||
* @param dataSource references the {@link DataSource} to be used as the Task
|
* @param dataSource references the {@link DataSource} to be used as the Task
|
||||||
* repository. If none is provided, a Map will be used (not recommended for
|
* repository. If none is provided, a Map will be used (not recommended for production
|
||||||
* production use.
|
* use.
|
||||||
* @param tablePrefix the prefix to apply to the task table names used by
|
* @param tablePrefix the prefix to apply to the task table names used by task
|
||||||
* task infrastructure.
|
* infrastructure.
|
||||||
* @param context the context to be used.
|
* @param context the context to be used.
|
||||||
*/
|
*/
|
||||||
public DefaultTaskConfigurer(DataSource dataSource, String tablePrefix, ApplicationContext context) {
|
public DefaultTaskConfigurer(DataSource dataSource, String tablePrefix,
|
||||||
|
ApplicationContext context) {
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
this.context = context;
|
this.context = context;
|
||||||
|
|
||||||
TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean;
|
TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean;
|
||||||
|
|
||||||
if(this.dataSource != null) {
|
if (this.dataSource != null) {
|
||||||
taskExecutionDaoFactoryBean = new
|
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(this.dataSource,
|
||||||
TaskExecutionDaoFactoryBean(this.dataSource, tablePrefix);
|
tablePrefix);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
|
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
|
||||||
@@ -137,22 +136,27 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
if (isDataSourceAvailable()) {
|
if (isDataSourceAvailable()) {
|
||||||
try {
|
try {
|
||||||
Class.forName("javax.persistence.EntityManager");
|
Class.forName("javax.persistence.EntityManager");
|
||||||
if (this.context != null && this.context.getBeanNamesForType(EntityManager.class).length > 0) {
|
if (this.context != null && this.context
|
||||||
logger.debug("EntityManager was found, using JpaTransactionManager");
|
.getBeanNamesForType(EntityManager.class).length > 0) {
|
||||||
|
logger.debug(
|
||||||
|
"EntityManager was found, using JpaTransactionManager");
|
||||||
this.transactionManager = new JpaTransactionManager();
|
this.transactionManager = new JpaTransactionManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException ignore) {
|
catch (ClassNotFoundException ignore) {
|
||||||
logger.debug("No EntityManager was found, using DataSourceTransactionManager");
|
logger.debug(
|
||||||
|
"No EntityManager was found, using DataSourceTransactionManager");
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
if (this.transactionManager == null) {
|
if (this.transactionManager == null) {
|
||||||
this.transactionManager = new DataSourceTransactionManager(this.dataSource);
|
this.transactionManager = new DataSourceTransactionManager(
|
||||||
|
this.dataSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.debug("No DataSource was found, using ResourcelessTransactionManager");
|
logger.debug(
|
||||||
|
"No DataSource was found, using ResourcelessTransactionManager");
|
||||||
this.transactionManager = new ResourcelessTransactionManager();
|
this.transactionManager = new ResourcelessTransactionManager();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -163,4 +167,5 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
|||||||
private boolean isDataSourceAvailable() {
|
private boolean isDataSourceAvailable() {
|
||||||
return this.dataSource != null;
|
return this.dataSource != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -23,13 +23,12 @@ import java.lang.annotation.Retention;
|
|||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
import org.springframework.cloud.task.repository.TaskRepository;
|
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* Enables the {@link org.springframework.cloud.task.listener.TaskLifecycleListener}
|
* Enables the {@link org.springframework.cloud.task.listener.TaskLifecycleListener} so
|
||||||
* so that the features of Spring Cloud Task will be applied.
|
* that the features of Spring Cloud Task will be applied.
|
||||||
*
|
*
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
* @Configuration
|
* @Configuration
|
||||||
@@ -39,13 +38,14 @@ import org.springframework.context.annotation.Import;
|
|||||||
* @Bean
|
* @Bean
|
||||||
* public MyCommandLineRunner myCommandLineRunner() {
|
* public MyCommandLineRunner myCommandLineRunner() {
|
||||||
* return new MyCommandLineRunner()
|
* return new MyCommandLineRunner()
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Note that only one of your configuration classes needs to have the <code>@EnableTask</code>
|
* Note that only one of your configuration classes needs to have the
|
||||||
* annotation. Once you have an <code>@EnableTask</code> class in your configuration
|
* <code>@EnableTask</code> annotation. Once you have an
|
||||||
* the task will have the Spring Cloud Task features available.
|
* <code>@EnableTask</code> class in your configuration the task will have the Spring
|
||||||
|
* Cloud Task features available.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*
|
*
|
||||||
@@ -56,4 +56,5 @@ import org.springframework.context.annotation.Import;
|
|||||||
@Inherited
|
@Inherited
|
||||||
@Import(TaskLifecycleConfiguration.class)
|
@Import(TaskLifecycleConfiguration.class)
|
||||||
public @interface EnableTask {
|
public @interface EnableTask {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -54,10 +54,13 @@ import org.springframework.util.CollectionUtils;
|
|||||||
@Configuration
|
@Configuration
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
@EnableConfigurationProperties(TaskProperties.class)
|
@EnableConfigurationProperties(TaskProperties.class)
|
||||||
|
// @checkstyle:off
|
||||||
@ConditionalOnProperty(prefix = "spring.cloud.task.autoconfiguration", name = "enabled", havingValue = "true", matchIfMissing = true)
|
@ConditionalOnProperty(prefix = "spring.cloud.task.autoconfiguration", name = "enabled", havingValue = "true", matchIfMissing = true)
|
||||||
|
// @checkstyle:on
|
||||||
public class SimpleTaskAutoConfiguration {
|
public class SimpleTaskAutoConfiguration {
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(SimpleTaskAutoConfiguration.class);
|
protected static final Log logger = LogFactory
|
||||||
|
.getLog(SimpleTaskAutoConfiguration.class);
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
private Collection<DataSource> dataSources;
|
private Collection<DataSource> dataSources;
|
||||||
@@ -80,7 +83,7 @@ public class SimpleTaskAutoConfiguration {
|
|||||||
private TaskExplorer taskExplorer;
|
private TaskExplorer taskExplorer;
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskRepository taskRepository(){
|
public TaskRepository taskRepository() {
|
||||||
return this.taskRepository;
|
return this.taskRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +107,7 @@ public class SimpleTaskAutoConfiguration {
|
|||||||
public TaskRepositoryInitializer taskRepositoryInitializer() {
|
public TaskRepositoryInitializer taskRepositoryInitializer() {
|
||||||
TaskRepositoryInitializer taskRepositoryInitializer = new TaskRepositoryInitializer();
|
TaskRepositoryInitializer taskRepositoryInitializer = new TaskRepositoryInitializer();
|
||||||
DataSource initializerDataSource = getDefaultConfigurer().getTaskDataSource();
|
DataSource initializerDataSource = getDefaultConfigurer().getTaskDataSource();
|
||||||
if(initializerDataSource != null) {
|
if (initializerDataSource != null) {
|
||||||
taskRepositoryInitializer.setDataSource(initializerDataSource);
|
taskRepositoryInitializer.setDataSource(initializerDataSource);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,7 +119,7 @@ public class SimpleTaskAutoConfiguration {
|
|||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
if (initialized) {
|
if (this.initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,7 +131,7 @@ public class SimpleTaskAutoConfiguration {
|
|||||||
this.taskRepository = taskConfigurer.getTaskRepository();
|
this.taskRepository = taskConfigurer.getTaskRepository();
|
||||||
this.platformTransactionManager = taskConfigurer.getTransactionManager();
|
this.platformTransactionManager = taskConfigurer.getTransactionManager();
|
||||||
this.taskExplorer = taskConfigurer.getTaskExplorer();
|
this.taskExplorer = taskConfigurer.getTaskExplorer();
|
||||||
initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskConfigurer getDefaultConfigurer() {
|
private TaskConfigurer getDefaultConfigurer() {
|
||||||
@@ -138,36 +141,44 @@ public class SimpleTaskAutoConfiguration {
|
|||||||
|
|
||||||
if (configurers < 1) {
|
if (configurers < 1) {
|
||||||
TaskConfigurer taskConfigurer;
|
TaskConfigurer taskConfigurer;
|
||||||
if(!CollectionUtils.isEmpty(this.dataSources) && this.dataSources.size() == 1) {
|
if (!CollectionUtils.isEmpty(this.dataSources)
|
||||||
|
&& this.dataSources.size() == 1) {
|
||||||
taskConfigurer = new DefaultTaskConfigurer(
|
taskConfigurer = new DefaultTaskConfigurer(
|
||||||
this.dataSources.iterator().next(),
|
this.dataSources.iterator().next(),
|
||||||
taskProperties.getTablePrefix(), context);
|
this.taskProperties.getTablePrefix(), this.context);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
taskConfigurer = new DefaultTaskConfigurer(taskProperties.getTablePrefix());
|
taskConfigurer = new DefaultTaskConfigurer(
|
||||||
|
this.taskProperties.getTablePrefix());
|
||||||
}
|
}
|
||||||
this.context.getBeanFactory().registerSingleton("taskConfigurer", taskConfigurer);
|
this.context.getBeanFactory().registerSingleton("taskConfigurer",
|
||||||
|
taskConfigurer);
|
||||||
return taskConfigurer;
|
return taskConfigurer;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if(configurers == 1) {
|
if (configurers == 1) {
|
||||||
return this.context.getBean(TaskConfigurer.class);
|
return this.context.getBean(TaskConfigurer.class);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException("Expected one TaskConfigurer but found " + configurers);
|
throw new IllegalStateException(
|
||||||
|
"Expected one TaskConfigurer but found " + configurers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyEnvironment() {
|
private void verifyEnvironment() {
|
||||||
int configurers = this.context.getBeanNamesForType(TaskConfigurer.class).length;
|
int configurers = this.context.getBeanNamesForType(TaskConfigurer.class).length;
|
||||||
// retrieve the count of dataSources (without instantiating them) excluding DataSource proxy beans
|
// retrieve the count of dataSources (without instantiating them) excluding
|
||||||
long dataSources = Arrays.stream(this.context.getBeanNamesForType(DataSource.class))
|
// DataSource proxy beans
|
||||||
|
long dataSources = Arrays
|
||||||
|
.stream(this.context.getBeanNamesForType(DataSource.class))
|
||||||
.filter((name -> !ScopedProxyUtils.isScopedTarget(name))).count();
|
.filter((name -> !ScopedProxyUtils.isScopedTarget(name))).count();
|
||||||
|
|
||||||
if(configurers == 0 && dataSources > 1) {
|
if (configurers == 0 && dataSources > 1) {
|
||||||
throw new IllegalStateException("To use the default TaskConfigurer the context must contain no more than" +
|
throw new IllegalStateException(
|
||||||
" one DataSource, found " + dataSources);
|
"To use the default TaskConfigurer the context must contain no more than"
|
||||||
|
+ " one DataSource, found " + dataSources);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
@@ -39,10 +39,10 @@ import org.springframework.integration.support.leader.LockRegistryLeaderInitiato
|
|||||||
import org.springframework.integration.support.locks.LockRegistry;
|
import org.springframework.integration.support.locks.LockRegistry;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When spring.cloud.task.single-instance-enabled is set to true this listener will create a lock for the task
|
* When spring.cloud.task.single-instance-enabled is set to true this listener will create
|
||||||
* based on the spring.cloud.task.name. If a lock already exists this Listener will throw
|
* a lock for the task based on the spring.cloud.task.name. If a lock already exists this
|
||||||
* a TaskExecutionException. If this listener is added manually, then it should
|
* Listener will throw a TaskExecutionException. If this listener is added manually, then
|
||||||
* be added as the first listener in the chain.
|
* it should be added as the first listener in the chain.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
@@ -68,19 +68,18 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
|||||||
private TaskProperties taskProperties;
|
private TaskProperties taskProperties;
|
||||||
|
|
||||||
public SingleInstanceTaskListener(LockRegistry lockRegistry,
|
public SingleInstanceTaskListener(LockRegistry lockRegistry,
|
||||||
TaskNameResolver taskNameResolver,
|
TaskNameResolver taskNameResolver, TaskProperties taskProperties,
|
||||||
TaskProperties taskProperties,
|
|
||||||
ApplicationEventPublisher applicationEventPublisher) {
|
ApplicationEventPublisher applicationEventPublisher) {
|
||||||
this.lockRegistry = lockRegistry;
|
this.lockRegistry = lockRegistry;
|
||||||
this.taskNameResolver = taskNameResolver;
|
this.taskNameResolver = taskNameResolver;
|
||||||
this.taskProperties = taskProperties;
|
this.taskProperties = taskProperties;
|
||||||
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(this.lockRegistry);
|
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
|
||||||
|
this.lockRegistry);
|
||||||
this.applicationEventPublisher = applicationEventPublisher;
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SingleInstanceTaskListener(DataSource dataSource,
|
public SingleInstanceTaskListener(DataSource dataSource,
|
||||||
TaskNameResolver taskNameResolver,
|
TaskNameResolver taskNameResolver, TaskProperties taskProperties,
|
||||||
TaskProperties taskProperties,
|
|
||||||
ApplicationEventPublisher applicationEventPublisher) {
|
ApplicationEventPublisher applicationEventPublisher) {
|
||||||
this.taskNameResolver = taskNameResolver;
|
this.taskNameResolver = taskNameResolver;
|
||||||
this.applicationEventPublisher = applicationEventPublisher;
|
this.applicationEventPublisher = applicationEventPublisher;
|
||||||
@@ -90,14 +89,15 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
|||||||
|
|
||||||
@BeforeTask
|
@BeforeTask
|
||||||
public void lockTask(TaskExecution taskExecution) {
|
public void lockTask(TaskExecution taskExecution) {
|
||||||
if(this.lockRegistry == null ) {
|
if (this.lockRegistry == null) {
|
||||||
this.lockRegistry = getDefaultLockRegistry(taskExecution.getExecutionId());
|
this.lockRegistry = getDefaultLockRegistry(taskExecution.getExecutionId());
|
||||||
}
|
}
|
||||||
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
|
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
|
||||||
this.lockRegistry,
|
this.lockRegistry,
|
||||||
new DefaultCandidate(String.valueOf(taskExecution.getExecutionId()),
|
new DefaultCandidate(String.valueOf(taskExecution.getExecutionId()),
|
||||||
taskNameResolver.getTaskName()));
|
this.taskNameResolver.getTaskName()));
|
||||||
this.lockRegistryLeaderInitiator.setApplicationEventPublisher(this.applicationEventPublisher);
|
this.lockRegistryLeaderInitiator
|
||||||
|
.setApplicationEventPublisher(this.applicationEventPublisher);
|
||||||
this.lockRegistryLeaderInitiator.setPublishFailedEvents(true);
|
this.lockRegistryLeaderInitiator.setPublishFailedEvents(true);
|
||||||
this.lockRegistryLeaderInitiator.start();
|
this.lockRegistryLeaderInitiator.start();
|
||||||
while (!this.lockReady) {
|
while (!this.lockReady) {
|
||||||
@@ -115,7 +115,8 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
|||||||
this.lockRegistryLeaderInitiator.destroy();
|
this.lockRegistryLeaderInitiator.destroy();
|
||||||
}
|
}
|
||||||
catch (Exception exception) {
|
catch (Exception exception) {
|
||||||
throw new TaskExecutionException("Failed to destroy lock.", exception);
|
throw new TaskExecutionException("Failed to destroy lock.",
|
||||||
|
exception);
|
||||||
}
|
}
|
||||||
throw new TaskExecutionException(errorMessage);
|
throw new TaskExecutionException(errorMessage);
|
||||||
}
|
}
|
||||||
@@ -128,7 +129,8 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
|||||||
}
|
}
|
||||||
|
|
||||||
@FailedTask
|
@FailedTask
|
||||||
public void unlockTaskOnError(TaskExecution taskExecution, Throwable throwable) throws Exception {
|
public void unlockTaskOnError(TaskExecution taskExecution, Throwable throwable)
|
||||||
|
throws Exception {
|
||||||
this.lockRegistryLeaderInitiator.destroy();
|
this.lockRegistryLeaderInitiator.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,13 +144,13 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private LockRegistry getDefaultLockRegistry( long executionId) {
|
private LockRegistry getDefaultLockRegistry(long executionId) {
|
||||||
DefaultLockRepository lockRepository =
|
DefaultLockRepository lockRepository = new DefaultLockRepository(this.dataSource,
|
||||||
new DefaultLockRepository(this.dataSource, String.valueOf(
|
String.valueOf(executionId));
|
||||||
executionId));
|
|
||||||
lockRepository.setPrefix(this.taskProperties.getTablePrefix());
|
lockRepository.setPrefix(this.taskProperties.getTablePrefix());
|
||||||
lockRepository.setTimeToLive(this.taskProperties.getSingleInstanceLockTtl());
|
lockRepository.setTimeToLive(this.taskProperties.getSingleInstanceLockTtl());
|
||||||
lockRepository.afterPropertiesSet();
|
lockRepository.afterPropertiesSet();
|
||||||
return new JdbcLockRegistry(lockRepository);
|
return new JdbcLockRegistry(lockRepository);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
@@ -47,17 +47,15 @@ public class SingleTaskConfiguration {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private TaskConfigurer taskConfigurer;
|
private TaskConfigurer taskConfigurer;
|
||||||
|
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public SingleInstanceTaskListener taskListener(TaskNameResolver resolver) {
|
public SingleInstanceTaskListener taskListener(TaskNameResolver resolver) {
|
||||||
if (taskConfigurer.getTaskDataSource() == null) {
|
if (this.taskConfigurer.getTaskDataSource() == null) {
|
||||||
return new SingleInstanceTaskListener(new PassThruLockRegistry(),
|
return new SingleInstanceTaskListener(new PassThruLockRegistry(), resolver,
|
||||||
resolver, this.taskProperties, this.applicationEventPublisher);
|
this.taskProperties, this.applicationEventPublisher);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SingleInstanceTaskListener(taskConfigurer.getTaskDataSource(),
|
return new SingleInstanceTaskListener(this.taskConfigurer.getTaskDataSource(),
|
||||||
resolver,
|
resolver, this.taskProperties, this.applicationEventPublisher);
|
||||||
this.taskProperties,
|
|
||||||
this.applicationEventPublisher);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -23,10 +23,9 @@ import org.springframework.cloud.task.repository.TaskRepository;
|
|||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a strategy interface for providing configuration
|
* Provides a strategy interface for providing configuration customization to the task
|
||||||
* customization to the task system. Users should not directly use getter methods
|
* system. Users should not directly use getter methods from a <code>TaskConfigurer</code>
|
||||||
* from a <code>TaskConfigurer</code> directly unless they are using it to supply the implementations
|
* directly unless they are using it to supply the implementations for Spring Beans.
|
||||||
* for Spring Beans.
|
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@@ -34,7 +33,6 @@ public interface TaskConfigurer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link TaskRepository} for the Task.
|
* Create a {@link TaskRepository} for the Task.
|
||||||
*
|
|
||||||
* @return A TaskRepository
|
* @return A TaskRepository
|
||||||
*/
|
*/
|
||||||
TaskRepository getTaskRepository();
|
TaskRepository getTaskRepository();
|
||||||
@@ -42,23 +40,22 @@ public interface TaskConfigurer {
|
|||||||
/**
|
/**
|
||||||
* Create a {@link PlatformTransactionManager} for use with the
|
* Create a {@link PlatformTransactionManager} for use with the
|
||||||
* <code>TaskRepository</code>.
|
* <code>TaskRepository</code>.
|
||||||
*
|
|
||||||
* @return A <code>PlatformTransactionManager</code>
|
* @return A <code>PlatformTransactionManager</code>
|
||||||
*/
|
*/
|
||||||
PlatformTransactionManager getTransactionManager();
|
PlatformTransactionManager getTransactionManager();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a {@link TaskExplorer} for the task.
|
* Create a {@link TaskExplorer} for the task.
|
||||||
*
|
|
||||||
* @return a <code>TaskExplorer</code>
|
* @return a <code>TaskExplorer</code>
|
||||||
*/
|
*/
|
||||||
TaskExplorer getTaskExplorer();
|
TaskExplorer getTaskExplorer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the {@link DataSource} that will be used for task operations. If a
|
* Retrieves the {@link DataSource} that will be used for task operations. If a
|
||||||
* DataSource is not being used for the implemented TaskConfigurer this
|
* DataSource is not being used for the implemented TaskConfigurer this method will
|
||||||
* method will return null.
|
* return null.
|
||||||
* @return {@link DataSource} that will be used for task operations.
|
* @return {@link DataSource} that will be used for task operations.
|
||||||
*/
|
*/
|
||||||
DataSource getTaskDataSource();
|
DataSource getTaskDataSource();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
@@ -43,7 +43,8 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
@Configuration
|
@Configuration
|
||||||
public class TaskLifecycleConfiguration {
|
public class TaskLifecycleConfiguration {
|
||||||
|
|
||||||
protected static final Log logger = LogFactory.getLog(TaskLifecycleConfiguration.class);
|
protected static final Log logger = LogFactory
|
||||||
|
.getLog(TaskLifecycleConfiguration.class);
|
||||||
|
|
||||||
private TaskProperties taskProperties;
|
private TaskProperties taskProperties;
|
||||||
|
|
||||||
@@ -63,10 +64,8 @@ public class TaskLifecycleConfiguration {
|
|||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public TaskLifecycleConfiguration(TaskProperties taskProperties,
|
public TaskLifecycleConfiguration(TaskProperties taskProperties,
|
||||||
ConfigurableApplicationContext context,
|
ConfigurableApplicationContext context, TaskRepository taskRepository,
|
||||||
TaskRepository taskRepository,
|
TaskExplorer taskExplorer, TaskNameResolver taskNameResolver,
|
||||||
TaskExplorer taskExplorer,
|
|
||||||
TaskNameResolver taskNameResolver,
|
|
||||||
ObjectProvider<ApplicationArguments> applicationArguments) {
|
ObjectProvider<ApplicationArguments> applicationArguments) {
|
||||||
|
|
||||||
this.taskProperties = taskProperties;
|
this.taskProperties = taskProperties;
|
||||||
@@ -88,15 +87,13 @@ public class TaskLifecycleConfiguration {
|
|||||||
@PostConstruct
|
@PostConstruct
|
||||||
protected void initialize() {
|
protected void initialize() {
|
||||||
if (!this.initialized) {
|
if (!this.initialized) {
|
||||||
this.taskLifecycleListener =
|
this.taskLifecycleListener = new TaskLifecycleListener(this.taskRepository,
|
||||||
new TaskLifecycleListener(this.taskRepository,
|
this.taskNameResolver, this.applicationArguments, this.taskExplorer,
|
||||||
this.taskNameResolver,
|
this.taskProperties,
|
||||||
this.applicationArguments,
|
new TaskListenerExecutorObjectFactory(this.context));
|
||||||
this.taskExplorer,
|
|
||||||
this.taskProperties,
|
|
||||||
new TaskListenerExecutorObjectFactory(context));
|
|
||||||
|
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,21 @@
|
|||||||
/*
|
/*
|
||||||
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
|
|
||||||
|
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
@@ -32,11 +31,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|||||||
@ConfigurationProperties(prefix = "spring.cloud.task")
|
@ConfigurationProperties(prefix = "spring.cloud.task")
|
||||||
public class TaskProperties {
|
public class TaskProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default table prefix for Spring Cloud Task.
|
||||||
|
*/
|
||||||
|
public static final String DEFAULT_TABLE_PREFIX = "TASK_";
|
||||||
|
|
||||||
private static final int DEFAULT_CHECK_INTERVAL = 500;
|
private static final int DEFAULT_CHECK_INTERVAL = 500;
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(TaskProperties.class);
|
private static final Log logger = LogFactory.getLog(TaskProperties.class);
|
||||||
|
|
||||||
public static final String DEFAULT_TABLE_PREFIX = "TASK_";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An id that can be associated with a task.
|
* An id that can be associated with a task.
|
||||||
@@ -49,8 +51,8 @@ public class TaskProperties {
|
|||||||
private Long executionid;
|
private Long executionid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The id of the parent task execution id that launched this task execution.
|
* The id of the parent task execution id that launched this task execution. Defaults
|
||||||
* Defaults to null if task execution had no parent.
|
* to null if task execution had no parent.
|
||||||
*/
|
*/
|
||||||
private Long parentExecutionId;
|
private Long parentExecutionId;
|
||||||
|
|
||||||
@@ -60,35 +62,34 @@ public class TaskProperties {
|
|||||||
private String tablePrefix = DEFAULT_TABLE_PREFIX;
|
private String tablePrefix = DEFAULT_TABLE_PREFIX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When set to true the context is closed at the end of the task. Else
|
* When set to true the context is closed at the end of the task. Else the context
|
||||||
* the context remains open.
|
* remains open.
|
||||||
*/
|
*/
|
||||||
private Boolean closecontextEnabled = false;
|
private Boolean closecontextEnabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When set to true it
|
* When set to true it will check to see if a task execution with the same task name
|
||||||
* will check to see if a task execution with the same task name is already
|
* is already running. If a task is still running then it will throw a
|
||||||
* running. If a task is still running then it will throw a
|
* {@link org.springframework.cloud.task.listener.TaskExecutionException}. When task
|
||||||
* {@link org.springframework.cloud.task.listener.TaskExecutionException}.
|
* execution ends the lock is released.
|
||||||
* When task execution ends the lock is released.
|
|
||||||
*/
|
*/
|
||||||
private boolean singleInstanceEnabled = false;
|
private boolean singleInstanceEnabled = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declares the maximum amount of time (in millis) that a task execution can
|
* Declares the maximum amount of time (in millis) that a task execution can hold a
|
||||||
* hold a lock to prevent another task from executing with a specific task
|
* lock to prevent another task from executing with a specific task name when the
|
||||||
* name when the single-instance-enabled is set to true. Default time is: Integer.MAX_VALUE.
|
* single-instance-enabled is set to true. Default time is: Integer.MAX_VALUE.
|
||||||
*/
|
*/
|
||||||
private int singleInstanceLockTtl = Integer.MAX_VALUE;
|
private int singleInstanceLockTtl = Integer.MAX_VALUE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declares the time (in millis) that a task execution will wait between
|
* Declares the time (in millis) that a task execution will wait between checks.
|
||||||
* checks. Default time is: 500 millis.
|
* Default time is: 500 millis.
|
||||||
*/
|
*/
|
||||||
private int singleInstanceLockCheckInterval = DEFAULT_CHECK_INTERVAL;
|
private int singleInstanceLockCheckInterval = DEFAULT_CHECK_INTERVAL;
|
||||||
|
|
||||||
public String getExternalExecutionId() {
|
public String getExternalExecutionId() {
|
||||||
return externalExecutionId;
|
return this.externalExecutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExternalExecutionId(String externalExecutionId) {
|
public void setExternalExecutionId(String externalExecutionId) {
|
||||||
@@ -96,7 +97,7 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Long getExecutionid() {
|
public Long getExecutionid() {
|
||||||
return executionid;
|
return this.executionid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExecutionid(Long executionid) {
|
public void setExecutionid(Long executionid) {
|
||||||
@@ -104,7 +105,7 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getClosecontextEnabled() {
|
public Boolean getClosecontextEnabled() {
|
||||||
return closecontextEnabled;
|
return this.closecontextEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setClosecontextEnabled(Boolean closecontextEnabled) {
|
public void setClosecontextEnabled(Boolean closecontextEnabled) {
|
||||||
@@ -112,7 +113,7 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getTablePrefix() {
|
public String getTablePrefix() {
|
||||||
return tablePrefix;
|
return this.tablePrefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTablePrefix(String tablePrefix) {
|
public void setTablePrefix(String tablePrefix) {
|
||||||
@@ -120,7 +121,7 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Long getParentExecutionId() {
|
public Long getParentExecutionId() {
|
||||||
return parentExecutionId;
|
return this.parentExecutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParentExecutionId(Long parentExecutionId) {
|
public void setParentExecutionId(Long parentExecutionId) {
|
||||||
@@ -128,7 +129,7 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean getSingleInstanceEnabled() {
|
public boolean getSingleInstanceEnabled() {
|
||||||
return singleInstanceEnabled;
|
return this.singleInstanceEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSingleInstanceEnabled(boolean singleInstanceEnabled) {
|
public void setSingleInstanceEnabled(boolean singleInstanceEnabled) {
|
||||||
@@ -136,7 +137,7 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getSingleInstanceLockTtl() {
|
public int getSingleInstanceLockTtl() {
|
||||||
return singleInstanceLockTtl;
|
return this.singleInstanceLockTtl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSingleInstanceLockTtl(int singleInstanceLockTtl) {
|
public void setSingleInstanceLockTtl(int singleInstanceLockTtl) {
|
||||||
@@ -144,10 +145,11 @@ public class TaskProperties {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getSingleInstanceLockCheckInterval() {
|
public int getSingleInstanceLockCheckInterval() {
|
||||||
return singleInstanceLockCheckInterval;
|
return this.singleInstanceLockCheckInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSingleInstanceLockCheckInterval(int singleInstanceLockCheckInterval) {
|
public void setSingleInstanceLockCheckInterval(int singleInstanceLockCheckInterval) {
|
||||||
this.singleInstanceLockCheckInterval = singleInstanceLockCheckInterval;
|
this.singleInstanceLockCheckInterval = singleInstanceLockCheckInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interfaces for configuring Spring Cloud Task and a default implementations.
|
* Interfaces for configuring Spring Cloud Task and a default implementations.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,15 +18,16 @@ package org.springframework.cloud.task.listener;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Base Exception for any Task issues.
|
* Base Exception for any Task issues.
|
||||||
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class TaskException extends RuntimeException {
|
public class TaskException extends RuntimeException {
|
||||||
|
|
||||||
public TaskException(String message, Throwable e){
|
public TaskException(String message, Throwable e) {
|
||||||
super(message, e);
|
super(message, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskException(String message){
|
public TaskException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -23,11 +23,12 @@ package org.springframework.cloud.task.listener;
|
|||||||
*/
|
*/
|
||||||
public class TaskExecutionException extends TaskException {
|
public class TaskExecutionException extends TaskException {
|
||||||
|
|
||||||
public TaskExecutionException(String message){
|
public TaskExecutionException(String message) {
|
||||||
super(message);
|
super(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskExecutionException(String message, Throwable throwable){
|
public TaskExecutionException(String message, Throwable throwable) {
|
||||||
super(message, throwable);
|
super(message, throwable);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -21,29 +21,32 @@ import org.springframework.cloud.task.repository.TaskRepository;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The listener interface for receiving task execution events.
|
* The listener interface for receiving task execution events.
|
||||||
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public interface TaskExecutionListener {
|
public interface TaskExecutionListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked after the {@link TaskExecution} has been stored in the {@link TaskRepository}.
|
* Invoked after the {@link TaskExecution} has been stored in the
|
||||||
|
* {@link TaskRepository}.
|
||||||
* @param taskExecution instance containing the information about the current task.
|
* @param taskExecution instance containing the information about the current task.
|
||||||
*/
|
*/
|
||||||
void onTaskStartup(TaskExecution taskExecution);
|
void onTaskStartup(TaskExecution taskExecution);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked before the {@link TaskExecution} has been updated in the {@link TaskRepository}
|
* Invoked before the {@link TaskExecution} has been updated in the
|
||||||
* upon task end.
|
* {@link TaskRepository} upon task end.
|
||||||
* @param taskExecution instance containing the information about the current task.
|
* @param taskExecution instance containing the information about the current task.
|
||||||
*/
|
*/
|
||||||
void onTaskEnd(TaskExecution taskExecution);
|
void onTaskEnd(TaskExecution taskExecution);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invoked if an uncaught exception occurs during a task execution. This invocation
|
* Invoked if an uncaught exception occurs during a task execution. This invocation
|
||||||
* will occur before the {@link TaskExecution} has been updated in the {@link TaskRepository}
|
* will occur before the {@link TaskExecution} has been updated in the
|
||||||
* and before the onTaskEnd is called.
|
* {@link TaskRepository} and before the onTaskEnd is called.
|
||||||
* @param taskExecution instance containing the information about the current task.
|
* @param taskExecution instance containing the information about the current task.
|
||||||
* @param throwable the uncaught exception that was thrown during task execution.
|
* @param throwable the uncaught exception that was thrown during task execution.
|
||||||
*/
|
*/
|
||||||
void onTaskFailed(TaskExecution taskExecution, Throwable throwable);
|
void onTaskFailed(TaskExecution taskExecution, Throwable throwable);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.listener;
|
package org.springframework.cloud.task.listener;
|
||||||
|
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
@@ -25,6 +26,7 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
|||||||
* @since 1.2
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public class TaskExecutionListenerSupport implements TaskExecutionListener {
|
public class TaskExecutionListenerSupport implements TaskExecutionListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskStartup(TaskExecution taskExecution) {
|
public void onTaskStartup(TaskExecution taskExecution) {
|
||||||
|
|
||||||
@@ -39,4 +41,5 @@ public class TaskExecutionListenerSupport implements TaskExecutionListener {
|
|||||||
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.listener;
|
package org.springframework.cloud.task.listener;
|
||||||
|
|
||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
@@ -49,33 +50,42 @@ import org.springframework.util.CollectionUtils;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitors the lifecycle of a task. This listener will record both the start and end of
|
* Monitors the lifecycle of a task. This listener will record both the start and end of a
|
||||||
* a task in the registered {@link TaskRepository}.
|
* task in the registered {@link TaskRepository}.
|
||||||
*
|
*
|
||||||
* The following events are used to identify the start and end of a task:
|
* The following events are used to identify the start and end of a task:
|
||||||
*
|
*
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link SmartLifecycle#start()} - Used to identify the start of a task. A task
|
* <li>{@link SmartLifecycle#start()} - Used to identify the start of a task. A task is
|
||||||
* is expected to contain a single application context.</li>
|
* expected to contain a single application context.</li>
|
||||||
* <li>{@link ApplicationReadyEvent} - Used to identify the successful end of a task.</li>
|
* <li>{@link ApplicationReadyEvent} - Used to identify the successful end of a task.</li>
|
||||||
* <li>{@link ApplicationFailedEvent} - Used to identify the failure of a task.</li>
|
* <li>{@link ApplicationFailedEvent} - Used to identify the failure of a task.</li>
|
||||||
* <li>{@link SmartLifecycle#stop()} - Used to identify the end of a task,
|
* <li>{@link SmartLifecycle#stop()} - Used to identify the end of a task, if the
|
||||||
* if the {@link ApplicationReadyEvent} or {@link ApplicationFailedEvent}
|
* {@link ApplicationReadyEvent} or {@link ApplicationFailedEvent} is not emitted. This
|
||||||
* is not emitted. This can occur if an error occurs while executing a BeforeTask.
|
* can occur if an error occurs while executing a BeforeTask.</li>
|
||||||
* </li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <b>Note:</b> By default, the context will close at the completion of the task unless other non-daemon
|
* <b>Note:</b> By default, the context will close at the completion of the task unless
|
||||||
* threads keep it running. Programatic closing of the context can be configured via the
|
* other non-daemon threads keep it running. Programatic closing of the context can be
|
||||||
* property <code>spring.cloud.task.closecontext.enabled</code> (defaults to false).
|
* configured via the property <code>spring.cloud.task.closecontext.enabled</code>
|
||||||
* If the <code>spring.cloud.task.closecontext.enabled</code> is set to true,
|
* (defaults to false). If the <code>spring.cloud.task.closecontext.enabled</code> is set
|
||||||
* then the context will be closed upon task completion regardless if non-daemon threads are still running.
|
* to true, then the context will be closed upon task completion regardless if non-daemon
|
||||||
* Also if the context did not start, the FailedTask and TaskEnd may not have all the dependencies met.
|
* threads are still running. Also if the context did not start, the FailedTask and
|
||||||
|
* TaskEnd may not have all the dependencies met.
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class TaskLifecycleListener implements ApplicationListener<ApplicationEvent>, SmartLifecycle, DisposableBean {
|
public class TaskLifecycleListener
|
||||||
|
implements ApplicationListener<ApplicationEvent>, SmartLifecycle, DisposableBean {
|
||||||
|
|
||||||
|
private static final Log logger = LogFactory.getLog(TaskLifecycleListener.class);
|
||||||
|
|
||||||
|
private final TaskRepository taskRepository;
|
||||||
|
|
||||||
|
private final TaskExplorer taskExplorer;
|
||||||
|
|
||||||
|
private final TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConfigurableApplicationContext context;
|
private ConfigurableApplicationContext context;
|
||||||
@@ -85,14 +95,6 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
|
|
||||||
private List<TaskExecutionListener> taskExecutionListeners;
|
private List<TaskExecutionListener> taskExecutionListeners;
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(TaskLifecycleListener.class);
|
|
||||||
|
|
||||||
private final TaskRepository taskRepository;
|
|
||||||
|
|
||||||
private final TaskExplorer taskExplorer;
|
|
||||||
|
|
||||||
private final TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory;
|
|
||||||
|
|
||||||
private TaskExecution taskExecution;
|
private TaskExecution taskExecution;
|
||||||
|
|
||||||
private TaskProperties taskProperties;
|
private TaskProperties taskProperties;
|
||||||
@@ -115,22 +117,25 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param taskRepository {@link TaskRepository} to record executions.
|
* @param taskRepository {@link TaskRepository} to record executions.
|
||||||
* @param taskNameResolver {@link TaskNameResolver} used to determine task name for task execution.
|
* @param taskNameResolver {@link TaskNameResolver} used to determine task name for
|
||||||
* @param applicationArguments {@link ApplicationArguments} to be used for task execution.
|
* task execution.
|
||||||
|
* @param applicationArguments {@link ApplicationArguments} to be used for task
|
||||||
|
* execution.
|
||||||
* @param taskExplorer {@link TaskExplorer} to be used for task execution.
|
* @param taskExplorer {@link TaskExplorer} to be used for task execution.
|
||||||
* @param taskProperties {@link TaskProperties} to be used for the task execution.
|
* @param taskProperties {@link TaskProperties} to be used for the task execution.
|
||||||
* @param taskListenerExecutorObjectFactory {@link TaskListenerExecutorObjectFactory} to initialize TaskListenerExecutor for a task
|
* @param taskListenerExecutorObjectFactory {@link TaskListenerExecutorObjectFactory}
|
||||||
|
* to initialize TaskListenerExecutor for a task
|
||||||
*/
|
*/
|
||||||
public TaskLifecycleListener(TaskRepository taskRepository,
|
public TaskLifecycleListener(TaskRepository taskRepository,
|
||||||
TaskNameResolver taskNameResolver,
|
TaskNameResolver taskNameResolver, ApplicationArguments applicationArguments,
|
||||||
ApplicationArguments applicationArguments, TaskExplorer taskExplorer,
|
TaskExplorer taskExplorer, TaskProperties taskProperties,
|
||||||
TaskProperties taskProperties,
|
|
||||||
TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory) {
|
TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory) {
|
||||||
Assert.notNull(taskRepository, "A taskRepository is required");
|
Assert.notNull(taskRepository, "A taskRepository is required");
|
||||||
Assert.notNull(taskNameResolver, "A taskNameResolver is required");
|
Assert.notNull(taskNameResolver, "A taskNameResolver is required");
|
||||||
Assert.notNull(taskExplorer, "A taskExplorer is required");
|
Assert.notNull(taskExplorer, "A taskExplorer is required");
|
||||||
Assert.notNull(taskProperties, "TaskProperties is required");
|
Assert.notNull(taskProperties, "TaskProperties is required");
|
||||||
Assert.notNull(taskListenerExecutorObjectFactory, "A TaskListenerExecutorObjectFactory is required");
|
Assert.notNull(taskListenerExecutorObjectFactory,
|
||||||
|
"A TaskListenerExecutorObjectFactory is required");
|
||||||
|
|
||||||
this.taskRepository = taskRepository;
|
this.taskRepository = taskRepository;
|
||||||
this.taskNameResolver = taskNameResolver;
|
this.taskNameResolver = taskNameResolver;
|
||||||
@@ -141,25 +146,25 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utilizes {@link ApplicationEvent}s to determine the end and failure of a
|
* Utilizes {@link ApplicationEvent}s to determine the end and failure of a task.
|
||||||
* task. Specifically:
|
* Specifically:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link ApplicationReadyEvent} - Successful end of a task</li>
|
* <li>{@link ApplicationReadyEvent} - Successful end of a task</li>
|
||||||
* <li>{@link ApplicationFailedEvent} - Failure of a task</li>
|
* <li>{@link ApplicationFailedEvent} - Failure of a task</li>
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
|
||||||
* @param applicationEvent The application being listened for.
|
* @param applicationEvent The application being listened for.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
||||||
if(applicationEvent instanceof ApplicationFailedEvent) {
|
if (applicationEvent instanceof ApplicationFailedEvent) {
|
||||||
this.applicationFailedException = ((ApplicationFailedEvent) applicationEvent).getException();
|
this.applicationFailedException = ((ApplicationFailedEvent) applicationEvent)
|
||||||
|
.getException();
|
||||||
doTaskEnd();
|
doTaskEnd();
|
||||||
}
|
}
|
||||||
else if(applicationEvent instanceof ExitCodeEvent){
|
else if (applicationEvent instanceof ExitCodeEvent) {
|
||||||
this.exitCodeEvent = (ExitCodeEvent) applicationEvent;
|
this.exitCodeEvent = (ExitCodeEvent) applicationEvent;
|
||||||
}
|
}
|
||||||
else if(applicationEvent instanceof ApplicationReadyEvent) {
|
else if (applicationEvent instanceof ApplicationReadyEvent) {
|
||||||
doTaskEnd();
|
doTaskEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,37 +179,41 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void doTaskEnd() {
|
private void doTaskEnd() {
|
||||||
if((this.listenerFailed || this.started) && !this.finished) {
|
if ((this.listenerFailed || this.started) && !this.finished) {
|
||||||
this.taskExecution.setEndTime(new Date());
|
this.taskExecution.setEndTime(new Date());
|
||||||
|
|
||||||
if(this.applicationFailedException != null) {
|
if (this.applicationFailedException != null) {
|
||||||
this.taskExecution.setErrorMessage(stackTraceToString(this.applicationFailedException));
|
this.taskExecution.setErrorMessage(
|
||||||
|
stackTraceToString(this.applicationFailedException));
|
||||||
}
|
}
|
||||||
|
|
||||||
this.taskExecution.setExitCode(calcExitStatus());
|
this.taskExecution.setExitCode(calcExitStatus());
|
||||||
if (this.applicationFailedException != null) {
|
if (this.applicationFailedException != null) {
|
||||||
setExitMessage(invokeOnTaskError(this.taskExecution, this.applicationFailedException));
|
setExitMessage(invokeOnTaskError(this.taskExecution,
|
||||||
|
this.applicationFailedException));
|
||||||
}
|
}
|
||||||
|
|
||||||
setExitMessage(invokeOnTaskEnd(this.taskExecution));
|
setExitMessage(invokeOnTaskEnd(this.taskExecution));
|
||||||
this.taskRepository.completeTaskExecution(this.taskExecution.getExecutionId(), this.taskExecution.getExitCode(),
|
this.taskRepository.completeTaskExecution(this.taskExecution.getExecutionId(),
|
||||||
this.taskExecution.getEndTime(), this.taskExecution.getExitMessage(), this.taskExecution.getErrorMessage());
|
this.taskExecution.getExitCode(), this.taskExecution.getEndTime(),
|
||||||
|
this.taskExecution.getExitMessage(),
|
||||||
|
this.taskExecution.getErrorMessage());
|
||||||
|
|
||||||
this.finished = true;
|
this.finished = true;
|
||||||
|
|
||||||
if(this.taskProperties.getClosecontextEnabled() && this.context.isActive()) {
|
if (this.taskProperties.getClosecontextEnabled() && this.context.isActive()) {
|
||||||
this.context.close();
|
this.context.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if(!this.started){
|
else if (!this.started) {
|
||||||
logger.error("An event to end a task has been received for a task that has " +
|
logger.error("An event to end a task has been received for a task that has "
|
||||||
"not yet started.");
|
+ "not yet started.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setExitMessage(TaskExecution taskExecutionParam) {
|
private void setExitMessage(TaskExecution taskExecutionParam) {
|
||||||
if(taskExecutionParam.getExitMessage() != null) {
|
if (taskExecutionParam.getExitMessage() != null) {
|
||||||
this.taskExecution.setExitMessage(taskExecutionParam.getExitMessage());
|
this.taskExecution.setExitMessage(taskExecutionParam.getExitMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,10 +227,12 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
Throwable exception = this.listenerException;
|
Throwable exception = this.listenerException;
|
||||||
if (exception instanceof TaskExecutionException) {
|
if (exception instanceof TaskExecutionException) {
|
||||||
TaskExecutionException taskExecutionException = (TaskExecutionException) exception;
|
TaskExecutionException taskExecutionException = (TaskExecutionException) exception;
|
||||||
if (taskExecutionException.getCause() instanceof InvocationTargetException) {
|
if (taskExecutionException
|
||||||
|
.getCause() instanceof InvocationTargetException) {
|
||||||
InvocationTargetException invocationTargetException = (InvocationTargetException) taskExecutionException
|
InvocationTargetException invocationTargetException = (InvocationTargetException) taskExecutionException
|
||||||
.getCause();
|
.getCause();
|
||||||
if(invocationTargetException != null && invocationTargetException.getTargetException() != null) {
|
if (invocationTargetException != null
|
||||||
|
&& invocationTargetException.getTargetException() != null) {
|
||||||
exception = invocationTargetException.getTargetException();
|
exception = invocationTargetException.getTargetException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,25 +251,32 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
|
|
||||||
private void doTaskStart() {
|
private void doTaskStart() {
|
||||||
try {
|
try {
|
||||||
if(!this.started) {
|
if (!this.started) {
|
||||||
this.taskExecutionListeners = new ArrayList<>();
|
this.taskExecutionListeners = new ArrayList<>();
|
||||||
this.taskListenerExecutorObjectFactory.getObject();
|
this.taskListenerExecutorObjectFactory.getObject();
|
||||||
if(!CollectionUtils.isEmpty(this.taskExecutionListenersFromContext)) {
|
if (!CollectionUtils.isEmpty(this.taskExecutionListenersFromContext)) {
|
||||||
this.taskExecutionListeners.addAll(this.taskExecutionListenersFromContext);
|
this.taskExecutionListeners
|
||||||
|
.addAll(this.taskExecutionListenersFromContext);
|
||||||
}
|
}
|
||||||
this.taskExecutionListeners.add(this.taskListenerExecutorObjectFactory.getObject());
|
this.taskExecutionListeners
|
||||||
|
.add(this.taskListenerExecutorObjectFactory.getObject());
|
||||||
|
|
||||||
List<String> args = new ArrayList<>(0);
|
List<String> args = new ArrayList<>(0);
|
||||||
|
|
||||||
if(this.applicationArguments != null) {
|
if (this.applicationArguments != null) {
|
||||||
args = Arrays.asList(this.applicationArguments.getSourceArgs());
|
args = Arrays.asList(this.applicationArguments.getSourceArgs());
|
||||||
}
|
}
|
||||||
if(this.taskProperties.getExecutionid() != null) {
|
if (this.taskProperties.getExecutionid() != null) {
|
||||||
TaskExecution taskExecution = this.taskExplorer.getTaskExecution(this.taskProperties.getExecutionid());
|
TaskExecution taskExecution = this.taskExplorer
|
||||||
Assert.notNull(taskExecution, String.format("Invalid TaskExecution, ID %s not found", this.taskProperties.getExecutionid()));
|
.getTaskExecution(this.taskProperties.getExecutionid());
|
||||||
|
Assert.notNull(taskExecution,
|
||||||
|
String.format("Invalid TaskExecution, ID %s not found",
|
||||||
|
this.taskProperties.getExecutionid()));
|
||||||
Assert.isNull(taskExecution.getEndTime(), String.format(
|
Assert.isNull(taskExecution.getEndTime(), String.format(
|
||||||
"Invalid TaskExecution, ID %s task is already complete", this.taskProperties.getExecutionid()));
|
"Invalid TaskExecution, ID %s task is already complete",
|
||||||
this.taskExecution = this.taskRepository.startTaskExecution(this.taskProperties.getExecutionid(),
|
this.taskProperties.getExecutionid()));
|
||||||
|
this.taskExecution = this.taskRepository.startTaskExecution(
|
||||||
|
this.taskProperties.getExecutionid(),
|
||||||
this.taskNameResolver.getTaskName(), new Date(), args,
|
this.taskNameResolver.getTaskName(), new Date(), args,
|
||||||
this.taskProperties.getExternalExecutionId(),
|
this.taskProperties.getExternalExecutionId(),
|
||||||
this.taskProperties.getParentExecutionId());
|
this.taskProperties.getParentExecutionId());
|
||||||
@@ -268,15 +286,18 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
taskExecution.setTaskName(this.taskNameResolver.getTaskName());
|
taskExecution.setTaskName(this.taskNameResolver.getTaskName());
|
||||||
taskExecution.setStartTime(new Date());
|
taskExecution.setStartTime(new Date());
|
||||||
taskExecution.setArguments(args);
|
taskExecution.setArguments(args);
|
||||||
taskExecution.setExternalExecutionId(this.taskProperties.getExternalExecutionId());
|
taskExecution.setExternalExecutionId(
|
||||||
taskExecution.setParentExecutionId(this.taskProperties.getParentExecutionId());
|
this.taskProperties.getExternalExecutionId());
|
||||||
this.taskExecution = this.taskRepository.createTaskExecution(
|
taskExecution.setParentExecutionId(
|
||||||
taskExecution);
|
this.taskProperties.getParentExecutionId());
|
||||||
|
this.taskExecution = this.taskRepository
|
||||||
|
.createTaskExecution(taskExecution);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
logger.error("Multiple start events have been received. The first one was " +
|
logger.error(
|
||||||
"recorded.");
|
"Multiple start events have been received. The first one was "
|
||||||
|
+ "recorded.");
|
||||||
}
|
}
|
||||||
|
|
||||||
setExitMessage(invokeOnTaskStartup(this.taskExecution));
|
setExitMessage(invokeOnTaskStartup(this.taskExecution));
|
||||||
@@ -289,9 +310,10 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskExecution invokeOnTaskStartup(TaskExecution taskExecution){
|
private TaskExecution invokeOnTaskStartup(TaskExecution taskExecution) {
|
||||||
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
|
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
|
||||||
List<TaskExecutionListener> startupListenerList = new ArrayList<>(this.taskExecutionListeners);
|
List<TaskExecutionListener> startupListenerList = new ArrayList<>(
|
||||||
|
this.taskExecutionListeners);
|
||||||
if (!CollectionUtils.isEmpty(startupListenerList)) {
|
if (!CollectionUtils.isEmpty(startupListenerList)) {
|
||||||
try {
|
try {
|
||||||
Collections.reverse(startupListenerList);
|
Collections.reverse(startupListenerList);
|
||||||
@@ -310,7 +332,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
return listenerTaskExecution;
|
return listenerTaskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskExecution invokeOnTaskEnd(TaskExecution taskExecution){
|
private TaskExecution invokeOnTaskEnd(TaskExecution taskExecution) {
|
||||||
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
|
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
|
||||||
if (this.taskExecutionListeners != null) {
|
if (this.taskExecutionListeners != null) {
|
||||||
try {
|
try {
|
||||||
@@ -321,7 +343,8 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
catch (Throwable listenerException) {
|
catch (Throwable listenerException) {
|
||||||
String errorMessage = stackTraceToString(listenerException);
|
String errorMessage = stackTraceToString(listenerException);
|
||||||
if (StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
|
if (StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
|
||||||
errorMessage = String.format("%s :Task also threw this Exception: %s", errorMessage, listenerTaskExecution.getErrorMessage());
|
errorMessage = String.format("%s :Task also threw this Exception: %s",
|
||||||
|
errorMessage, listenerTaskExecution.getErrorMessage());
|
||||||
}
|
}
|
||||||
logger.error(errorMessage);
|
logger.error(errorMessage);
|
||||||
listenerTaskExecution.setErrorMessage(errorMessage);
|
listenerTaskExecution.setErrorMessage(errorMessage);
|
||||||
@@ -331,7 +354,8 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
return listenerTaskExecution;
|
return listenerTaskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskExecution invokeOnTaskError(TaskExecution taskExecution, Throwable throwable){
|
private TaskExecution invokeOnTaskError(TaskExecution taskExecution,
|
||||||
|
Throwable throwable) {
|
||||||
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
|
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
|
||||||
if (this.taskExecutionListeners != null) {
|
if (this.taskExecutionListeners != null) {
|
||||||
try {
|
try {
|
||||||
@@ -342,9 +366,9 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
catch (Throwable listenerException) {
|
catch (Throwable listenerException) {
|
||||||
this.listenerFailed = true;
|
this.listenerFailed = true;
|
||||||
String errorMessage;
|
String errorMessage;
|
||||||
if(StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
|
if (StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
|
||||||
errorMessage = String.format("%s :While handling " +
|
errorMessage = String.format("%s :While handling " + "this error: %s",
|
||||||
"this error: %s", listenerException.getMessage(),
|
listenerException.getMessage(),
|
||||||
listenerTaskExecution.getErrorMessage());
|
listenerTaskExecution.getErrorMessage());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -359,14 +383,14 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
|||||||
return listenerTaskExecution;
|
return listenerTaskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskExecution getTaskExecutionCopy(TaskExecution taskExecution){
|
private TaskExecution getTaskExecutionCopy(TaskExecution taskExecution) {
|
||||||
Date startTime = new Date(taskExecution.getStartTime().getTime());
|
Date startTime = new Date(taskExecution.getStartTime().getTime());
|
||||||
Date endTime = (taskExecution.getEndTime() == null) ?
|
Date endTime = (taskExecution.getEndTime() == null) ? null
|
||||||
null : new Date(taskExecution.getEndTime().getTime());
|
: new Date(taskExecution.getEndTime().getTime());
|
||||||
|
|
||||||
return new TaskExecution(taskExecution.getExecutionId(),
|
return new TaskExecution(taskExecution.getExecutionId(),
|
||||||
taskExecution.getExitCode(), taskExecution.getTaskName(), startTime,
|
taskExecution.getExitCode(), taskExecution.getTaskName(), startTime,
|
||||||
endTime,taskExecution.getExitMessage(),
|
endTime, taskExecution.getExitMessage(),
|
||||||
Collections.unmodifiableList(taskExecution.getArguments()),
|
Collections.unmodifiableList(taskExecution.getArguments()),
|
||||||
taskExecution.getErrorMessage(), taskExecution.getExternalExecutionId());
|
taskExecution.getErrorMessage(), taskExecution.getExternalExecutionId());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.listener;
|
package org.springframework.cloud.task.listener;
|
||||||
@@ -47,12 +47,13 @@ import org.springframework.core.annotation.AnnotationUtils;
|
|||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @since 2.1.0
|
* @since 2.1.0
|
||||||
*/
|
*/
|
||||||
public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExecutionListener> {
|
public class TaskListenerExecutorObjectFactory
|
||||||
|
implements ObjectFactory<TaskExecutionListener> {
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(TaskListenerExecutor.class);
|
private static final Log logger = LogFactory.getLog(TaskListenerExecutor.class);
|
||||||
|
|
||||||
private final Set<Class<?>> nonAnnotatedClasses =
|
private final Set<Class<?>> nonAnnotatedClasses = Collections
|
||||||
Collections.newSetFromMap(new ConcurrentHashMap<>());
|
.newSetFromMap(new ConcurrentHashMap<>());
|
||||||
|
|
||||||
private ConfigurableApplicationContext context;
|
private ConfigurableApplicationContext context;
|
||||||
|
|
||||||
@@ -62,7 +63,7 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
|
|||||||
|
|
||||||
private Map<Method, Object> failedTaskInstances;
|
private Map<Method, Object> failedTaskInstances;
|
||||||
|
|
||||||
public TaskListenerExecutorObjectFactory(ConfigurableApplicationContext context){
|
public TaskListenerExecutorObjectFactory(ConfigurableApplicationContext context) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,12 +73,13 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
|
|||||||
this.afterTaskInstances = new HashMap<>();
|
this.afterTaskInstances = new HashMap<>();
|
||||||
this.failedTaskInstances = new HashMap<>();
|
this.failedTaskInstances = new HashMap<>();
|
||||||
initializeExecutor();
|
initializeExecutor();
|
||||||
return new TaskListenerExecutor(beforeTaskInstances, afterTaskInstances, failedTaskInstances);
|
return new TaskListenerExecutor(this.beforeTaskInstances, this.afterTaskInstances,
|
||||||
|
this.failedTaskInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeExecutor( ) {
|
private void initializeExecutor() {
|
||||||
ConfigurableListableBeanFactory factory = context.getBeanFactory();
|
ConfigurableListableBeanFactory factory = this.context.getBeanFactory();
|
||||||
for( String beanName : context.getBeanDefinitionNames()) {
|
for (String beanName : this.context.getBeanDefinitionNames()) {
|
||||||
|
|
||||||
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
|
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
|
||||||
Class<?> type = null;
|
Class<?> type = null;
|
||||||
@@ -85,9 +87,11 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
|
|||||||
type = AutoProxyUtils.determineTargetClass(factory, beanName);
|
type = AutoProxyUtils.determineTargetClass(factory, beanName);
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
// An unresolvable bean type, probably from a lazy bean - let's ignore it.
|
// An unresolvable bean type, probably from a lazy bean - let's ignore
|
||||||
|
// it.
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
|
logger.debug("Could not resolve target class for bean with name '"
|
||||||
|
+ beanName + "'", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
@@ -99,7 +103,10 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
|
|||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
// An invalid scoped proxy arrangement - let's ignore it.
|
// An invalid scoped proxy arrangement - let's ignore it.
|
||||||
if (logger.isDebugEnabled()) {
|
if (logger.isDebugEnabled()) {
|
||||||
logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
|
logger.debug(
|
||||||
|
"Could not resolve target bean for scoped proxy '"
|
||||||
|
+ beanName + "'",
|
||||||
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -107,8 +114,11 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
|
|||||||
processBean(beanName, type);
|
processBean(beanName, type);
|
||||||
}
|
}
|
||||||
catch (RuntimeException ex) {
|
catch (RuntimeException ex) {
|
||||||
throw new BeanInitializationException("Failed to process @BeforeTask " +
|
throw new BeanInitializationException(
|
||||||
"annotation on bean with name '" + beanName + "'", ex);
|
"Failed to process @BeforeTask "
|
||||||
|
+ "annotation on bean with name '" + beanName
|
||||||
|
+ "'",
|
||||||
|
ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -116,41 +126,49 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void processBean(String beanName, final Class<?> type){
|
private void processBean(String beanName, final Class<?> type) {
|
||||||
if (!this.nonAnnotatedClasses.contains(type)) {
|
if (!this.nonAnnotatedClasses.contains(type)) {
|
||||||
Map<Method, BeforeTask> beforeTaskMethods =
|
Map<Method, BeforeTask> beforeTaskMethods = (new MethodGetter<BeforeTask>())
|
||||||
(new MethodGetter<BeforeTask>()).getMethods(type, BeforeTask.class);
|
.getMethods(type, BeforeTask.class);
|
||||||
Map<Method, AfterTask> afterTaskMethods =
|
Map<Method, AfterTask> afterTaskMethods = (new MethodGetter<AfterTask>())
|
||||||
(new MethodGetter<AfterTask>()).getMethods(type, AfterTask.class);
|
.getMethods(type, AfterTask.class);
|
||||||
Map<Method, FailedTask> failedTaskMethods =
|
Map<Method, FailedTask> failedTaskMethods = (new MethodGetter<FailedTask>())
|
||||||
(new MethodGetter<FailedTask>()).getMethods(type, FailedTask.class);
|
.getMethods(type, FailedTask.class);
|
||||||
|
|
||||||
if (beforeTaskMethods.isEmpty() && afterTaskMethods.isEmpty()) {
|
if (beforeTaskMethods.isEmpty() && afterTaskMethods.isEmpty()) {
|
||||||
this.nonAnnotatedClasses.add(type);
|
this.nonAnnotatedClasses.add(type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if(!beforeTaskMethods.isEmpty()) {
|
if (!beforeTaskMethods.isEmpty()) {
|
||||||
for(Method beforeTaskMethod : beforeTaskMethods.keySet()) {
|
for (Method beforeTaskMethod : beforeTaskMethods.keySet()) {
|
||||||
this.beforeTaskInstances.put(beforeTaskMethod, context.getBean(beanName));
|
this.beforeTaskInstances.put(beforeTaskMethod,
|
||||||
|
this.context.getBean(beanName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!afterTaskMethods.isEmpty()){
|
if (!afterTaskMethods.isEmpty()) {
|
||||||
for(Method afterTaskMethod : afterTaskMethods.keySet()) {
|
for (Method afterTaskMethod : afterTaskMethods.keySet()) {
|
||||||
this.afterTaskInstances.put(afterTaskMethod, context.getBean(beanName));
|
this.afterTaskInstances.put(afterTaskMethod,
|
||||||
|
this.context.getBean(beanName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!failedTaskMethods.isEmpty()){
|
if (!failedTaskMethods.isEmpty()) {
|
||||||
for(Method failedTaskMethod : failedTaskMethods.keySet()) {
|
for (Method failedTaskMethod : failedTaskMethods.keySet()) {
|
||||||
this.failedTaskInstances.put(failedTaskMethod, context.getBean(beanName));
|
this.failedTaskInstances.put(failedTaskMethod,
|
||||||
|
this.context.getBean(beanName));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MethodGetter<T extends Annotation> {
|
private static class MethodGetter<T extends Annotation> {
|
||||||
public Map<Method, T> getMethods(final Class<?> type, final Class<T> annotationClass){
|
|
||||||
|
public Map<Method, T> getMethods(final Class<?> type,
|
||||||
|
final Class<T> annotationClass) {
|
||||||
return MethodIntrospector.selectMethods(type,
|
return MethodIntrospector.selectMethods(type,
|
||||||
(MethodIntrospector.MetadataLookup<T>) method -> AnnotationUtils.findAnnotation(method, annotationClass));
|
(MethodIntrospector.MetadataLookup<T>) method -> AnnotationUtils
|
||||||
|
.findAnnotation(method, annotationClass));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -27,22 +27,22 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* {@link TaskExecutionListener#onTaskEnd(TaskExecution)}
|
* {@link TaskExecutionListener#onTaskEnd(TaskExecution)}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
* public class MyListener {
|
* public class MyListener {
|
||||||
|
|
||||||
* @AfterTask
|
* @AfterTask
|
||||||
* public void doSomething(TaskExecution taskExecution) {
|
* public void doSomething(TaskExecution taskExecution) {
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface AfterTask {
|
public @interface AfterTask {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -27,22 +27,22 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* {@link TaskExecutionListener#onTaskStartup(TaskExecution)}
|
* {@link TaskExecutionListener#onTaskStartup(TaskExecution)}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
* public class MyListener {
|
* public class MyListener {
|
||||||
|
|
||||||
* @BeforeTask
|
* @BeforeTask
|
||||||
* public void doSomething(TaskExecution taskExecution) {
|
* public void doSomething(TaskExecution taskExecution) {
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface BeforeTask {
|
public @interface BeforeTask {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -27,22 +27,22 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* {@link TaskExecutionListener#onTaskFailed(TaskExecution, Throwable)}
|
* {@link TaskExecutionListener#onTaskFailed(TaskExecution, Throwable)}.
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* <pre class="code">
|
* <pre class="code">
|
||||||
* public class MyListener {
|
* public class MyListener {
|
||||||
|
|
||||||
* @FailedTask
|
* @FailedTask
|
||||||
* public void doSomething(TaskExecution taskExecution, Throwable throwable) {
|
* public void doSomething(TaskExecution taskExecution, Throwable throwable) {
|
||||||
* }
|
* }
|
||||||
* }
|
* }
|
||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
|
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Documented
|
@Documented
|
||||||
public @interface FailedTask {
|
public @interface FailedTask {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -32,7 +32,7 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
|||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class TaskListenerExecutor implements TaskExecutionListener{
|
public class TaskListenerExecutor implements TaskExecutionListener {
|
||||||
|
|
||||||
private Map<Method, Object> beforeTaskInstances;
|
private Map<Method, Object> beforeTaskInstances;
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ public class TaskListenerExecutor implements TaskExecutionListener{
|
|||||||
|
|
||||||
public TaskListenerExecutor(Map<Method, Object> beforeTaskInstances,
|
public TaskListenerExecutor(Map<Method, Object> beforeTaskInstances,
|
||||||
Map<Method, Object> afterTaskInstances,
|
Map<Method, Object> afterTaskInstances,
|
||||||
Map<Method, Object> failedTaskInstances){
|
Map<Method, Object> failedTaskInstances) {
|
||||||
|
|
||||||
this.beforeTaskInstances = beforeTaskInstances;
|
this.beforeTaskInstances = beforeTaskInstances;
|
||||||
this.afterTaskInstances = afterTaskInstances;
|
this.afterTaskInstances = afterTaskInstances;
|
||||||
@@ -50,66 +50,77 @@ public class TaskListenerExecutor implements TaskExecutionListener{
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes all the methods that have been annotated with @BeforeTask.
|
* Executes all the methods that have been annotated with @BeforeTask.
|
||||||
* @param taskExecution associated with the event.
|
* @param taskExecution associated with the event.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onTaskStartup(TaskExecution taskExecution) {
|
public void onTaskStartup(TaskExecution taskExecution) {
|
||||||
executeTaskListener(taskExecution, beforeTaskInstances.keySet(), beforeTaskInstances);
|
executeTaskListener(taskExecution, this.beforeTaskInstances.keySet(),
|
||||||
|
this.beforeTaskInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes all the methods that have been annotated with @AfterTask.
|
* Executes all the methods that have been annotated with @AfterTask.
|
||||||
* @param taskExecution associated with the event.
|
* @param taskExecution associated with the event.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onTaskEnd(TaskExecution taskExecution) {
|
public void onTaskEnd(TaskExecution taskExecution) {
|
||||||
executeTaskListener(taskExecution, afterTaskInstances.keySet(), afterTaskInstances);
|
executeTaskListener(taskExecution, this.afterTaskInstances.keySet(),
|
||||||
|
this.afterTaskInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes all the methods that have been annotated with @FailedTask.
|
* Executes all the methods that have been annotated with @FailedTask.
|
||||||
* @param throwable that was not caught for the task execution.
|
* @param throwable that was not caught for the task execution.
|
||||||
* @param taskExecution associated with the event.
|
* @param taskExecution associated with the event.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
||||||
executeTaskListenerWithThrowable(taskExecution, throwable,
|
executeTaskListenerWithThrowable(taskExecution, throwable,
|
||||||
failedTaskInstances.keySet(),failedTaskInstances);
|
this.failedTaskInstances.keySet(), this.failedTaskInstances);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeTaskListener(TaskExecution taskExecution, Set<Method> methods, Map<Method, Object> instances){
|
private void executeTaskListener(TaskExecution taskExecution, Set<Method> methods,
|
||||||
|
Map<Method, Object> instances) {
|
||||||
for (Method method : methods) {
|
for (Method method : methods) {
|
||||||
try {
|
try {
|
||||||
method.invoke(instances.get(method),taskExecution);
|
method.invoke(instances.get(method), taskExecution);
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException e) {
|
catch (IllegalAccessException e) {
|
||||||
throw new TaskExecutionException("@BeforeTask and @AfterTask annotated methods must be public.", e);
|
throw new TaskExecutionException(
|
||||||
|
"@BeforeTask and @AfterTask annotated methods must be public.",
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
throw new TaskExecutionException(String.format("Failed to process @BeforeTask or @AfterTask" +
|
throw new TaskExecutionException(String.format(
|
||||||
" annotation because: %s", e.getTargetException().getMessage()), e);
|
"Failed to process @BeforeTask or @AfterTask"
|
||||||
|
+ " annotation because: %s",
|
||||||
|
e.getTargetException().getMessage()), e);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e){
|
catch (IllegalArgumentException e) {
|
||||||
throw new TaskExecutionException("taskExecution parameter is required for @BeforeTask and @AfterTask annotated methods", e);
|
throw new TaskExecutionException("taskExecution parameter "
|
||||||
|
+ "is required for @BeforeTask and @AfterTask annotated methods",
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void executeTaskListenerWithThrowable(TaskExecution taskExecution,
|
private void executeTaskListenerWithThrowable(TaskExecution taskExecution,
|
||||||
Throwable throwable, Set<Method> methods, Map<Method, Object> instances){
|
Throwable throwable, Set<Method> methods, Map<Method, Object> instances) {
|
||||||
for (Method method : methods) {
|
for (Method method : methods) {
|
||||||
try {
|
try {
|
||||||
method.invoke(instances.get(method),taskExecution, throwable);
|
method.invoke(instances.get(method), taskExecution, throwable);
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException e) {
|
catch (IllegalAccessException e) {
|
||||||
throw new TaskExecutionException("@FailedTask annotated methods must be public.", e);
|
throw new TaskExecutionException(
|
||||||
|
"@FailedTask annotated methods must be public.", e);
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e) {
|
catch (InvocationTargetException e) {
|
||||||
throw new TaskExecutionException(String.format("Failed to process @FailedTask " +
|
throw new TaskExecutionException(String.format(
|
||||||
"annotation because: %s", e.getTargetException().getMessage()), e);
|
"Failed to process @FailedTask " + "annotation because: %s",
|
||||||
|
e.getTargetException().getMessage()), e);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e){
|
catch (IllegalArgumentException e) {
|
||||||
throw new TaskExecutionException("taskExecution and throwable parameters "
|
throw new TaskExecutionException("taskExecution and throwable parameters "
|
||||||
+ "are required for @FailedTask annotated methods", e);
|
+ "are required for @FailedTask annotated methods", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base package for spring cloud task.
|
* Base package for spring cloud task.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2017 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -33,7 +33,7 @@ import org.springframework.util.Assert;
|
|||||||
public class TaskExecution {
|
public class TaskExecution {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique id associated with the task execution.
|
* The unique id associated with the task execution.
|
||||||
*/
|
*/
|
||||||
private long executionId;
|
private long executionId;
|
||||||
|
|
||||||
@@ -75,7 +75,7 @@ public class TaskExecution {
|
|||||||
private String externalExecutionId;
|
private String externalExecutionId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error information available upon the failure of a task
|
* Error information available upon the failure of a task.
|
||||||
*
|
*
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
@@ -87,14 +87,12 @@ public class TaskExecution {
|
|||||||
private List<String> arguments;
|
private List<String> arguments;
|
||||||
|
|
||||||
public TaskExecution() {
|
public TaskExecution() {
|
||||||
arguments = new ArrayList<>();
|
this.arguments = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskExecution(long executionId, Integer exitCode, String taskName,
|
public TaskExecution(long executionId, Integer exitCode, String taskName,
|
||||||
Date startTime, Date endTime,
|
Date startTime, Date endTime, String exitMessage, List<String> arguments,
|
||||||
String exitMessage, List<String> arguments,
|
String errorMessage, String externalExecutionId, Long parentExecutionId) {
|
||||||
String errorMessage, String externalExecutionId,
|
|
||||||
Long parentExecutionId) {
|
|
||||||
|
|
||||||
Assert.notNull(arguments, "arguments must not be null");
|
Assert.notNull(arguments, "arguments must not be null");
|
||||||
this.executionId = executionId;
|
this.executionId = executionId;
|
||||||
@@ -102,24 +100,23 @@ public class TaskExecution {
|
|||||||
this.taskName = taskName;
|
this.taskName = taskName;
|
||||||
this.exitMessage = exitMessage;
|
this.exitMessage = exitMessage;
|
||||||
this.arguments = new ArrayList<>(arguments);
|
this.arguments = new ArrayList<>(arguments);
|
||||||
this.startTime = (startTime != null) ? (Date)startTime.clone() : null;
|
this.startTime = (startTime != null) ? (Date) startTime.clone() : null;
|
||||||
this.endTime = (endTime != null) ? (Date)endTime.clone() : null;
|
this.endTime = (endTime != null) ? (Date) endTime.clone() : null;
|
||||||
this.errorMessage = errorMessage;
|
this.errorMessage = errorMessage;
|
||||||
this.externalExecutionId = externalExecutionId;
|
this.externalExecutionId = externalExecutionId;
|
||||||
this.parentExecutionId = parentExecutionId;
|
this.parentExecutionId = parentExecutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TaskExecution(long executionId, Integer exitCode, String taskName,
|
public TaskExecution(long executionId, Integer exitCode, String taskName,
|
||||||
Date startTime, Date endTime,
|
Date startTime, Date endTime, String exitMessage, List<String> arguments,
|
||||||
String exitMessage, List<String> arguments,
|
|
||||||
String errorMessage, String externalExecutionId) {
|
String errorMessage, String externalExecutionId) {
|
||||||
|
|
||||||
this(executionId, exitCode, taskName, startTime, endTime, exitMessage,
|
this(executionId, exitCode, taskName, startTime, endTime, exitMessage, arguments,
|
||||||
arguments, errorMessage,externalExecutionId, null);
|
errorMessage, externalExecutionId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getExecutionId() {
|
public long getExecutionId() {
|
||||||
return executionId;
|
return this.executionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Integer getExitCode() {
|
public Integer getExitCode() {
|
||||||
@@ -131,7 +128,7 @@ public class TaskExecution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getTaskName() {
|
public String getTaskName() {
|
||||||
return taskName;
|
return this.taskName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTaskName(String taskName) {
|
public void setTaskName(String taskName) {
|
||||||
@@ -139,23 +136,23 @@ public class TaskExecution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Date getStartTime() {
|
public Date getStartTime() {
|
||||||
return (startTime != null) ? (Date)startTime.clone() : null;
|
return (this.startTime != null) ? (Date) this.startTime.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setStartTime(Date startTime) {
|
public void setStartTime(Date startTime) {
|
||||||
this.startTime = (startTime != null) ? (Date)startTime.clone() : null;
|
this.startTime = (startTime != null) ? (Date) startTime.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getEndTime() {
|
public Date getEndTime() {
|
||||||
return (endTime != null) ? (Date)endTime.clone() : null;
|
return (this.endTime != null) ? (Date) this.endTime.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEndTime(Date endTime) {
|
public void setEndTime(Date endTime) {
|
||||||
this.endTime = (endTime != null) ? (Date)endTime.clone() : null;
|
this.endTime = (endTime != null) ? (Date) endTime.clone() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExitMessage() {
|
public String getExitMessage() {
|
||||||
return exitMessage;
|
return this.exitMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExitMessage(String exitMessage) {
|
public void setExitMessage(String exitMessage) {
|
||||||
@@ -163,15 +160,15 @@ public class TaskExecution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getArguments() {
|
public List<String> getArguments() {
|
||||||
return arguments;
|
return this.arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setArguments(List<String> arguments) {
|
public void setArguments(List<String> arguments) {
|
||||||
this.arguments = new ArrayList<> (arguments);
|
this.arguments = new ArrayList<>(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getErrorMessage() {
|
public String getErrorMessage() {
|
||||||
return errorMessage;
|
return this.errorMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setErrorMessage(String errorMessage) {
|
public void setErrorMessage(String errorMessage) {
|
||||||
@@ -179,7 +176,7 @@ public class TaskExecution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getExternalExecutionId() {
|
public String getExternalExecutionId() {
|
||||||
return externalExecutionId;
|
return this.externalExecutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExternalExecutionId(String externalExecutionId) {
|
public void setExternalExecutionId(String externalExecutionId) {
|
||||||
@@ -187,7 +184,7 @@ public class TaskExecution {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Long getParentExecutionId() {
|
public Long getParentExecutionId() {
|
||||||
return parentExecutionId;
|
return this.parentExecutionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setParentExecutionId(Long parentExecutionId) {
|
public void setParentExecutionId(Long parentExecutionId) {
|
||||||
@@ -196,17 +193,13 @@ public class TaskExecution {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "TaskExecution{" +
|
return "TaskExecution{" + "executionId=" + this.executionId
|
||||||
"executionId=" + executionId +
|
+ ", parentExecutionId=" + this.parentExecutionId + ", exitCode="
|
||||||
", parentExecutionId=" + parentExecutionId +
|
+ this.exitCode + ", taskName='" + this.taskName + '\'' + ", startTime="
|
||||||
", exitCode=" + exitCode +
|
+ this.startTime + ", endTime=" + this.endTime + ", exitMessage='"
|
||||||
", taskName='" + taskName + '\'' +
|
+ this.exitMessage + '\'' + ", externalExecutionId='"
|
||||||
", startTime=" + startTime +
|
+ this.externalExecutionId + '\'' + ", errorMessage='" + this.errorMessage
|
||||||
", endTime=" + endTime +
|
+ '\'' + ", arguments=" + this.arguments + '}';
|
||||||
", exitMessage='" + exitMessage + '\'' +
|
|
||||||
", externalExecutionId='" + externalExecutionId + '\'' +
|
|
||||||
", errorMessage='" + errorMessage + '\'' +
|
|
||||||
", arguments=" + arguments +
|
|
||||||
'}';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -33,16 +33,13 @@ public interface TaskExplorer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a {@link TaskExecution} by its id.
|
* Retrieve a {@link TaskExecution} by its id.
|
||||||
*
|
|
||||||
* @param executionId the task execution id
|
* @param executionId the task execution id
|
||||||
* @return the {@link TaskExecution} with this id, or null if not found
|
* @return the {@link TaskExecution} with this id, or null if not found
|
||||||
*/
|
*/
|
||||||
TaskExecution getTaskExecution(long executionId);
|
TaskExecution getTaskExecution(long executionId);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a collection of taskExecutions that have the task name provided.
|
* Retrieve a collection of taskExecutions that have the task name provided.
|
||||||
*
|
|
||||||
* @param taskName the name of the task
|
* @param taskName the name of the task
|
||||||
* @param pageable the constraints for the search
|
* @param pageable the constraints for the search
|
||||||
* @return the set of running executions for tasks with the specified name
|
* @return the set of running executions for tasks with the specified name
|
||||||
@@ -51,14 +48,12 @@ public interface TaskExplorer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve a list of available task names.
|
* Retrieve a list of available task names.
|
||||||
*
|
|
||||||
* @return the set of task names that have been executed
|
* @return the set of task names that have been executed
|
||||||
*/
|
*/
|
||||||
List<String> getTaskNames();
|
List<String> getTaskNames();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get number of executions for a taskName.
|
* Get number of executions for a taskName.
|
||||||
*
|
|
||||||
* @param taskName the name of the task to be searched
|
* @param taskName the name of the task to be searched
|
||||||
* @return the number of running tasks that have the taskname specified
|
* @return the number of running tasks that have the taskname specified
|
||||||
*/
|
*/
|
||||||
@@ -66,21 +61,18 @@ public interface TaskExplorer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves current number of task executions.
|
* Retrieves current number of task executions.
|
||||||
*
|
|
||||||
* @return current number of task executions.
|
* @return current number of task executions.
|
||||||
*/
|
*/
|
||||||
long getTaskExecutionCount();
|
long getTaskExecutionCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves current number of running task executions.
|
* Retrieves current number of running task executions.
|
||||||
*
|
|
||||||
* @return current number of running task executions.
|
* @return current number of running task executions.
|
||||||
*/
|
*/
|
||||||
long getRunningTaskExecutionCount();
|
long getRunningTaskExecutionCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a collection/page of executions
|
* Get a collection/page of executions.
|
||||||
*
|
|
||||||
* @param taskName the name of the task to be searched
|
* @param taskName the name of the task to be searched
|
||||||
* @param pageable the constraints for the search
|
* @param pageable the constraints for the search
|
||||||
* @return list of task executions
|
* @return list of task executions
|
||||||
@@ -88,9 +80,8 @@ public interface TaskExplorer {
|
|||||||
Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable);
|
Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves all the task executions within the pageable constraints sorted by
|
* Retrieves all the task executions within the pageable constraints sorted by start
|
||||||
* start date descending, taskExecution id descending.
|
* date descending, taskExecution id descending.
|
||||||
*
|
|
||||||
* @param pageable the constraints for the search
|
* @param pageable the constraints for the search
|
||||||
* @return page containing the results from the search
|
* @return page containing the results from the search
|
||||||
*/
|
*/
|
||||||
@@ -98,8 +89,7 @@ public interface TaskExplorer {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the id of the TaskExecution that the requested Spring Batch job execution
|
* Returns the id of the TaskExecution that the requested Spring Batch job execution
|
||||||
* was executed within the context of. Returns null if none were found.
|
* was executed within the context of. Returns null if none were found.
|
||||||
*
|
|
||||||
* @param jobExecutionId the id of the JobExecution
|
* @param jobExecutionId the id of the JobExecution
|
||||||
* @return the id of the {@link TaskExecution}
|
* @return the id of the {@link TaskExecution}
|
||||||
*/
|
*/
|
||||||
@@ -108,39 +98,39 @@ public interface TaskExplorer {
|
|||||||
/**
|
/**
|
||||||
* Returns a Set of JobExecution ids for the jobs that were executed within the scope
|
* Returns a Set of JobExecution ids for the jobs that were executed within the scope
|
||||||
* of the requested task.
|
* of the requested task.
|
||||||
*
|
|
||||||
* @param taskExecutionId id of the {@link TaskExecution}
|
* @param taskExecutionId id of the {@link TaskExecution}
|
||||||
* @return a <code>Set</code> of the ids of the job executions executed within the task.
|
* @return a <code>Set</code> of the ids of the job executions executed within the
|
||||||
|
* task.
|
||||||
*/
|
*/
|
||||||
Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId);
|
Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link List} of the latest {@link TaskExecution} for 1 or more task names.
|
* Returns a {@link List} of the latest {@link TaskExecution} for 1 or more task
|
||||||
|
* names.
|
||||||
*
|
*
|
||||||
* Latest is defined by the most recent start time. A {@link TaskExecution} does not have to be finished
|
* Latest is defined by the most recent start time. A {@link TaskExecution} does not
|
||||||
* (The results may including pending {@link TaskExecution}s).
|
* have to be finished (The results may including pending {@link TaskExecution}s).
|
||||||
*
|
*
|
||||||
* It is theoretically possible that a {@link TaskExecution} with the same name to have more than 1
|
* It is theoretically possible that a {@link TaskExecution} with the same name to
|
||||||
* {@link TaskExecution} for the exact same start time. In that case the {@link TaskExecution} with the
|
* have more than 1 {@link TaskExecution} for the exact same start time. In that case
|
||||||
* highest Task Execution ID is returned.
|
* the {@link TaskExecution} with the highest Task Execution ID is returned.
|
||||||
*
|
|
||||||
* This method will not consider end times in its calculations. Thus, when a task execution {@code A} starts
|
|
||||||
* after task execution {@code B} but finishes BEFORE task execution {@code A}, then task execution {@code B}
|
|
||||||
* is being returned.
|
|
||||||
*
|
*
|
||||||
|
* This method will not consider end times in its calculations. Thus, when a task
|
||||||
|
* execution {@code A} starts after task execution {@code B} but finishes BEFORE task
|
||||||
|
* execution {@code A}, then task execution {@code B} is being returned.
|
||||||
* @param taskNames At least 1 task name must be provided
|
* @param taskNames At least 1 task name must be provided
|
||||||
* @return List of TaskExecutions. May be empty but never null.
|
* @return List of TaskExecutions. May be empty but never null.
|
||||||
*/
|
*/
|
||||||
List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames);
|
List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the latest task execution for a given task name. Will ultimately apply the same algorithm underneath
|
* Returns the latest task execution for a given task name. Will ultimately apply the
|
||||||
* as {@link #getLatestTaskExecutionsByTaskNames(String...)} but will only return a single result.
|
* same algorithm underneath as {@link #getLatestTaskExecutionsByTaskNames(String...)}
|
||||||
*
|
* but will only return a single result.
|
||||||
* @param taskName Must not be null or empty
|
* @param taskName Must not be null or empty
|
||||||
* @return The latest Task Execution or null
|
* @return The latest Task Execution or null
|
||||||
* @see #getLatestTaskExecutionsByTaskNames(String...)
|
* @see #getLatestTaskExecutionsByTaskNames(String...)
|
||||||
*/
|
*/
|
||||||
TaskExecution getLatestTaskExecutionForTaskName(String taskName);
|
TaskExecution getLatestTaskExecutionForTaskName(String taskName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.repository;
|
package org.springframework.cloud.task.repository;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -26,4 +27,5 @@ public interface TaskNameResolver {
|
|||||||
* @return the name of the task being executed within this context.
|
* @return the name of the task being executed within this context.
|
||||||
*/
|
*/
|
||||||
String getTaskName();
|
String getTaskName();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -31,7 +31,6 @@ public interface TaskRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the repository that a taskExecution has completed.
|
* Notifies the repository that a taskExecution has completed.
|
||||||
*
|
|
||||||
* @param executionId to the task execution to be updated.
|
* @param executionId to the task execution to be updated.
|
||||||
* @param exitCode to be stored for this task.
|
* @param exitCode to be stored for this task.
|
||||||
* @param endTime designated when the task completed.
|
* @param endTime designated when the task completed.
|
||||||
@@ -40,11 +39,10 @@ public interface TaskRepository {
|
|||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||||
String exitMessage);
|
String exitMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the repository that a taskExecution has completed.
|
* Notifies the repository that a taskExecution has completed.
|
||||||
*
|
|
||||||
* @param executionId to the task execution to be updated.
|
* @param executionId to the task execution to be updated.
|
||||||
* @param exitCode to be stored for this task execution.
|
* @param exitCode to be stored for this task execution.
|
||||||
* @param endTime designated when the task completed.
|
* @param endTime designated when the task completed.
|
||||||
@@ -55,30 +53,26 @@ public interface TaskRepository {
|
|||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||||
String exitMessage, String errorMessage);
|
String exitMessage, String errorMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the repository that a taskExecution needs to be created.
|
* Notifies the repository that a taskExecution needs to be created.
|
||||||
*
|
* @param taskExecution a TaskExecution instance containing the startTime, arguments
|
||||||
* @param taskExecution a TaskExecution instance containing the startTime,
|
* and externalExecutionId that will be stored in the repository. Only the values
|
||||||
* arguments and externalExecutionId that will be stored in the repository.
|
* enumerated above will be stored for this TaskExecution.
|
||||||
* Only the values enumerated above will be stored for this
|
* @return the {@link TaskExecution} that was stored in the repository. The
|
||||||
|
* TaskExecution's taskExecutionId will also contain the id that was used to store the
|
||||||
* TaskExecution.
|
* TaskExecution.
|
||||||
* @return the {@link TaskExecution} that was stored in the repository. The
|
|
||||||
* TaskExecution's taskExecutionId will also contain the id that was used
|
|
||||||
* to store the TaskExecution.
|
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
TaskExecution createTaskExecution(TaskExecution taskExecution);
|
TaskExecution createTaskExecution(TaskExecution taskExecution);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an empty TaskExecution with just an id and name provided. This is intended to be
|
* Creates an empty TaskExecution with just an id and name provided. This is intended
|
||||||
* utilized in systems where the request of launching a task is separate from the
|
* to be utilized in systems where the request of launching a task is separate from
|
||||||
* actual start of a task (the underlying system may need to deploy the task prior to
|
* the actual start of a task (the underlying system may need to deploy the task prior
|
||||||
* launching, etc).
|
* to launching, etc).
|
||||||
*
|
|
||||||
* @param name task name to be associated with the task execution.
|
* @param name task name to be associated with the task execution.
|
||||||
*
|
|
||||||
* @return the initial {@link TaskExecution}
|
* @return the initial {@link TaskExecution}
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -89,7 +83,6 @@ public interface TaskRepository {
|
|||||||
* utilized in systems where the request of launching a task is separate from the
|
* utilized in systems where the request of launching a task is separate from the
|
||||||
* actual start of a task (the underlying system may need to deploy the task prior to
|
* actual start of a task (the underlying system may need to deploy the task prior to
|
||||||
* launching, etc).
|
* launching, etc).
|
||||||
*
|
|
||||||
* @return the initial {@link TaskExecution}
|
* @return the initial {@link TaskExecution}
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
@@ -97,43 +90,38 @@ public interface TaskRepository {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the repository that a taskExecution has has started.
|
* Notifies the repository that a taskExecution has has started.
|
||||||
*
|
* @param executionid to the task execution to be updated.
|
||||||
* @param executionid to the task execution to be updated.
|
* @param taskName the name that associated with the task execution.
|
||||||
* @param taskName the name that associated with the task execution.
|
* @param startTime the time task began.
|
||||||
* @param startTime the time task began.
|
* @param arguments list of key/value pairs that configure the task.
|
||||||
* @param arguments list of key/value pairs that configure the task.
|
|
||||||
* @param externalExecutionId id assigned to the task by the platform.
|
* @param externalExecutionId id assigned to the task by the platform.
|
||||||
* @return TaskExecution created based on the parameters.
|
* @return TaskExecution created based on the parameters.
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
TaskExecution startTaskExecution(long executionid, String taskName,
|
TaskExecution startTaskExecution(long executionid, String taskName, Date startTime,
|
||||||
Date startTime,List<String> arguments, String externalExecutionId);
|
List<String> arguments, String externalExecutionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the repository to update the taskExecution's externalExecutionId.
|
* Notifies the repository to update the taskExecution's externalExecutionId.
|
||||||
*
|
* @param executionid to the task execution to be updated.
|
||||||
* @param executionid to the task execution to be updated.
|
|
||||||
* @param externalExecutionId id assigned to the task by the platform.
|
* @param externalExecutionId id assigned to the task by the platform.
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
void updateExternalExecutionId(long executionid,
|
void updateExternalExecutionId(long executionid, String externalExecutionId);
|
||||||
String externalExecutionId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notifies the repository that a taskExecution has has started.
|
* Notifies the repository that a taskExecution has has started.
|
||||||
* @param executionid to the task execution to be updated.
|
* @param executionid to the task execution to be updated.
|
||||||
* @param taskName the name that associated with the task execution.
|
* @param taskName the name that associated with the task execution.
|
||||||
* @param startTime the time task began.
|
* @param startTime the time task began.
|
||||||
* @param arguments list of key/value pairs that configure the task.
|
* @param arguments list of key/value pairs that configure the task.
|
||||||
* @param externalExecutionId id assigned to the task by the platform.
|
* @param externalExecutionId id assigned to the task by the platform.
|
||||||
* @param parentExecutionId the parent task execution id.
|
* @param parentExecutionId the parent task execution id.
|
||||||
|
* @return A TaskExecution that contains the information available at the beginning of
|
||||||
* @return A TaskExecution that contains the information available at the
|
* a TaskExecution.
|
||||||
* beginning of a TaskExecution.
|
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
TaskExecution startTaskExecution(long executionid, String taskName,
|
TaskExecution startTaskExecution(long executionid, String taskName, Date startTime,
|
||||||
Date startTime,List<String> arguments, String externalExecutionId,
|
List<String> arguments, String externalExecutionId, Long parentExecutionId);
|
||||||
Long parentExecutionId);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -61,22 +61,33 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SELECT clause for task execution.
|
||||||
|
*/
|
||||||
public static final String SELECT_CLAUSE = "TASK_EXECUTION_ID, "
|
public static final String SELECT_CLAUSE = "TASK_EXECUTION_ID, "
|
||||||
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
||||||
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, "
|
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, "
|
||||||
+ "EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID ";
|
+ "EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FROM clause for task execution.
|
||||||
|
*/
|
||||||
public static final String FROM_CLAUSE = "%PREFIX%EXECUTION";
|
public static final String FROM_CLAUSE = "%PREFIX%EXECUTION";
|
||||||
|
|
||||||
public static final String RUNNING_TASK_WHERE_CLAUSE =
|
/**
|
||||||
"where TASK_NAME = :taskName AND END_TIME IS NULL ";
|
* WHERE clause for running task.
|
||||||
|
*/
|
||||||
|
public static final String RUNNING_TASK_WHERE_CLAUSE = "where TASK_NAME = :taskName AND END_TIME IS NULL ";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WHERE clause for task name.
|
||||||
|
*/
|
||||||
public static final String TASK_NAME_WHERE_CLAUSE = "where TASK_NAME = :taskName ";
|
public static final String TASK_NAME_WHERE_CLAUSE = "where TASK_NAME = :taskName ";
|
||||||
|
|
||||||
private static final String SAVE_TASK_EXECUTION = "INSERT into %PREFIX%EXECUTION"
|
private static final String SAVE_TASK_EXECUTION = "INSERT into %PREFIX%EXECUTION"
|
||||||
+ "(TASK_EXECUTION_ID, EXIT_CODE, START_TIME, TASK_NAME, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID)"
|
+ "(TASK_EXECUTION_ID, EXIT_CODE, START_TIME, TASK_NAME, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID)"
|
||||||
+ "values (:taskExecutionId, :exitCode, :startTime, :taskName, :lastUpdated, :externalExecutionId, :parentExecutionId)";
|
+ "values (:taskExecutionId, :exitCode, :startTime, "
|
||||||
|
+ ":taskName, :lastUpdated, :externalExecutionId, :parentExecutionId)";
|
||||||
|
|
||||||
private static final String CREATE_TASK_ARGUMENT = "INSERT into "
|
private static final String CREATE_TASK_ARGUMENT = "INSERT into "
|
||||||
+ "%PREFIX%EXECUTION_PARAMS(TASK_EXECUTION_ID, TASK_PARAM ) values (:taskExecutionId, :taskParam)";
|
+ "%PREFIX%EXECUTION_PARAMS(TASK_EXECUTION_ID, TASK_PARAM ) values (:taskExecutionId, :taskParam)";
|
||||||
@@ -85,9 +96,11 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
+ "START_TIME = :startTime, TASK_NAME = :taskName, LAST_UPDATED = :lastUpdated";
|
+ "START_TIME = :startTime, TASK_NAME = :taskName, LAST_UPDATED = :lastUpdated";
|
||||||
|
|
||||||
private static final String START_TASK_EXECUTION_EXTERNAL_ID_SUFFIX = ", "
|
private static final String START_TASK_EXECUTION_EXTERNAL_ID_SUFFIX = ", "
|
||||||
+ "EXTERNAL_EXECUTION_ID = :externalExecutionId, PARENT_EXECUTION_ID = :parentExecutionId where TASK_EXECUTION_ID = :taskExecutionId";
|
+ "EXTERNAL_EXECUTION_ID = :externalExecutionId, PARENT_EXECUTION_ID = :parentExecutionId "
|
||||||
|
+ "where TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
|
|
||||||
private static final String START_TASK_EXECUTION_SUFFIX = ", PARENT_EXECUTION_ID = :parentExecutionId where TASK_EXECUTION_ID = :taskExecutionId";
|
private static final String START_TASK_EXECUTION_SUFFIX = ", PARENT_EXECUTION_ID = :parentExecutionId "
|
||||||
|
+ "where TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
|
|
||||||
private static final String CHECK_TASK_EXECUTION_EXISTS = "SELECT COUNT(*) FROM "
|
private static final String CHECK_TASK_EXECUTION_EXISTS = "SELECT COUNT(*) FROM "
|
||||||
+ "%PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = :taskExecutionId";
|
+ "%PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
@@ -99,8 +112,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
private static final String UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID = "UPDATE %PREFIX%EXECUTION set "
|
private static final String UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID = "UPDATE %PREFIX%EXECUTION set "
|
||||||
+ "EXTERNAL_EXECUTION_ID = :externalExecutionId where TASK_EXECUTION_ID = :taskExecutionId";
|
+ "EXTERNAL_EXECUTION_ID = :externalExecutionId where TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
|
|
||||||
private static final String GET_EXECUTION_BY_ID = "SELECT TASK_EXECUTION_ID, " +
|
private static final String GET_EXECUTION_BY_ID = "SELECT TASK_EXECUTION_ID, "
|
||||||
"START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
|
||||||
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, "
|
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, "
|
||||||
+ "PARENT_EXECUTION_ID "
|
+ "PARENT_EXECUTION_ID "
|
||||||
+ "from %PREFIX%EXECUTION where TASK_EXECUTION_ID = :taskExecutionId";
|
+ "from %PREFIX%EXECUTION where TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
@@ -108,41 +121,40 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
private static final String FIND_ARGUMENT_FROM_ID = "SELECT TASK_EXECUTION_ID, "
|
private static final String FIND_ARGUMENT_FROM_ID = "SELECT TASK_EXECUTION_ID, "
|
||||||
+ "TASK_PARAM from %PREFIX%EXECUTION_PARAMS where TASK_EXECUTION_ID = :taskExecutionId";
|
+ "TASK_PARAM from %PREFIX%EXECUTION_PARAMS where TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
|
|
||||||
private static final String TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM " +
|
private static final String TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM "
|
||||||
"%PREFIX%EXECUTION ";
|
+ "%PREFIX%EXECUTION ";
|
||||||
|
|
||||||
private static final String TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM " +
|
private static final String TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM "
|
||||||
"%PREFIX%EXECUTION where TASK_NAME = :taskName";
|
+ "%PREFIX%EXECUTION where TASK_NAME = :taskName";
|
||||||
|
|
||||||
private static final String RUNNING_TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM " +
|
private static final String RUNNING_TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM "
|
||||||
"%PREFIX%EXECUTION where TASK_NAME = :taskName AND END_TIME IS NULL ";
|
+ "%PREFIX%EXECUTION where TASK_NAME = :taskName AND END_TIME IS NULL ";
|
||||||
|
|
||||||
private static final String RUNNING_TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM " +
|
private static final String RUNNING_TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM "
|
||||||
"%PREFIX%EXECUTION where END_TIME IS NULL ";
|
+ "%PREFIX%EXECUTION where END_TIME IS NULL ";
|
||||||
|
|
||||||
private static final String LAST_TASK_EXECUTIONS_BY_TASK_NAMES =
|
private static final String LAST_TASK_EXECUTIONS_BY_TASK_NAMES = "select TE2.* from ("
|
||||||
"select TE2.* from (" +
|
+ "select MAX(TE.TASK_EXECUTION_ID) as TASK_EXECUTION_ID, TE.TASK_NAME, TE.START_TIME from ("
|
||||||
"select MAX(TE.TASK_EXECUTION_ID) as TASK_EXECUTION_ID, TE.TASK_NAME, TE.START_TIME from (" +
|
+ "select TASK_NAME, MAX(START_TIME) as START_TIME"
|
||||||
"select TASK_NAME, MAX(START_TIME) as START_TIME" +
|
+ " FROM %PREFIX%EXECUTION where TASK_NAME in (:taskNames)"
|
||||||
" FROM %PREFIX%EXECUTION where TASK_NAME in (:taskNames)" +
|
+ " GROUP BY TASK_NAME" + ") TE_MAX "
|
||||||
" GROUP BY TASK_NAME" +
|
+ "inner join %PREFIX%EXECUTION TE ON TE.TASK_NAME = TE_MAX.TASK_NAME AND TE.START_TIME = TE_MAX.START_TIME "
|
||||||
") TE_MAX " +
|
+ "group by TE.TASK_NAME, TE.START_TIME" + ") TE1 "
|
||||||
"inner join %PREFIX%EXECUTION TE ON TE.TASK_NAME = TE_MAX.TASK_NAME AND TE.START_TIME = TE_MAX.START_TIME " +
|
+ "inner join %PREFIX%EXECUTION TE2 ON TE1.TASK_EXECUTION_ID = TE2.TASK_EXECUTION_ID "
|
||||||
"group by TE.TASK_NAME, TE.START_TIME" +
|
+ "order by TE2.START_TIME DESC, TE2.TASK_EXECUTION_ID DESC";
|
||||||
") TE1 " +
|
|
||||||
"inner join %PREFIX%EXECUTION TE2 ON TE1.TASK_EXECUTION_ID = TE2.TASK_EXECUTION_ID " +
|
|
||||||
"order by TE2.START_TIME DESC, TE2.TASK_EXECUTION_ID DESC";
|
|
||||||
|
|
||||||
private static final String FIND_TASK_NAMES = "SELECT distinct TASK_NAME from %PREFIX%EXECUTION order by TASK_NAME";
|
private static final String FIND_TASK_NAMES = "SELECT distinct TASK_NAME from %PREFIX%EXECUTION order by TASK_NAME";
|
||||||
|
|
||||||
private static final String FIND_TASK_EXECUTION_BY_JOB_EXECUTION_ID = "SELECT TASK_EXECUTION_ID FROM %PREFIX%TASK_BATCH WHERE JOB_EXECUTION_ID = :jobExecutionId";
|
private static final String FIND_TASK_EXECUTION_BY_JOB_EXECUTION_ID = "SELECT TASK_EXECUTION_ID FROM "
|
||||||
|
+ "%PREFIX%TASK_BATCH WHERE JOB_EXECUTION_ID = :jobExecutionId";
|
||||||
|
|
||||||
private static final String FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID = "SELECT JOB_EXECUTION_ID FROM %PREFIX%TASK_BATCH WHERE TASK_EXECUTION_ID = :taskExecutionId";
|
private static final String FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID = "SELECT JOB_EXECUTION_ID "
|
||||||
|
+ "FROM %PREFIX%TASK_BATCH WHERE TASK_EXECUTION_ID = :taskExecutionId";
|
||||||
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
|
||||||
|
|
||||||
private final NamedParameterJdbcTemplate jdbcTemplate;
|
private final NamedParameterJdbcTemplate jdbcTemplate;
|
||||||
|
|
||||||
|
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
||||||
|
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
private LinkedHashMap<String, Order> orderMap;
|
private LinkedHashMap<String, Order> orderMap;
|
||||||
@@ -169,120 +181,119 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
Assert.notNull(dataSource, "The dataSource must not be null.");
|
Assert.notNull(dataSource, "The dataSource must not be null.");
|
||||||
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
|
||||||
this.dataSource = dataSource;
|
this.dataSource = dataSource;
|
||||||
orderMap = new LinkedHashMap<>();
|
this.orderMap = new LinkedHashMap<>();
|
||||||
orderMap.put("START_TIME", Order.DESCENDING);
|
this.orderMap.put("START_TIME", Order.DESCENDING);
|
||||||
orderMap.put("TASK_EXECUTION_ID", Order.DESCENDING);
|
this.orderMap.put("TASK_EXECUTION_ID", Order.DESCENDING);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TaskExecution createTaskExecution(String taskName,
|
|
||||||
Date startTime, List<String> arguments, String externalExecutionId) {
|
|
||||||
return createTaskExecution(taskName, startTime, arguments,
|
|
||||||
externalExecutionId, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution createTaskExecution(String taskName, Date startTime,
|
public TaskExecution createTaskExecution(String taskName, Date startTime,
|
||||||
List<String> arguments, String externalExecutionId,
|
List<String> arguments, String externalExecutionId) {
|
||||||
Long parentExecutionId) {
|
return createTaskExecution(taskName, startTime, arguments, externalExecutionId,
|
||||||
|
null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TaskExecution createTaskExecution(String taskName, Date startTime,
|
||||||
|
List<String> arguments, String externalExecutionId, Long parentExecutionId) {
|
||||||
long nextExecutionId = getNextExecutionId();
|
long nextExecutionId = getNextExecutionId();
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(nextExecutionId, null, taskName,
|
TaskExecution taskExecution = new TaskExecution(nextExecutionId, null, taskName,
|
||||||
startTime, null, null, arguments, null, externalExecutionId);
|
startTime, null, null, arguments, null, externalExecutionId);
|
||||||
|
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskExecutionId", nextExecutionId, Types.BIGINT)
|
.addValue("taskExecutionId", nextExecutionId, Types.BIGINT)
|
||||||
.addValue("exitCode", null, Types.INTEGER)
|
.addValue("exitCode", null, Types.INTEGER)
|
||||||
.addValue("startTime", startTime, Types.TIMESTAMP)
|
.addValue("startTime", startTime, Types.TIMESTAMP)
|
||||||
.addValue("taskName", taskName, Types.VARCHAR)
|
.addValue("taskName", taskName, Types.VARCHAR)
|
||||||
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
|
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
|
||||||
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
|
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
|
||||||
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT);
|
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT);
|
||||||
|
|
||||||
jdbcTemplate.update(
|
this.jdbcTemplate.update(getQuery(SAVE_TASK_EXECUTION), queryParameters);
|
||||||
getQuery(SAVE_TASK_EXECUTION),
|
|
||||||
queryParameters);
|
|
||||||
insertTaskArguments(nextExecutionId, arguments);
|
insertTaskArguments(nextExecutionId, arguments);
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution startTaskExecution(long executionId, String taskName,
|
public TaskExecution startTaskExecution(long executionId, String taskName,
|
||||||
Date startTime, List<String> arguments,
|
Date startTime, List<String> arguments, String externalExecutionId) {
|
||||||
String externalExecutionId) {
|
|
||||||
return startTaskExecution(executionId, taskName, startTime, arguments,
|
return startTaskExecution(executionId, taskName, startTime, arguments,
|
||||||
externalExecutionId, null);
|
externalExecutionId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution startTaskExecution(long executionId, String taskName,
|
public TaskExecution startTaskExecution(long executionId, String taskName,
|
||||||
Date startTime, List<String> arguments,
|
Date startTime, List<String> arguments, String externalExecutionId,
|
||||||
String externalExecutionId, Long parentExecutionId) {
|
Long parentExecutionId) {
|
||||||
TaskExecution taskExecution = new TaskExecution(executionId, null, taskName,
|
TaskExecution taskExecution = new TaskExecution(executionId, null, taskName,
|
||||||
startTime, null, null, arguments,null, externalExecutionId, parentExecutionId);
|
startTime, null, null, arguments, null, externalExecutionId,
|
||||||
|
parentExecutionId);
|
||||||
|
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("startTime", startTime, Types.TIMESTAMP)
|
.addValue("startTime", startTime, Types.TIMESTAMP)
|
||||||
.addValue("exitCode", null, Types.INTEGER)
|
.addValue("exitCode", null, Types.INTEGER)
|
||||||
.addValue("taskName", taskName, Types.VARCHAR)
|
.addValue("taskName", taskName, Types.VARCHAR)
|
||||||
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
|
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
|
||||||
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT)
|
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT)
|
||||||
.addValue("taskExecutionId", executionId, Types.BIGINT);
|
.addValue("taskExecutionId", executionId, Types.BIGINT);
|
||||||
|
|
||||||
String updateString = START_TASK_EXECUTION_PREFIX;
|
String updateString = START_TASK_EXECUTION_PREFIX;
|
||||||
|
|
||||||
if(externalExecutionId == null) {
|
if (externalExecutionId == null) {
|
||||||
updateString += START_TASK_EXECUTION_SUFFIX;
|
updateString += START_TASK_EXECUTION_SUFFIX;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
updateString += START_TASK_EXECUTION_EXTERNAL_ID_SUFFIX;
|
updateString += START_TASK_EXECUTION_EXTERNAL_ID_SUFFIX;
|
||||||
queryParameters.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR);
|
queryParameters.addValue("externalExecutionId", externalExecutionId,
|
||||||
|
Types.VARCHAR);
|
||||||
}
|
}
|
||||||
|
|
||||||
jdbcTemplate.update(getQuery(updateString), queryParameters);
|
this.jdbcTemplate.update(getQuery(updateString), queryParameters);
|
||||||
insertTaskArguments(executionId, arguments);
|
insertTaskArguments(executionId, arguments);
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime,
|
public void completeTaskExecution(long taskExecutionId, Integer exitCode,
|
||||||
String exitMessage, String errorMessage) {
|
Date endTime, String exitMessage, String errorMessage) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
||||||
|
|
||||||
// Check if given TaskExecution's Id already exists, if none is found
|
// Check if given TaskExecution's Id already exists, if none is found
|
||||||
// it is invalid and an exception should be thrown.
|
// it is invalid and an exception should be thrown.
|
||||||
if (jdbcTemplate.queryForObject(getQuery(CHECK_TASK_EXECUTION_EXISTS), queryParameters, Integer.class) != 1) {
|
if (this.jdbcTemplate.queryForObject(getQuery(CHECK_TASK_EXECUTION_EXISTS),
|
||||||
throw new IllegalStateException("Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
queryParameters, Integer.class) != 1) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
final MapSqlParameterSource parameters = new MapSqlParameterSource()
|
final MapSqlParameterSource parameters = new MapSqlParameterSource()
|
||||||
.addValue("endTime", endTime, Types.TIMESTAMP)
|
.addValue("endTime", endTime, Types.TIMESTAMP)
|
||||||
.addValue("exitCode", exitCode, Types.INTEGER)
|
.addValue("exitCode", exitCode, Types.INTEGER)
|
||||||
.addValue("exitMessage", exitMessage, Types.VARCHAR)
|
.addValue("exitMessage", exitMessage, Types.VARCHAR)
|
||||||
.addValue("errorMessage", errorMessage, Types.VARCHAR)
|
.addValue("errorMessage", errorMessage, Types.VARCHAR)
|
||||||
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
|
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
|
||||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
||||||
|
|
||||||
jdbcTemplate.update(
|
this.jdbcTemplate.update(getQuery(UPDATE_TASK_EXECUTION), parameters);
|
||||||
getQuery(UPDATE_TASK_EXECUTION),
|
|
||||||
parameters);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime,
|
public void completeTaskExecution(long taskExecutionId, Integer exitCode,
|
||||||
String exitMessage) {
|
Date endTime, String exitMessage) {
|
||||||
completeTaskExecution(taskExecutionId, exitCode, endTime, exitMessage, null);
|
completeTaskExecution(taskExecutionId, exitCode, endTime, exitMessage, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution getTaskExecution(long executionId) {
|
public TaskExecution getTaskExecution(long executionId) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskExecutionId", executionId, Types.BIGINT);
|
.addValue("taskExecutionId", executionId, Types.BIGINT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
TaskExecution taskExecution = jdbcTemplate.queryForObject(getQuery(GET_EXECUTION_BY_ID),
|
TaskExecution taskExecution = this.jdbcTemplate.queryForObject(
|
||||||
queryParameters, new TaskExecutionRowMapper());
|
getQuery(GET_EXECUTION_BY_ID), queryParameters,
|
||||||
|
new TaskExecutionRowMapper());
|
||||||
taskExecution.setArguments(getTaskArguments(executionId));
|
taskExecution.setArguments(getTaskArguments(executionId));
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
@@ -295,11 +306,11 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
public long getTaskExecutionCountByTaskName(String taskName) {
|
public long getTaskExecutionCountByTaskName(String taskName) {
|
||||||
|
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskName", taskName, Types.VARCHAR);
|
.addValue("taskName", taskName, Types.VARCHAR);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return jdbcTemplate.queryForObject(
|
return this.jdbcTemplate.queryForObject(
|
||||||
getQuery(TASK_EXECUTION_COUNT_BY_NAME), queryParameters, Long.class);
|
getQuery(TASK_EXECUTION_COUNT_BY_NAME), queryParameters, Long.class);
|
||||||
}
|
}
|
||||||
catch (EmptyResultDataAccessException e) {
|
catch (EmptyResultDataAccessException e) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -309,11 +320,12 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public long getRunningTaskExecutionCountByTaskName(String taskName) {
|
public long getRunningTaskExecutionCountByTaskName(String taskName) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskName", taskName, Types.VARCHAR);
|
.addValue("taskName", taskName, Types.VARCHAR);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return jdbcTemplate.queryForObject(
|
return this.jdbcTemplate.queryForObject(
|
||||||
getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), queryParameters, Long.class);
|
getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), queryParameters,
|
||||||
|
Long.class);
|
||||||
}
|
}
|
||||||
catch (EmptyResultDataAccessException e) {
|
catch (EmptyResultDataAccessException e) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -325,8 +337,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource();
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource();
|
||||||
return jdbcTemplate.queryForObject(
|
return this.jdbcTemplate.queryForObject(
|
||||||
getQuery(RUNNING_TASK_EXECUTION_COUNT), queryParameters, Long.class);
|
getQuery(RUNNING_TASK_EXECUTION_COUNT), queryParameters, Long.class);
|
||||||
}
|
}
|
||||||
catch (EmptyResultDataAccessException e) {
|
catch (EmptyResultDataAccessException e) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -345,14 +357,15 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.isTrue(taskNamesAsList.size() == taskNames.length,
|
Assert.isTrue(taskNamesAsList.size() == taskNames.length, String.format(
|
||||||
String.format("Task names must not contain any empty elements but %s of %s were empty or null.",
|
"Task names must not contain any empty elements but %s of %s were empty or null.",
|
||||||
taskNames.length - taskNamesAsList.size(), taskNames.length));
|
taskNames.length - taskNamesAsList.size(), taskNames.length));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
final Map<String, List<String>> paramMap = Collections.singletonMap("taskNames", taskNamesAsList);
|
final Map<String, List<String>> paramMap = Collections
|
||||||
return this.jdbcTemplate.query(
|
.singletonMap("taskNames", taskNamesAsList);
|
||||||
getQuery(LAST_TASK_EXECUTIONS_BY_TASK_NAMES), paramMap, new TaskExecutionRowMapper());
|
return this.jdbcTemplate.query(getQuery(LAST_TASK_EXECUTIONS_BY_TASK_NAMES),
|
||||||
|
paramMap, new TaskExecutionRowMapper());
|
||||||
}
|
}
|
||||||
catch (EmptyResultDataAccessException e) {
|
catch (EmptyResultDataAccessException e) {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@@ -362,7 +375,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
|
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
|
||||||
Assert.hasText(taskName, "The task name must not be empty.");
|
Assert.hasText(taskName, "The task name must not be empty.");
|
||||||
final List<TaskExecution> taskExecutions = this.getLatestTaskExecutionsByTaskNames(taskName);
|
final List<TaskExecution> taskExecutions = this
|
||||||
|
.getLatestTaskExecutionsByTaskNames(taskName);
|
||||||
if (taskExecutions.isEmpty()) {
|
if (taskExecutions.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -370,7 +384,9 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
return taskExecutions.get(0);
|
return taskExecutions.get(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException("Only expected a single TaskExecution but received " + taskExecutions.size());
|
throw new IllegalStateException(
|
||||||
|
"Only expected a single TaskExecution but received "
|
||||||
|
+ taskExecutions.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -378,8 +394,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
public long getTaskExecutionCount() {
|
public long getTaskExecutionCount() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return jdbcTemplate.queryForObject(
|
return this.jdbcTemplate.queryForObject(getQuery(TASK_EXECUTION_COUNT),
|
||||||
getQuery(TASK_EXECUTION_COUNT), new MapSqlParameterSource(), Long.class);
|
new MapSqlParameterSource(), Long.class);
|
||||||
}
|
}
|
||||||
catch (EmptyResultDataAccessException e) {
|
catch (EmptyResultDataAccessException e) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -387,14 +403,17 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
|
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
|
||||||
|
Pageable pageable) {
|
||||||
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE,
|
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE,
|
||||||
RUNNING_TASK_WHERE_CLAUSE, new MapSqlParameterSource("taskName", taskName),
|
RUNNING_TASK_WHERE_CLAUSE,
|
||||||
|
new MapSqlParameterSource("taskName", taskName),
|
||||||
getRunningTaskExecutionCountByTaskName(taskName));
|
getRunningTaskExecutionCountByTaskName(taskName));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
|
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
|
||||||
|
Pageable pageable) {
|
||||||
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE,
|
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE,
|
||||||
TASK_NAME_WHERE_CLAUSE, new MapSqlParameterSource("taskName", taskName),
|
TASK_NAME_WHERE_CLAUSE, new MapSqlParameterSource("taskName", taskName),
|
||||||
getTaskExecutionCountByTaskName(taskName));
|
getTaskExecutionCountByTaskName(taskName));
|
||||||
@@ -402,7 +421,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getTaskNames() {
|
public List<String> getTaskNames() {
|
||||||
return jdbcTemplate.queryForList(getQuery(FIND_TASK_NAMES), new MapSqlParameterSource(), String.class);
|
return this.jdbcTemplate.queryForList(getQuery(FIND_TASK_NAMES),
|
||||||
|
new MapSqlParameterSource(), String.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -415,19 +435,18 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
this.taskIncrementer = taskIncrementer;
|
this.taskIncrementer = taskIncrementer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNextExecutionId(){
|
public long getNextExecutionId() {
|
||||||
return taskIncrementer.nextLongValue();
|
return this.taskIncrementer.nextLongValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
|
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("jobExecutionId", jobExecutionId, Types.BIGINT);
|
.addValue("jobExecutionId", jobExecutionId, Types.BIGINT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return jdbcTemplate.queryForObject(
|
return this.jdbcTemplate.queryForObject(
|
||||||
getQuery(FIND_TASK_EXECUTION_BY_JOB_EXECUTION_ID),
|
getQuery(FIND_TASK_EXECUTION_BY_JOB_EXECUTION_ID), queryParameters,
|
||||||
queryParameters,
|
|
||||||
Long.class);
|
Long.class);
|
||||||
}
|
}
|
||||||
catch (EmptyResultDataAccessException e) {
|
catch (EmptyResultDataAccessException e) {
|
||||||
@@ -438,19 +457,20 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return jdbcTemplate.query(
|
return this.jdbcTemplate.query(
|
||||||
getQuery(FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID),
|
getQuery(FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID), queryParameters,
|
||||||
queryParameters,
|
|
||||||
new ResultSetExtractor<Set<Long>>() {
|
new ResultSetExtractor<Set<Long>>() {
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
|
public Set<Long> extractData(ResultSet resultSet)
|
||||||
|
throws SQLException, DataAccessException {
|
||||||
Set<Long> jobExecutionIds = new TreeSet<>();
|
Set<Long> jobExecutionIds = new TreeSet<>();
|
||||||
|
|
||||||
while(resultSet.next()) {
|
while (resultSet.next()) {
|
||||||
jobExecutionIds.add(resultSet.getLong("JOB_EXECUTION_ID"));
|
jobExecutionIds
|
||||||
|
.add(resultSet.getLong("JOB_EXECUTION_ID"));
|
||||||
}
|
}
|
||||||
|
|
||||||
return jobExecutionIds;
|
return jobExecutionIds;
|
||||||
@@ -463,29 +483,27 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateExternalExecutionId(long taskExecutionId, String externalExecutionId) {
|
public void updateExternalExecutionId(long taskExecutionId,
|
||||||
|
String externalExecutionId) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
|
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
|
||||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
||||||
|
|
||||||
if (jdbcTemplate.update(
|
if (this.jdbcTemplate.update(
|
||||||
getQuery(UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID),
|
getQuery(UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID),
|
||||||
queryParameters) != 1) {
|
queryParameters) != 1) {
|
||||||
throw new IllegalStateException("Invalid TaskExecution, ID "
|
throw new IllegalStateException(
|
||||||
+ taskExecutionId + " not found.");
|
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Page<TaskExecution> queryForPageableResults(Pageable pageable,
|
private Page<TaskExecution> queryForPageableResults(Pageable pageable,
|
||||||
String selectClause,
|
String selectClause, String fromClause, String whereClause,
|
||||||
String fromClause,
|
MapSqlParameterSource queryParameters, long totalCount) {
|
||||||
String whereClause,
|
|
||||||
MapSqlParameterSource queryParameters,
|
|
||||||
long totalCount){
|
|
||||||
SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean();
|
SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean();
|
||||||
factoryBean.setSelectClause(selectClause);
|
factoryBean.setSelectClause(selectClause);
|
||||||
factoryBean.setFromClause(fromClause);
|
factoryBean.setFromClause(fromClause);
|
||||||
if(StringUtils.hasText(whereClause)){
|
if (StringUtils.hasText(whereClause)) {
|
||||||
factoryBean.setWhereClause(whereClause);
|
factoryBean.setWhereClause(whereClause);
|
||||||
}
|
}
|
||||||
final Sort sort = pageable.getSort();
|
final Sort sort = pageable.getSort();
|
||||||
@@ -493,7 +511,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
if (sort != null) {
|
if (sort != null) {
|
||||||
for (Sort.Order sortOrder : sort) {
|
for (Sort.Order sortOrder : sort) {
|
||||||
sortOrderMap.put(sortOrder.getProperty(), sortOrder.isAscending() ? Order.ASCENDING : Order.DESCENDING);
|
sortOrderMap.put(sortOrder.getProperty(),
|
||||||
|
sortOrder.isAscending() ? Order.ASCENDING : Order.DESCENDING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -508,29 +527,25 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
PagingQueryProvider pagingQueryProvider;
|
PagingQueryProvider pagingQueryProvider;
|
||||||
try {
|
try {
|
||||||
pagingQueryProvider = factoryBean.getObject();
|
pagingQueryProvider = factoryBean.getObject();
|
||||||
pagingQueryProvider.init(dataSource);
|
pagingQueryProvider.init(this.dataSource);
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
String query = pagingQueryProvider.getPageQuery(pageable);
|
String query = pagingQueryProvider.getPageQuery(pageable);
|
||||||
List<TaskExecution> resultList = jdbcTemplate.query(
|
List<TaskExecution> resultList = this.jdbcTemplate.query(getQuery(query),
|
||||||
getQuery(query),
|
queryParameters, new TaskExecutionRowMapper());
|
||||||
queryParameters,
|
|
||||||
new TaskExecutionRowMapper());
|
|
||||||
return new PageImpl<>(resultList, pageable, totalCount);
|
return new PageImpl<>(resultList, pageable, totalCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getQuery(String base) {
|
private String getQuery(String base) {
|
||||||
return StringUtils.replace(base, "%PREFIX%", tablePrefix);
|
return StringUtils.replace(base, "%PREFIX%", this.tablePrefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method that inserts all arguments from the provided
|
* Convenience method that inserts all arguments from the provided task arguments.
|
||||||
* task arguments.
|
* @param executionId The executionId to which the arguments are associated.
|
||||||
*
|
* @param taskArguments The arguments to be stored.
|
||||||
* @param executionId The executionId to which the arguments are associated.
|
|
||||||
* @param taskArguments The arguments to be stored.
|
|
||||||
*/
|
*/
|
||||||
private void insertTaskArguments(long executionId, List<String> taskArguments) {
|
private void insertTaskArguments(long executionId, List<String> taskArguments) {
|
||||||
for (String args : taskArguments) {
|
for (String args : taskArguments) {
|
||||||
@@ -541,26 +556,29 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
/**
|
/**
|
||||||
* Convenience method that inserts an individual records into the
|
* Convenience method that inserts an individual records into the
|
||||||
* TASK_EXECUTION_PARAMS table.
|
* TASK_EXECUTION_PARAMS table.
|
||||||
|
* @param taskExecutionId id of a task execution
|
||||||
|
* @param taskParam task parameters
|
||||||
*/
|
*/
|
||||||
private void insertArgument(long taskExecutionId, String taskParam) {
|
private void insertArgument(long taskExecutionId, String taskParam) {
|
||||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT)
|
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT)
|
||||||
.addValue("taskParam", taskParam, Types.VARCHAR);
|
.addValue("taskParam", taskParam, Types.VARCHAR);
|
||||||
jdbcTemplate.update(getQuery(CREATE_TASK_ARGUMENT), queryParameters);
|
this.jdbcTemplate.update(getQuery(CREATE_TASK_ARGUMENT), queryParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<String> getTaskArguments(long taskExecutionId){
|
private List<String> getTaskArguments(long taskExecutionId) {
|
||||||
final List<String> params= new ArrayList<>();
|
final List<String> params = new ArrayList<>();
|
||||||
RowCallbackHandler handler = new RowCallbackHandler() {
|
RowCallbackHandler handler = new RowCallbackHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void processRow(ResultSet rs) throws SQLException {
|
public void processRow(ResultSet rs) throws SQLException {
|
||||||
params.add(rs.getString(2));
|
params.add(rs.getString(2));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
jdbcTemplate.query(getQuery(FIND_ARGUMENT_FROM_ID), new MapSqlParameterSource("taskExecutionId", taskExecutionId),
|
this.jdbcTemplate.query(getQuery(FIND_ARGUMENT_FROM_ID),
|
||||||
handler);
|
new MapSqlParameterSource("taskExecutionId", taskExecutionId), handler);
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-usable mapper for {@link TaskExecution} instances.
|
* Re-usable mapper for {@link TaskExecution} instances.
|
||||||
*
|
*
|
||||||
@@ -572,26 +590,23 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution mapRow(ResultSet rs, int rowNum) throws SQLException {
|
public TaskExecution mapRow(ResultSet rs, int rowNum) throws SQLException {
|
||||||
long id = rs.getLong("TASK_EXECUTION_ID");
|
long id = rs.getLong("TASK_EXECUTION_ID");
|
||||||
Long parentExecutionId = rs.getLong("PARENT_EXECUTION_ID");
|
Long parentExecutionId = rs.getLong("PARENT_EXECUTION_ID");
|
||||||
if(rs.wasNull()) {
|
if (rs.wasNull()) {
|
||||||
parentExecutionId = null;
|
parentExecutionId = null;
|
||||||
}
|
}
|
||||||
return new TaskExecution(id,
|
return new TaskExecution(id, getNullableExitCode(rs),
|
||||||
getNullableExitCode(rs),
|
rs.getString("TASK_NAME"), rs.getTimestamp("START_TIME"),
|
||||||
rs.getString("TASK_NAME"),
|
rs.getTimestamp("END_TIME"), rs.getString("EXIT_MESSAGE"),
|
||||||
rs.getTimestamp("START_TIME"),
|
getTaskArguments(id), rs.getString("ERROR_MESSAGE"),
|
||||||
rs.getTimestamp("END_TIME"),
|
rs.getString("EXTERNAL_EXECUTION_ID"), parentExecutionId);
|
||||||
rs.getString("EXIT_MESSAGE"),
|
|
||||||
getTaskArguments(id),
|
|
||||||
rs.getString("ERROR_MESSAGE"),
|
|
||||||
rs.getString("EXTERNAL_EXECUTION_ID"),
|
|
||||||
parentExecutionId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Integer getNullableExitCode(ResultSet rs) throws SQLException {
|
private Integer getNullableExitCode(ResultSet rs) throws SQLException {
|
||||||
int exitCode = rs.getInt("EXIT_CODE");
|
int exitCode = rs.getInt("EXIT_CODE");
|
||||||
return !rs.wasNull() ? exitCode : null;
|
return !rs.wasNull() ? exitCode : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -46,36 +46,38 @@ import org.springframework.util.StringUtils;
|
|||||||
*/
|
*/
|
||||||
public class MapTaskExecutionDao implements TaskExecutionDao {
|
public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||||
|
|
||||||
|
private final AtomicLong currentId = new AtomicLong(0L);
|
||||||
|
|
||||||
private ConcurrentMap<Long, TaskExecution> taskExecutions;
|
private ConcurrentMap<Long, TaskExecution> taskExecutions;
|
||||||
|
|
||||||
private ConcurrentMap<Long, Set<Long>> batchJobAssociations;
|
private ConcurrentMap<Long, Set<Long>> batchJobAssociations;
|
||||||
|
|
||||||
private final AtomicLong currentId = new AtomicLong(0L);
|
|
||||||
|
|
||||||
public MapTaskExecutionDao() {
|
public MapTaskExecutionDao() {
|
||||||
taskExecutions = new ConcurrentHashMap<>();
|
this.taskExecutions = new ConcurrentHashMap<>();
|
||||||
batchJobAssociations = new ConcurrentHashMap<>();
|
this.batchJobAssociations = new ConcurrentHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution createTaskExecution(String taskName,
|
public TaskExecution createTaskExecution(String taskName, Date startTime,
|
||||||
Date startTime, List<String> arguments, String externalExecutionId) {
|
List<String> arguments, String externalExecutionId) {
|
||||||
return createTaskExecution(taskName, startTime, arguments,
|
return createTaskExecution(taskName, startTime, arguments, externalExecutionId,
|
||||||
externalExecutionId, null);
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution createTaskExecution(String taskName, Date startTime, List<String> arguments, String externalExecutionId, Long parentExecutionId) {
|
public TaskExecution createTaskExecution(String taskName, Date startTime,
|
||||||
|
List<String> arguments, String externalExecutionId, Long parentExecutionId) {
|
||||||
long taskExecutionId = getNextExecutionId();
|
long taskExecutionId = getNextExecutionId();
|
||||||
TaskExecution taskExecution = new TaskExecution(taskExecutionId, null, taskName,
|
TaskExecution taskExecution = new TaskExecution(taskExecutionId, null, taskName,
|
||||||
startTime, null, null, arguments, null, externalExecutionId, parentExecutionId);
|
startTime, null, null, arguments, null, externalExecutionId,
|
||||||
taskExecutions.put(taskExecutionId, taskExecution);
|
parentExecutionId);
|
||||||
|
this.taskExecutions.put(taskExecutionId, taskExecution);
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution startTaskExecution(long executionId, String taskName, Date startTime, List<String> arguments,
|
public TaskExecution startTaskExecution(long executionId, String taskName,
|
||||||
String externalExecutionid) {
|
Date startTime, List<String> arguments, String externalExecutionid) {
|
||||||
return startTaskExecution(executionId, taskName, startTime, arguments,
|
return startTaskExecution(executionId, taskName, startTime, arguments,
|
||||||
externalExecutionid, null);
|
externalExecutionid, null);
|
||||||
}
|
}
|
||||||
@@ -84,24 +86,26 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
public TaskExecution startTaskExecution(long executionId, String taskName,
|
public TaskExecution startTaskExecution(long executionId, String taskName,
|
||||||
Date startTime, List<String> arguments, String externalExecutionid,
|
Date startTime, List<String> arguments, String externalExecutionid,
|
||||||
Long parentExecutionId) {
|
Long parentExecutionId) {
|
||||||
TaskExecution taskExecution= taskExecutions.get(executionId);
|
TaskExecution taskExecution = this.taskExecutions.get(executionId);
|
||||||
taskExecution.setTaskName(taskName);
|
taskExecution.setTaskName(taskName);
|
||||||
taskExecution.setStartTime(startTime);
|
taskExecution.setStartTime(startTime);
|
||||||
taskExecution.setArguments(arguments);
|
taskExecution.setArguments(arguments);
|
||||||
taskExecution.setParentExecutionId(parentExecutionId);
|
taskExecution.setParentExecutionId(parentExecutionId);
|
||||||
if(externalExecutionid != null) {
|
if (externalExecutionid != null) {
|
||||||
taskExecution.setExternalExecutionId(externalExecutionid);
|
taskExecution.setExternalExecutionId(externalExecutionid);
|
||||||
}
|
}
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage, String errorMessage) {
|
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||||
if(!this.taskExecutions.containsKey(executionId)) {
|
String exitMessage, String errorMessage) {
|
||||||
throw new IllegalStateException("Invalid TaskExecution, ID " + executionId + " not found.");
|
if (!this.taskExecutions.containsKey(executionId)) {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Invalid TaskExecution, ID " + executionId + " not found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskExecution taskExecution= taskExecutions.get(executionId);
|
TaskExecution taskExecution = this.taskExecutions.get(executionId);
|
||||||
taskExecution.setEndTime(endTime);
|
taskExecution.setEndTime(endTime);
|
||||||
taskExecution.setExitCode(exitCode);
|
taskExecution.setExitCode(exitCode);
|
||||||
taskExecution.setExitMessage(exitMessage);
|
taskExecution.setExitMessage(exitMessage);
|
||||||
@@ -109,19 +113,20 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage) {
|
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||||
|
String exitMessage) {
|
||||||
completeTaskExecution(executionId, exitCode, endTime, exitMessage, null);
|
completeTaskExecution(executionId, exitCode, endTime, exitMessage, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution getTaskExecution(long executionId) {
|
public TaskExecution getTaskExecution(long executionId) {
|
||||||
return taskExecutions.get(executionId);
|
return this.taskExecutions.get(executionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTaskExecutionCountByTaskName(String taskName) {
|
public long getTaskExecutionCountByTaskName(String taskName) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||||
if (entry.getValue().getTaskName().equals(taskName)) {
|
if (entry.getValue().getTaskName().equals(taskName)) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@@ -132,9 +137,9 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public long getRunningTaskExecutionCountByTaskName(String taskName) {
|
public long getRunningTaskExecutionCountByTaskName(String taskName) {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||||
if (entry.getValue().getTaskName().equals(taskName) &&
|
if (entry.getValue().getTaskName().equals(taskName)
|
||||||
entry.getValue().getEndTime() == null) {
|
&& entry.getValue().getEndTime() == null) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -144,8 +149,8 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public long getRunningTaskExecutionCount() {
|
public long getRunningTaskExecutionCount() {
|
||||||
long count = 0;
|
long count = 0;
|
||||||
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||||
if ( entry.getValue().getEndTime() == null) {
|
if (entry.getValue().getEndTime() == null) {
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,15 +159,16 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTaskExecutionCount() {
|
public long getTaskExecutionCount() {
|
||||||
return taskExecutions.size();
|
return this.taskExecutions.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
|
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
|
||||||
|
Pageable pageable) {
|
||||||
Set<TaskExecution> result = getTaskExecutionTreeSet();
|
Set<TaskExecution> result = getTaskExecutionTreeSet();
|
||||||
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||||
if (entry.getValue().getTaskName().equals(taskName) &&
|
if (entry.getValue().getTaskName().equals(taskName)
|
||||||
entry.getValue().getEndTime() == null) {
|
&& entry.getValue().getEndTime() == null) {
|
||||||
result.add(entry.getValue());
|
result.add(entry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,9 +177,10 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
|
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
|
||||||
|
Pageable pageable) {
|
||||||
Set<TaskExecution> filteredSet = getTaskExecutionTreeSet();
|
Set<TaskExecution> filteredSet = getTaskExecutionTreeSet();
|
||||||
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||||
if (entry.getValue().getTaskName().equals(taskName)) {
|
if (entry.getValue().getTaskName().equals(taskName)) {
|
||||||
filteredSet.add(entry.getValue());
|
filteredSet.add(entry.getValue());
|
||||||
}
|
}
|
||||||
@@ -185,7 +192,7 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public List<String> getTaskNames() {
|
public List<String> getTaskNames() {
|
||||||
Set<String> result = new TreeSet<>();
|
Set<String> result = new TreeSet<>();
|
||||||
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||||
result.add(entry.getValue().getTaskName());
|
result.add(entry.getValue().getTaskName());
|
||||||
}
|
}
|
||||||
return new ArrayList<>(result);
|
return new ArrayList<>(result);
|
||||||
@@ -194,17 +201,17 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findAll(Pageable pageable) {
|
public Page<TaskExecution> findAll(Pageable pageable) {
|
||||||
TreeSet<TaskExecution> sortedSet = getTaskExecutionTreeSet();
|
TreeSet<TaskExecution> sortedSet = getTaskExecutionTreeSet();
|
||||||
sortedSet.addAll(taskExecutions.values());
|
sortedSet.addAll(this.taskExecutions.values());
|
||||||
List<TaskExecution> result = new ArrayList<>(sortedSet.descendingSet());
|
List<TaskExecution> result = new ArrayList<>(sortedSet.descendingSet());
|
||||||
return getPageFromList(result, pageable, getTaskExecutionCount());
|
return getPageFromList(result, pageable, getTaskExecutionCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<Long, TaskExecution> getTaskExecutions() {
|
public Map<Long, TaskExecution> getTaskExecutions() {
|
||||||
return Collections.unmodifiableMap(taskExecutions);
|
return Collections.unmodifiableMap(this.taskExecutions);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNextExecutionId(){
|
public long getNextExecutionId() {
|
||||||
return currentId.getAndIncrement();
|
return this.currentId.getAndIncrement();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -213,9 +220,10 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
found:
|
found:
|
||||||
|
|
||||||
for (Map.Entry<Long, Set<Long>> association : batchJobAssociations.entrySet()) {
|
for (Map.Entry<Long, Set<Long>> association : this.batchJobAssociations
|
||||||
|
.entrySet()) {
|
||||||
for (Long curJobExecutionId : association.getValue()) {
|
for (Long curJobExecutionId : association.getValue()) {
|
||||||
if(curJobExecutionId.equals(jobExecutionId)) {
|
if (curJobExecutionId.equals(jobExecutionId)) {
|
||||||
taskId = association.getKey();
|
taskId = association.getKey();
|
||||||
break found;
|
break found;
|
||||||
}
|
}
|
||||||
@@ -227,8 +235,9 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
||||||
if(batchJobAssociations.containsKey(taskExecutionId)) {
|
if (this.batchJobAssociations.containsKey(taskExecutionId)) {
|
||||||
return Collections.unmodifiableSet(batchJobAssociations.get(taskExecutionId));
|
return Collections
|
||||||
|
.unmodifiableSet(this.batchJobAssociations.get(taskExecutionId));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new TreeSet<>();
|
return new TreeSet<>();
|
||||||
@@ -236,15 +245,16 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateExternalExecutionId(long taskExecutionId, String externalExecutionId) {
|
public void updateExternalExecutionId(long taskExecutionId,
|
||||||
TaskExecution taskExecution = taskExecutions.get(taskExecutionId);
|
String externalExecutionId) {
|
||||||
Assert.notNull(taskExecution, "Invalid TaskExecution, ID "
|
TaskExecution taskExecution = this.taskExecutions.get(taskExecutionId);
|
||||||
+ taskExecutionId + " not found.");
|
Assert.notNull(taskExecution,
|
||||||
|
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||||
taskExecution.setExternalExecutionId(externalExecutionId);
|
taskExecution.setExternalExecutionId(externalExecutionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConcurrentMap<Long, Set<Long>> getBatchJobAssociations() {
|
public ConcurrentMap<Long, Set<Long>> getBatchJobAssociations() {
|
||||||
return batchJobAssociations;
|
return this.batchJobAssociations;
|
||||||
}
|
}
|
||||||
|
|
||||||
private TreeSet<TaskExecution> getTaskExecutionTreeSet() {
|
private TreeSet<TaskExecution> getTaskExecutionTreeSet() {
|
||||||
@@ -252,19 +262,22 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public int compare(TaskExecution e1, TaskExecution e2) {
|
public int compare(TaskExecution e1, TaskExecution e2) {
|
||||||
int result = e1.getStartTime().compareTo(e2.getStartTime());
|
int result = e1.getStartTime().compareTo(e2.getStartTime());
|
||||||
if (result == 0){
|
if (result == 0) {
|
||||||
result = Long.valueOf(e1.getExecutionId()).compareTo(e2.getExecutionId());
|
result = Long.valueOf(e1.getExecutionId())
|
||||||
|
.compareTo(e2.getExecutionId());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Page getPageFromList(List<TaskExecution> executionList, Pageable pageable, long maxSize){
|
private Page getPageFromList(List<TaskExecution> executionList, Pageable pageable,
|
||||||
long toIndex = (pageable.getOffset() + pageable.getPageSize() > executionList.size()) ?
|
long maxSize) {
|
||||||
executionList.size() : pageable.getOffset() + pageable.getPageSize();
|
long toIndex = (pageable.getOffset() + pageable.getPageSize() > executionList
|
||||||
|
.size()) ? executionList.size()
|
||||||
|
: pageable.getOffset() + pageable.getPageSize();
|
||||||
return new PageImpl<>(
|
return new PageImpl<>(
|
||||||
executionList.subList((int)pageable.getOffset(), (int)toIndex),
|
executionList.subList((int) pageable.getOffset(), (int) toIndex),
|
||||||
pageable, maxSize);
|
pageable, maxSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,29 +294,34 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.isTrue(taskNamesAsList.size() == taskNames.length,
|
Assert.isTrue(taskNamesAsList.size() == taskNames.length, String.format(
|
||||||
String.format("Task names must not contain any empty elements but %s of %s were empty or null.",
|
"Task names must not contain any empty elements but %s of %s were empty or null.",
|
||||||
taskNames.length - taskNamesAsList.size(), taskNames.length));
|
taskNames.length - taskNamesAsList.size(), taskNames.length));
|
||||||
|
|
||||||
final Map<String, TaskExecution> tempTaskExecutions = new HashMap<>();
|
final Map<String, TaskExecution> tempTaskExecutions = new HashMap<>();
|
||||||
|
|
||||||
for (Map.Entry<Long, TaskExecution> taskExecutionMapEntry : this.taskExecutions.entrySet()) {
|
for (Map.Entry<Long, TaskExecution> taskExecutionMapEntry : this.taskExecutions
|
||||||
if (!taskNamesAsList.contains(taskExecutionMapEntry.getValue().getTaskName())) {
|
.entrySet()) {
|
||||||
|
if (!taskNamesAsList
|
||||||
|
.contains(taskExecutionMapEntry.getValue().getTaskName())) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
final TaskExecution tempTaskExecution = tempTaskExecutions.get(taskExecutionMapEntry.getValue().getTaskName());
|
final TaskExecution tempTaskExecution = tempTaskExecutions
|
||||||
|
.get(taskExecutionMapEntry.getValue().getTaskName());
|
||||||
if (tempTaskExecution == null
|
if (tempTaskExecution == null
|
||||||
|| tempTaskExecution.getStartTime().before(taskExecutionMapEntry.getValue().getStartTime())
|
|| tempTaskExecution.getStartTime()
|
||||||
|| (
|
.before(taskExecutionMapEntry.getValue().getStartTime())
|
||||||
tempTaskExecution.getStartTime().equals(taskExecutionMapEntry.getValue().getStartTime())
|
|| (tempTaskExecution.getStartTime()
|
||||||
&& tempTaskExecution.getExecutionId() < taskExecutionMapEntry.getValue().getExecutionId()
|
.equals(taskExecutionMapEntry.getValue().getStartTime())
|
||||||
)
|
&& tempTaskExecution.getExecutionId() < taskExecutionMapEntry
|
||||||
) {
|
.getValue().getExecutionId())) {
|
||||||
tempTaskExecutions.put(taskExecutionMapEntry.getValue().getTaskName(), taskExecutionMapEntry.getValue());
|
tempTaskExecutions.put(taskExecutionMapEntry.getValue().getTaskName(),
|
||||||
|
taskExecutionMapEntry.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final List<TaskExecution> latestTaskExecutions = new ArrayList<>(tempTaskExecutions.values());
|
final List<TaskExecution> latestTaskExecutions = new ArrayList<>(
|
||||||
|
tempTaskExecutions.values());
|
||||||
Collections.sort(latestTaskExecutions, new TaskExecutionComparator());
|
Collections.sort(latestTaskExecutions, new TaskExecutionComparator());
|
||||||
return latestTaskExecutions;
|
return latestTaskExecutions;
|
||||||
}
|
}
|
||||||
@@ -311,7 +329,8 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
@Override
|
@Override
|
||||||
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
|
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
|
||||||
Assert.hasText(taskName, "The task name must not be empty.");
|
Assert.hasText(taskName, "The task name must not be empty.");
|
||||||
final List<TaskExecution> taskExecutions = this.getLatestTaskExecutionsByTaskNames(taskName);
|
final List<TaskExecution> taskExecutions = this
|
||||||
|
.getLatestTaskExecutionsByTaskNames(taskName);
|
||||||
if (taskExecutions.isEmpty()) {
|
if (taskExecutions.isEmpty()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -319,20 +338,29 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
|||||||
return taskExecutions.get(0);
|
return taskExecutions.get(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new IllegalStateException("Only expected a single TaskExecution but received " + taskExecutions.size());
|
throw new IllegalStateException(
|
||||||
|
"Only expected a single TaskExecution but received "
|
||||||
|
+ taskExecutions.size());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TaskExecutionComparator implements Comparator<TaskExecution>, Serializable {
|
private static class TaskExecutionComparator
|
||||||
|
implements Comparator<TaskExecution>, Serializable {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int compare(TaskExecution firstTaskExecution, TaskExecution secondTaskExecution) {
|
public int compare(TaskExecution firstTaskExecution,
|
||||||
if (firstTaskExecution.getStartTime().equals(secondTaskExecution.getStartTime())) {
|
TaskExecution secondTaskExecution) {
|
||||||
return Long.compare(firstTaskExecution.getExecutionId(), secondTaskExecution.getExecutionId());
|
if (firstTaskExecution.getStartTime()
|
||||||
|
.equals(secondTaskExecution.getStartTime())) {
|
||||||
|
return Long.compare(firstTaskExecution.getExecutionId(),
|
||||||
|
secondTaskExecution.getExecutionId());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return secondTaskExecution.getStartTime().compareTo(firstTaskExecution.getStartTime());
|
return secondTaskExecution.getStartTime()
|
||||||
|
.compareTo(firstTaskExecution.getStartTime());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -36,19 +36,17 @@ public interface TaskExecutionDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a new {@link TaskExecution}.
|
* Save a new {@link TaskExecution}.
|
||||||
*
|
|
||||||
* @param taskName the name that associated with the task execution.
|
* @param taskName the name that associated with the task execution.
|
||||||
* @param startTime the time task began.
|
* @param startTime the time task began.
|
||||||
* @param arguments list of key/value pairs that configure the task.
|
* @param arguments list of key/value pairs that configure the task.
|
||||||
* @param externalExecutionId id assigned to the task by the platform
|
* @param externalExecutionId id assigned to the task by the platform
|
||||||
* @return A fully qualified {@link TaskExecution} instance.
|
* @return A fully qualified {@link TaskExecution} instance.
|
||||||
*/
|
*/
|
||||||
TaskExecution createTaskExecution( String taskName,
|
TaskExecution createTaskExecution(String taskName, Date startTime,
|
||||||
Date startTime, List<String> arguments, String externalExecutionId);
|
List<String> arguments, String externalExecutionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a new {@link TaskExecution}.
|
* Save a new {@link TaskExecution}.
|
||||||
*
|
|
||||||
* @param taskName the name that associated with the task execution.
|
* @param taskName the name that associated with the task execution.
|
||||||
* @param startTime the time task began.
|
* @param startTime the time task began.
|
||||||
* @param arguments list of key/value pairs that configure the task.
|
* @param arguments list of key/value pairs that configure the task.
|
||||||
@@ -57,65 +55,62 @@ public interface TaskExecutionDao {
|
|||||||
* @return A fully qualified {@link TaskExecution} instance.
|
* @return A fully qualified {@link TaskExecution} instance.
|
||||||
* @since 1.2.0
|
* @since 1.2.0
|
||||||
*/
|
*/
|
||||||
TaskExecution createTaskExecution( String taskName,
|
TaskExecution createTaskExecution(String taskName, Date startTime,
|
||||||
Date startTime, List<String> arguments, String externalExecutionId,
|
List<String> arguments, String externalExecutionId, Long parentExecutionId);
|
||||||
Long parentExecutionId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update and existing {@link TaskExecution} to mark it as started.
|
* Update and existing {@link TaskExecution} to mark it as started.
|
||||||
*
|
* @param executionId the id of the taskExecution to be updated.
|
||||||
* @param executionId the id of the taskExecution to be updated.
|
|
||||||
* @param taskName the name that associated with the task execution.
|
* @param taskName the name that associated with the task execution.
|
||||||
* @param startTime the time task began.
|
* @param startTime the time task began.
|
||||||
* @param arguments list of key/value pairs that configure the task.
|
* @param arguments list of key/value pairs that configure the task.
|
||||||
* @param externalExecutionId id assigned to the task by the platform
|
* @param externalExecutionId id assigned to the task by the platform
|
||||||
* @return A TaskExecution containing the information available at task execution start.
|
* @return A TaskExecution containing the information available at task execution
|
||||||
|
* start.
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
TaskExecution startTaskExecution(long executionId, String taskName,
|
TaskExecution startTaskExecution(long executionId, String taskName, Date startTime,
|
||||||
Date startTime, List<String> arguments, String externalExecutionId);
|
List<String> arguments, String externalExecutionId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update and existing {@link TaskExecution} to mark it as started.
|
* Update and existing {@link TaskExecution} to mark it as started.
|
||||||
*
|
* @param executionId the id of the taskExecution to be updated.
|
||||||
* @param executionId the id of the taskExecution to be updated.
|
|
||||||
* @param taskName the name that associated with the task execution.
|
* @param taskName the name that associated with the task execution.
|
||||||
* @param startTime the time task began.
|
* @param startTime the time task began.
|
||||||
* @param arguments list of key/value pairs that configure the task.
|
* @param arguments list of key/value pairs that configure the task.
|
||||||
* @param externalExecutionId id assigned to the task by the platform
|
* @param externalExecutionId id assigned to the task by the platform
|
||||||
* @param parentExecutionId the parent task execution id.
|
* @param parentExecutionId the parent task execution id.
|
||||||
* @return A TaskExecution containing the information available at task execution start.
|
* @return A TaskExecution containing the information available at task execution
|
||||||
|
* start.
|
||||||
* @since 1.2.0
|
* @since 1.2.0
|
||||||
*/
|
*/
|
||||||
TaskExecution startTaskExecution(long executionId, String taskName,
|
TaskExecution startTaskExecution(long executionId, String taskName, Date startTime,
|
||||||
Date startTime, List<String> arguments, String externalExecutionId,
|
List<String> arguments, String externalExecutionId, Long parentExecutionId);
|
||||||
Long parentExecutionId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update and existing {@link TaskExecution} to mark it as completed.
|
* Update and existing {@link TaskExecution} to mark it as completed.
|
||||||
*
|
* @param executionId the id of the taskExecution to be updated.
|
||||||
* @param executionId the id of the taskExecution to be updated.
|
|
||||||
* @param exitCode the status of the task upon completion.
|
* @param exitCode the status of the task upon completion.
|
||||||
* @param endTime the time the task completed.
|
* @param endTime the time the task completed.
|
||||||
* @param exitMessage the message assigned to the task upon completion.
|
* @param exitMessage the message assigned to the task upon completion.
|
||||||
* @param errorMessage error information available upon failure of a task.
|
* @param errorMessage error information available upon failure of a task.
|
||||||
* @since 1.1.0
|
* @since 1.1.0
|
||||||
*/
|
*/
|
||||||
void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage, String errorMessage);
|
void completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||||
|
String exitMessage, String errorMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update and existing {@link TaskExecution}.
|
* Update and existing {@link TaskExecution}.
|
||||||
*
|
* @param executionId the id of the taskExecution to be updated.
|
||||||
* @param executionId the id of the taskExecution to be updated.
|
|
||||||
* @param exitCode the status of the task upon completion.
|
* @param exitCode the status of the task upon completion.
|
||||||
* @param endTime the time the task completed.
|
* @param endTime the time the task completed.
|
||||||
* @param exitMessage the message assigned to the task upon completion.
|
* @param exitMessage the message assigned to the task upon completion.
|
||||||
*/
|
*/
|
||||||
void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage);
|
void completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||||
|
String exitMessage);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a task execution from the task repository.
|
* Retrieves a task execution from the task repository.
|
||||||
*
|
|
||||||
* @param executionId the id associated with the task execution.
|
* @param executionId the id associated with the task execution.
|
||||||
* @return a fully qualified TaskExecution instance.
|
* @return a fully qualified TaskExecution instance.
|
||||||
*/
|
*/
|
||||||
@@ -123,16 +118,14 @@ public interface TaskExecutionDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves current number of task executions for a taskName.
|
* Retrieves current number of task executions for a taskName.
|
||||||
*
|
|
||||||
* @param taskName the name of the task to search for in the repository.
|
* @param taskName the name of the task to search for in the repository.
|
||||||
* @return current number of task executions for the taskName.
|
* @return current number of task executions for the taskName.
|
||||||
*/
|
*/
|
||||||
long getTaskExecutionCountByTaskName(String taskName);
|
long getTaskExecutionCountByTaskName(String taskName);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves current number of task executions for a taskName and with an endTime of null.
|
* Retrieves current number of task executions for a taskName and with an endTime of
|
||||||
*
|
* null.
|
||||||
* @param taskName the name of the task to search for in the repository.
|
* @param taskName the name of the task to search for in the repository.
|
||||||
* @return current number of task executions for the taskName.
|
* @return current number of task executions for the taskName.
|
||||||
*/
|
*/
|
||||||
@@ -140,15 +133,12 @@ public interface TaskExecutionDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves current number of task executions with an endTime of null.
|
* Retrieves current number of task executions with an endTime of null.
|
||||||
*
|
|
||||||
* @return current number of task executions.
|
* @return current number of task executions.
|
||||||
*/
|
*/
|
||||||
long getRunningTaskExecutionCount();
|
long getRunningTaskExecutionCount();
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves current number of task executions.
|
* Retrieves current number of task executions.
|
||||||
*
|
|
||||||
* @return current number of task executions.
|
* @return current number of task executions.
|
||||||
*/
|
*/
|
||||||
long getTaskExecutionCount();
|
long getTaskExecutionCount();
|
||||||
@@ -159,7 +149,7 @@ public interface TaskExecutionDao {
|
|||||||
* @param pageable the constraints for the search.
|
* @param pageable the constraints for the search.
|
||||||
* @return set of running task executions.
|
* @return set of running task executions.
|
||||||
*/
|
*/
|
||||||
Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable);
|
Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a subset of task executions by task name, start location and size.
|
* Retrieves a subset of task executions by task name, start location and size.
|
||||||
@@ -172,7 +162,6 @@ public interface TaskExecutionDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves a sorted list of distinct task names for the task executions.
|
* Retrieves a sorted list of distinct task names for the task executions.
|
||||||
*
|
|
||||||
* @return a list of distinct task names from the task repository..
|
* @return a list of distinct task names from the task repository..
|
||||||
*/
|
*/
|
||||||
List<String> getTaskNames();
|
List<String> getTaskNames();
|
||||||
@@ -193,8 +182,7 @@ public interface TaskExecutionDao {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the id of the TaskExecution that the requested Spring Batch job execution
|
* Returns the id of the TaskExecution that the requested Spring Batch job execution
|
||||||
* was executed within the context of. Returns null if non were found.
|
* was executed within the context of. Returns null if non were found.
|
||||||
*
|
|
||||||
* @param jobExecutionId the id of the JobExecution
|
* @param jobExecutionId the id of the JobExecution
|
||||||
* @return the id of the {@link TaskExecution}
|
* @return the id of the {@link TaskExecution}
|
||||||
*/
|
*/
|
||||||
@@ -203,7 +191,8 @@ public interface TaskExecutionDao {
|
|||||||
/**
|
/**
|
||||||
* Returns the job execution ids associated with a task execution id.
|
* Returns the job execution ids associated with a task execution id.
|
||||||
* @param taskExecutionId id of the {@link TaskExecution}
|
* @param taskExecutionId id of the {@link TaskExecution}
|
||||||
* @return a <code>Set</code> of the ids of the job executions executed within the task.
|
* @return a <code>Set</code> of the ids of the job executions executed within the
|
||||||
|
* task.
|
||||||
*/
|
*/
|
||||||
Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId);
|
Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId);
|
||||||
|
|
||||||
@@ -212,35 +201,35 @@ public interface TaskExecutionDao {
|
|||||||
* @param taskExecutionId the execution id for the task to be updated.
|
* @param taskExecutionId the execution id for the task to be updated.
|
||||||
* @param externalExecutionId the new externalExecutionId.
|
* @param externalExecutionId the new externalExecutionId.
|
||||||
*/
|
*/
|
||||||
void updateExternalExecutionId(long taskExecutionId,
|
void updateExternalExecutionId(long taskExecutionId, String externalExecutionId);
|
||||||
String externalExecutionId);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a {@link List} of the latest {@link TaskExecution} for 1 or more task names.
|
* Returns a {@link List} of the latest {@link TaskExecution} for 1 or more task
|
||||||
|
* names.
|
||||||
*
|
*
|
||||||
* Latest is defined by the most recent start time. A {@link TaskExecution} does not have to be finished
|
* Latest is defined by the most recent start time. A {@link TaskExecution} does not
|
||||||
* (The results may including pending {@link TaskExecution}s).
|
* have to be finished (The results may including pending {@link TaskExecution}s).
|
||||||
*
|
*
|
||||||
* It is theoretically possible that a {@link TaskExecution} with the same name to have more than 1
|
* It is theoretically possible that a {@link TaskExecution} with the same name to
|
||||||
* {@link TaskExecution} for the exact same start time. In that case the {@link TaskExecution} with the
|
* have more than 1 {@link TaskExecution} for the exact same start time. In that case
|
||||||
* highest Task Execution ID is returned.
|
* the {@link TaskExecution} with the highest Task Execution ID is returned.
|
||||||
*
|
|
||||||
* This method will not consider end times in its calculations. Thus, when a task execution {@code A} starts
|
|
||||||
* after task execution {@code B} but finishes BEFORE task execution {@code A}, then task execution {@code B}
|
|
||||||
* is being returned.
|
|
||||||
*
|
*
|
||||||
|
* This method will not consider end times in its calculations. Thus, when a task
|
||||||
|
* execution {@code A} starts after task execution {@code B} but finishes BEFORE task
|
||||||
|
* execution {@code A}, then task execution {@code B} is being returned.
|
||||||
* @param taskNames At least 1 task name must be provided
|
* @param taskNames At least 1 task name must be provided
|
||||||
* @return List of TaskExecutions. May be empty but never null.
|
* @return List of TaskExecutions. May be empty but never null.
|
||||||
*/
|
*/
|
||||||
List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames);
|
List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the latest task execution for a given task name. Will ultimately apply the same algorithm underneath
|
* Returns the latest task execution for a given task name. Will ultimately apply the
|
||||||
* as {@link #getLatestTaskExecutionsByTaskNames(String...)} but will only return a single result.
|
* same algorithm underneath as {@link #getLatestTaskExecutionsByTaskNames(String...)}
|
||||||
*
|
* but will only return a single result.
|
||||||
* @param taskName Must not be null or empty
|
* @param taskName Must not be null or empty
|
||||||
* @return The latest Task Execution or null
|
* @return The latest Task Execution or null
|
||||||
* @see #getLatestTaskExecutionsByTaskNames(String...)
|
* @see #getLatestTaskExecutionsByTaskNames(String...)
|
||||||
*/
|
*/
|
||||||
TaskExecution getLatestTaskExecutionForTaskName(String taskName);
|
TaskExecution getLatestTaskExecutionForTaskName(String taskName);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface DAO and default implementations for storing and retrieving data for tasks
|
* Interface DAO and default implementations for storing and retrieving data for tasks
|
||||||
* from a repository.
|
* from a repository.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -25,35 +25,33 @@ import org.springframework.data.domain.Pageable;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface defining the functionality to be provided for generating paging queries.
|
* Interface defining the functionality to be provided for generating paging queries.
|
||||||
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public interface PagingQueryProvider {
|
public interface PagingQueryProvider {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the query provider using the provided {@link DataSource} if necessary.
|
* Initialize the query provider using the provided {@link DataSource} if necessary.
|
||||||
*
|
|
||||||
* @param dataSource DataSource to use for any initialization
|
* @param dataSource DataSource to use for any initialization
|
||||||
* @throws Exception throws {@link Exception} if query provider initialize fails.
|
* @throws Exception throws {@link Exception} if query provider initialize fails.
|
||||||
*/
|
*/
|
||||||
void init(DataSource dataSource) throws Exception;
|
void init(DataSource dataSource) throws Exception;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of parameters that are declared in the query
|
* The number of parameters that are declared in the query.
|
||||||
* @return number of parameters
|
* @return number of parameters
|
||||||
*/
|
*/
|
||||||
int getParameterCount();
|
int getParameterCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Indicate whether the generated queries use named parameter syntax.
|
* Indicate whether the generated queries use named parameter syntax.
|
||||||
*
|
|
||||||
* @return true if named parameter syntax is used
|
* @return true if named parameter syntax is used
|
||||||
*/
|
*/
|
||||||
boolean isUsingNamedParameters();
|
boolean isUsingNamedParameters();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The sort keys. A Map of the columns that make up the key and a Boolean indicating ascending or descending
|
* The sort keys. A Map of the columns that make up the key and a Boolean indicating
|
||||||
* (ascending = true).
|
* ascending or descending (ascending = true).
|
||||||
*
|
|
||||||
* @return the sort keys used to order the query
|
* @return the sort keys used to order the query
|
||||||
*/
|
*/
|
||||||
Map<String, Order> getSortKeys();
|
Map<String, Order> getSortKeys();
|
||||||
@@ -61,9 +59,9 @@ public interface PagingQueryProvider {
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Generate the query that will provide the jump to item query.
|
* Generate the query that will provide the jump to item query.
|
||||||
*
|
|
||||||
* @param pageable the coordinates to pull the next page from the datasource
|
* @param pageable the coordinates to pull the next page from the datasource
|
||||||
* @return the generated query
|
* @return the generated query
|
||||||
*/
|
*/
|
||||||
String getPageQuery(Pageable pageable);
|
String getPageQuery(Pageable pageable);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -31,15 +31,15 @@ import org.springframework.util.Assert;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract SQL Paging Query Provider to serve as a base class for all provided
|
* Abstract SQL Paging Query Provider to serve as a base class for all provided SQL paging
|
||||||
* SQL paging query providers.
|
* query providers.
|
||||||
*
|
*
|
||||||
* Any implementation must provide a way to specify the select clause, from
|
* Any implementation must provide a way to specify the select clause, from clause and
|
||||||
* clause and optionally a where clause. It is recommended that there should be an index for
|
* optionally a where clause. It is recommended that there should be an index for the sort
|
||||||
* the sort key to provide better performance.
|
* key to provide better performance.
|
||||||
*
|
*
|
||||||
* Provides properties and preparation for the mandatory "selectClause" and
|
* Provides properties and preparation for the mandatory "selectClause" and "fromClause"
|
||||||
* "fromClause" as well as for the optional "whereClause".
|
* as well as for the optional "whereClause".
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@@ -51,12 +51,19 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
|||||||
|
|
||||||
private String whereClause;
|
private String whereClause;
|
||||||
|
|
||||||
private Map<String, Order> sortKeys = new LinkedHashMap<String, Order>();
|
private Map<String, Order> sortKeys = new LinkedHashMap<>();
|
||||||
|
|
||||||
private int parameterCount;
|
private int parameterCount;
|
||||||
|
|
||||||
private boolean usingNamedParameters;
|
private boolean usingNamedParameters;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SQL SELECT clause part of SQL query string
|
||||||
|
*/
|
||||||
|
protected String getSelectClause() {
|
||||||
|
return this.selectClause;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param selectClause SELECT clause part of SQL query string
|
* @param selectClause SELECT clause part of SQL query string
|
||||||
*/
|
*/
|
||||||
@@ -65,11 +72,10 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return SQL FROM clause part of SQL query string
|
||||||
* @return SQL SELECT clause part of SQL query string
|
|
||||||
*/
|
*/
|
||||||
protected String getSelectClause() {
|
protected String getFromClause() {
|
||||||
return selectClause;
|
return this.fromClause;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -80,11 +86,10 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* @return SQL WHERE clause part of SQL query string
|
||||||
* @return SQL FROM clause part of SQL query string
|
|
||||||
*/
|
*/
|
||||||
protected String getFromClause() {
|
protected String getWhereClause() {
|
||||||
return fromClause;
|
return this.whereClause;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -100,11 +105,13 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* A Map<String, Order> of sort columns as the key and {@link Order} for
|
||||||
* @return SQL WHERE clause part of SQL query string
|
* ascending/descending.
|
||||||
|
* @return sortKey key to use to sort and limit page content
|
||||||
*/
|
*/
|
||||||
protected String getWhereClause() {
|
@Override
|
||||||
return whereClause;
|
public Map<String, Order> getSortKeys() {
|
||||||
|
return this.sortKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -114,56 +121,51 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
|||||||
this.sortKeys = sortKeys;
|
this.sortKeys = sortKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A Map<String, Order> of sort columns as the key and {@link Order} for ascending/descending.
|
|
||||||
*
|
|
||||||
* @return sortKey key to use to sort and limit page content
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public Map<String, Order> getSortKeys() {
|
|
||||||
return sortKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getParameterCount() {
|
public int getParameterCount() {
|
||||||
return parameterCount;
|
return this.parameterCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isUsingNamedParameters() {
|
public boolean isUsingNamedParameters() {
|
||||||
return usingNamedParameters;
|
return this.usingNamedParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(DataSource dataSource) throws Exception {
|
public void init(DataSource dataSource) throws Exception {
|
||||||
Assert.notNull(dataSource, "DataSource must not be null");
|
Assert.notNull(dataSource, "DataSource must not be null");
|
||||||
Assert.hasLength(selectClause, "selectClause must be specified");
|
Assert.hasLength(this.selectClause, "selectClause must be specified");
|
||||||
Assert.hasLength(fromClause, "fromClause must be specified");
|
Assert.hasLength(this.fromClause, "fromClause must be specified");
|
||||||
Assert.notEmpty(sortKeys, "sortKey must be specified");
|
Assert.notEmpty(this.sortKeys, "sortKey must be specified");
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT ").append(selectClause);
|
sql.append("SELECT ").append(this.selectClause);
|
||||||
sql.append(" FROM ").append(fromClause);
|
sql.append(" FROM ").append(this.fromClause);
|
||||||
if (whereClause != null) {
|
if (this.whereClause != null) {
|
||||||
sql.append(" WHERE ").append(whereClause);
|
sql.append(" WHERE ").append(this.whereClause);
|
||||||
}
|
}
|
||||||
List<String> namedParameters = new ArrayList<String>();
|
List<String> namedParameters = new ArrayList<>();
|
||||||
parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql.toString(), namedParameters);
|
this.parameterCount = JdbcParameterUtils
|
||||||
|
.countParameterPlaceholders(sql.toString(), namedParameters);
|
||||||
if (namedParameters.size() > 0) {
|
if (namedParameters.size() > 0) {
|
||||||
if (parameterCount != namedParameters.size()) {
|
if (this.parameterCount != namedParameters.size()) {
|
||||||
throw new InvalidDataAccessApiUsageException(
|
throw new InvalidDataAccessApiUsageException(
|
||||||
"You can't use both named parameters and classic \"?\" placeholders: " + sql);
|
"You can't use both named parameters and classic \"?\" placeholders: "
|
||||||
|
+ sql);
|
||||||
}
|
}
|
||||||
usingNamedParameters = true;
|
this.usingNamedParameters = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String removeKeyWord(String keyWord, String clause) {
|
private String removeKeyWord(String keyWord, String clause) {
|
||||||
String temp = clause.trim();
|
String temp = clause.trim();
|
||||||
String keyWordString = keyWord + " ";
|
String keyWordString = keyWord + " ";
|
||||||
if (temp.toLowerCase().startsWith(keyWordString) && temp.length() > keyWordString.length()) {
|
if (temp.toLowerCase().startsWith(keyWordString)
|
||||||
|
&& temp.length() > keyWordString.length()) {
|
||||||
return temp.substring(keyWordString.length());
|
return temp.substring(keyWordString.length());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -19,9 +19,10 @@ package org.springframework.cloud.task.repository.database.support;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IBM DB2 implementation of a {@link org.springframework.cloud.task.repository.database.PagingQueryProvider} using database
|
* IBM DB2 implementation of a
|
||||||
* specific features.
|
* {@link org.springframework.cloud.task.repository.database.PagingQueryProvider} using
|
||||||
*
|
* database specific features.
|
||||||
|
*
|
||||||
* @author Thomas Schuettel
|
* @author Thomas Schuettel
|
||||||
*/
|
*/
|
||||||
public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||||
@@ -30,15 +31,18 @@ public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
|||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
long offset = pageable.getOffset() + 1;
|
long offset = pageable.getOffset() + 1;
|
||||||
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
|
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
|
||||||
"TMP_ROW_NUM BETWEEN " + offset + " AND " + (offset + pageable.getPageSize()));
|
"TMP_ROW_NUM BETWEEN " + offset + " AND "
|
||||||
|
+ (offset + pageable.getPageSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateRowNumSqlQueryWithNesting(String selectClause, boolean remainingPageQuery,
|
private String generateRowNumSqlQueryWithNesting(String selectClause,
|
||||||
String rowNumClause) {
|
boolean remainingPageQuery, String rowNumClause) {
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause).append(", ")
|
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ")
|
||||||
|
.append(selectClause).append(", ")
|
||||||
.append("ROW_NUMBER() OVER() as TMP_ROW_NUM");
|
.append("ROW_NUMBER() OVER() as TMP_ROW_NUM");
|
||||||
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ").append(this.getFromClause());
|
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ")
|
||||||
|
.append(this.getFromClause());
|
||||||
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
||||||
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
|
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
|
||||||
sql.append(")) WHERE ").append(rowNumClause);
|
sql.append(")) WHERE ").append(rowNumClause);
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -29,8 +29,8 @@ public class H2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
|||||||
@Override
|
@Override
|
||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
String topClause = new StringBuilder().append("LIMIT ")
|
String topClause = new StringBuilder().append("LIMIT ")
|
||||||
.append(pageable.getOffset()).append(" ")
|
.append(pageable.getOffset()).append(" ").append(pageable.getPageSize())
|
||||||
.append(pageable.getPageSize()).toString();
|
.toString();
|
||||||
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
|
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -20,7 +20,8 @@ import org.springframework.cloud.task.repository.database.PagingQueryProvider;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HSQLDB implementation of a {@link PagingQueryProvider} using database specific features.
|
* HSQLDB implementation of a {@link PagingQueryProvider} using database specific
|
||||||
|
* features.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@@ -29,8 +30,8 @@ public class HsqlPagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
|||||||
@Override
|
@Override
|
||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
String topClause = new StringBuilder().append("LIMIT ")
|
String topClause = new StringBuilder().append("LIMIT ")
|
||||||
.append(pageable.getOffset()).append(" ")
|
.append(pageable.getOffset()).append(" ").append(pageable.getPageSize())
|
||||||
.append(pageable.getPageSize()).toString();
|
.toString();
|
||||||
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
|
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -25,11 +25,12 @@ import org.springframework.data.domain.Pageable;
|
|||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class MySqlPagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
public class MySqlPagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
String topClause = new StringBuilder().append("LIMIT ")
|
String topClause = new StringBuilder().append("LIMIT ")
|
||||||
.append(pageable.getOffset()).append(", ")
|
.append(pageable.getOffset()).append(", ").append(pageable.getPageSize())
|
||||||
.append(pageable.getPageSize()).toString();
|
.toString();
|
||||||
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, topClause);
|
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, topClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -20,7 +20,8 @@ import org.springframework.cloud.task.repository.database.PagingQueryProvider;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Oracle implementation of a {@link PagingQueryProvider} using database specific features.
|
* Oracle implementation of a {@link PagingQueryProvider} using database specific
|
||||||
|
* features.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@@ -28,22 +29,24 @@ public class OraclePagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
long offset = pageable.getOffset()+1;
|
long offset = pageable.getOffset() + 1;
|
||||||
return generateRowNumSqlQueryWithNesting(getSelectClause(), false, "TMP_ROW_NUM >= "
|
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
|
||||||
+ offset + " AND TMP_ROW_NUM < " + (offset+pageable.getPageSize()));
|
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < "
|
||||||
|
+ (offset + pageable.getPageSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateRowNumSqlQueryWithNesting(String selectClause,
|
private String generateRowNumSqlQueryWithNesting(String selectClause,
|
||||||
boolean remainingPageQuery,
|
boolean remainingPageQuery, String rowNumClause) {
|
||||||
String rowNumClause) {
|
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause)
|
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ")
|
||||||
.append(", ").append("ROWNUM as TMP_ROW_NUM");
|
.append(selectClause).append(", ").append("ROWNUM as TMP_ROW_NUM");
|
||||||
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ").append(this.getFromClause());
|
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ")
|
||||||
|
.append(this.getFromClause());
|
||||||
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
||||||
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
|
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
|
||||||
sql.append(")) WHERE ").append(rowNumClause);
|
sql.append(")) WHERE ").append(rowNumClause);
|
||||||
|
|
||||||
return sql.toString();
|
return sql.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -20,7 +20,8 @@ import org.springframework.cloud.task.repository.database.PagingQueryProvider;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Postgres implementation of a {@link PagingQueryProvider} using database specific features.
|
* Postgres implementation of a {@link PagingQueryProvider} using database specific
|
||||||
|
* features.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
@@ -28,9 +29,10 @@ public class PostgresPagingQueryProvider extends AbstractSqlPagingQueryProvider
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
String limitClause = new StringBuilder().append("LIMIT ").
|
String limitClause = new StringBuilder().append("LIMIT ")
|
||||||
append(pageable.getPageSize()).append(" OFFSET ").
|
.append(pageable.getPageSize()).append(" OFFSET ")
|
||||||
append(pageable.getOffset()).toString();
|
.append(pageable.getOffset()).toString();
|
||||||
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, limitClause);
|
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, limitClause);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -16,17 +16,6 @@
|
|||||||
|
|
||||||
package org.springframework.cloud.task.repository.database.support;
|
package org.springframework.cloud.task.repository.database.support;
|
||||||
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2AS400;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2VSE;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2ZOS;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.HSQL;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.H2;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.MYSQL;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.ORACLE;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.POSTGRES;
|
|
||||||
import static org.springframework.cloud.task.repository.support.DatabaseType.SQLSERVER;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -40,14 +29,26 @@ import org.springframework.jdbc.support.MetaDataAccessException;
|
|||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2AS400;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2VSE;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.DB2ZOS;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.H2;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.HSQL;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.MYSQL;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.ORACLE;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.POSTGRES;
|
||||||
|
import static org.springframework.cloud.task.repository.support.DatabaseType.SQLSERVER;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory bean for {@link PagingQueryProvider} interface. The database type
|
* Factory bean for {@link PagingQueryProvider} interface. The database type will be
|
||||||
* will be determined from the data source if not provided explicitly. Valid
|
* determined from the data source if not provided explicitly. Valid types are given by
|
||||||
* types are given by the {@link DatabaseType} enum.
|
* the {@link DatabaseType} enum.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQueryProvider> {
|
public class SqlPagingQueryProviderFactoryBean
|
||||||
|
implements FactoryBean<PagingQueryProvider> {
|
||||||
|
|
||||||
private DataSource dataSource;
|
private DataSource dataSource;
|
||||||
|
|
||||||
@@ -61,20 +62,19 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
|
|||||||
|
|
||||||
private Map<String, Order> sortKeys;
|
private Map<String, Order> sortKeys;
|
||||||
|
|
||||||
private Map<DatabaseType, AbstractSqlPagingQueryProvider> providers = new HashMap<DatabaseType, AbstractSqlPagingQueryProvider>();
|
private Map<DatabaseType, AbstractSqlPagingQueryProvider> providers = new HashMap<>();
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
providers.put(HSQL, new HsqlPagingQueryProvider());
|
this.providers.put(HSQL, new HsqlPagingQueryProvider());
|
||||||
providers.put(H2, new H2PagingQueryProvider());
|
this.providers.put(H2, new H2PagingQueryProvider());
|
||||||
providers.put(MYSQL, new MySqlPagingQueryProvider());
|
this.providers.put(MYSQL, new MySqlPagingQueryProvider());
|
||||||
providers.put(POSTGRES, new PostgresPagingQueryProvider());
|
this.providers.put(POSTGRES, new PostgresPagingQueryProvider());
|
||||||
providers.put(ORACLE, new OraclePagingQueryProvider());
|
this.providers.put(ORACLE, new OraclePagingQueryProvider());
|
||||||
providers.put(SQLSERVER, new SqlServerPagingQueryProvider());
|
this.providers.put(SQLSERVER, new SqlServerPagingQueryProvider());
|
||||||
providers.put(DB2, new Db2PagingQueryProvider());
|
this.providers.put(DB2, new Db2PagingQueryProvider());
|
||||||
providers.put(DB2VSE, new Db2PagingQueryProvider());
|
this.providers.put(DB2VSE, new Db2PagingQueryProvider());
|
||||||
providers.put(DB2ZOS, new Db2PagingQueryProvider());
|
this.providers.put(DB2ZOS, new Db2PagingQueryProvider());
|
||||||
providers.put(DB2AS400, new Db2PagingQueryProvider());
|
this.providers.put(DB2AS400, new Db2PagingQueryProvider());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,8 +124,8 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a {@link PagingQueryProvider} instance using the provided properties
|
* Get a {@link PagingQueryProvider} instance using the provided properties and
|
||||||
* and appropriate for the given database type.
|
* appropriate for the given database type.
|
||||||
*
|
*
|
||||||
* @see FactoryBean#getObject()
|
* @see FactoryBean#getObject()
|
||||||
*/
|
*/
|
||||||
@@ -134,24 +134,28 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
|
|||||||
|
|
||||||
DatabaseType type;
|
DatabaseType type;
|
||||||
try {
|
try {
|
||||||
type = databaseType != null ? DatabaseType.valueOf(databaseType.toUpperCase()) : DatabaseType
|
type = this.databaseType != null
|
||||||
.fromMetaData(dataSource);
|
? DatabaseType.valueOf(this.databaseType.toUpperCase())
|
||||||
|
: DatabaseType.fromMetaData(this.dataSource);
|
||||||
}
|
}
|
||||||
catch (MetaDataAccessException e) {
|
catch (MetaDataAccessException e) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Could not inspect meta data for database type. You have to supply it explicitly.", e);
|
"Could not inspect meta data for database type. You have to supply it explicitly.",
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
|
|
||||||
AbstractSqlPagingQueryProvider provider = providers.get(type);
|
AbstractSqlPagingQueryProvider provider = this.providers.get(type);
|
||||||
Assert.state(provider != null, "Should not happen: missing PagingQueryProvider for DatabaseType=" + type);
|
Assert.state(provider != null,
|
||||||
|
"Should not happen: missing PagingQueryProvider for DatabaseType="
|
||||||
|
+ type);
|
||||||
|
|
||||||
provider.setFromClause(fromClause);
|
provider.setFromClause(this.fromClause);
|
||||||
provider.setWhereClause(whereClause);
|
provider.setWhereClause(this.whereClause);
|
||||||
provider.setSortKeys(sortKeys);
|
provider.setSortKeys(this.sortKeys);
|
||||||
if (StringUtils.hasText(selectClause)) {
|
if (StringUtils.hasText(this.selectClause)) {
|
||||||
provider.setSelectClause(selectClause);
|
provider.setSelectClause(this.selectClause);
|
||||||
}
|
}
|
||||||
provider.init(dataSource);
|
provider.init(this.dataSource);
|
||||||
|
|
||||||
return provider;
|
return provider;
|
||||||
|
|
||||||
@@ -176,4 +180,5 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
|
|||||||
public boolean isSingleton() {
|
public boolean isSingleton() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -21,28 +21,29 @@ import java.util.Map;
|
|||||||
import org.springframework.batch.item.database.Order;
|
import org.springframework.batch.item.database.Order;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class that generates the actual SQL statements used by query
|
* Utility class that generates the actual SQL statements used by query providers.
|
||||||
* providers.
|
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class SqlPagingQueryUtils {
|
public final class SqlPagingQueryUtils {
|
||||||
|
|
||||||
private SqlPagingQueryUtils(){}
|
private SqlPagingQueryUtils() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate SQL query string using a LIMIT clause
|
* Generate SQL query string using a LIMIT clause.
|
||||||
*
|
* @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation
|
||||||
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
|
* specifics
|
||||||
* implementation specifics
|
|
||||||
* @param limitClause the implementation specific top clause to be used
|
* @param limitClause the implementation specific top clause to be used
|
||||||
* @return the generated query
|
* @return the generated query
|
||||||
*/
|
*/
|
||||||
public static String generateLimitJumpToQuery(AbstractSqlPagingQueryProvider provider, String limitClause) {
|
public static String generateLimitJumpToQuery(AbstractSqlPagingQueryProvider provider,
|
||||||
|
String limitClause) {
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT ").append(provider.getSelectClause());
|
sql.append("SELECT ").append(provider.getSelectClause());
|
||||||
sql.append(" FROM ").append(provider.getFromClause());
|
sql.append(" FROM ").append(provider.getFromClause());
|
||||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
sql.append(provider.getWhereClause() == null ? ""
|
||||||
|
: " WHERE " + provider.getWhereClause());
|
||||||
sql.append(" ORDER BY ").append(buildSortClause(provider));
|
sql.append(" ORDER BY ").append(buildSortClause(provider));
|
||||||
sql.append(" ").append(limitClause);
|
sql.append(" ").append(limitClause);
|
||||||
|
|
||||||
@@ -50,18 +51,20 @@ public class SqlPagingQueryUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate SQL query string using a TOP clause
|
* Generate SQL query string using a TOP clause.
|
||||||
*
|
* @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation
|
||||||
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
|
* specifics
|
||||||
* implementation specifics
|
|
||||||
* @param topClause the implementation specific top clause to be used
|
* @param topClause the implementation specific top clause to be used
|
||||||
* @return the generated query
|
* @return the generated query
|
||||||
*/
|
*/
|
||||||
public static String generateTopJumpToQuery(AbstractSqlPagingQueryProvider provider, String topClause) {
|
public static String generateTopJumpToQuery(AbstractSqlPagingQueryProvider provider,
|
||||||
|
String topClause) {
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT ").append(topClause).append(" ").append(provider.getSelectClause());
|
sql.append("SELECT ").append(topClause).append(" ")
|
||||||
|
.append(provider.getSelectClause());
|
||||||
sql.append(" FROM ").append(provider.getFromClause());
|
sql.append(" FROM ").append(provider.getFromClause());
|
||||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
sql.append(provider.getWhereClause() == null ? ""
|
||||||
|
: " WHERE " + provider.getWhereClause());
|
||||||
sql.append(" ORDER BY ").append(buildSortClause(provider));
|
sql.append(" ORDER BY ").append(buildSortClause(provider));
|
||||||
|
|
||||||
return sql.toString();
|
return sql.toString();
|
||||||
@@ -69,13 +72,12 @@ public class SqlPagingQueryUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates WHERE clause for queries that require sub selects.
|
* Generates WHERE clause for queries that require sub selects.
|
||||||
*
|
|
||||||
* @param provider the paging query provider that will provide the base where clause
|
* @param provider the paging query provider that will provide the base where clause
|
||||||
* @param remainingPageQuery if true assumes more will be appended to where clause
|
* @param remainingPageQuery if true assumes more will be appended to where clause
|
||||||
* @param sql the sql statement to be appended.
|
* @param sql the sql statement to be appended.
|
||||||
*/
|
*/
|
||||||
public static void buildWhereClause( AbstractSqlPagingQueryProvider provider,
|
public static void buildWhereClause(AbstractSqlPagingQueryProvider provider,
|
||||||
boolean remainingPageQuery, StringBuilder sql) {
|
boolean remainingPageQuery, StringBuilder sql) {
|
||||||
if (remainingPageQuery) {
|
if (remainingPageQuery) {
|
||||||
sql.append(" WHERE ");
|
sql.append(" WHERE ");
|
||||||
if (provider.getWhereClause() != null) {
|
if (provider.getWhereClause() != null) {
|
||||||
@@ -85,15 +87,15 @@ public class SqlPagingQueryUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
sql.append(provider.getWhereClause() == null ? ""
|
||||||
|
: " WHERE " + provider.getWhereClause());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates ORDER BY attributes based on the sort keys.
|
* Generates ORDER BY attributes based on the sort keys.
|
||||||
*
|
* @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation
|
||||||
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
|
* specifics
|
||||||
* implementation specifics
|
|
||||||
* @return a String that can be appended to an ORDER BY clause.
|
* @return a String that can be appended to an ORDER BY clause.
|
||||||
*/
|
*/
|
||||||
public static String buildSortClause(AbstractSqlPagingQueryProvider provider) {
|
public static String buildSortClause(AbstractSqlPagingQueryProvider provider) {
|
||||||
@@ -102,7 +104,6 @@ public class SqlPagingQueryUtils {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates ORDER BY attributes based on the sort keys.
|
* Generates ORDER BY attributes based on the sort keys.
|
||||||
*
|
|
||||||
* @param sortKeys generates order by clause from map
|
* @param sortKeys generates order by clause from map
|
||||||
* @return a String that can be appended to an ORDER BY clause.
|
* @return a String that can be appended to an ORDER BY clause.
|
||||||
*/
|
*/
|
||||||
@@ -117,7 +118,7 @@ public class SqlPagingQueryUtils {
|
|||||||
|
|
||||||
builder.append(sortKey.getKey());
|
builder.append(sortKey.getKey());
|
||||||
|
|
||||||
if(sortKey.getValue() != null && sortKey.getValue() == Order.DESCENDING) {
|
if (sortKey.getValue() != null && sortKey.getValue() == Order.DESCENDING) {
|
||||||
builder.append(" DESC");
|
builder.append(" DESC");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -127,4 +128,5 @@ public class SqlPagingQueryUtils {
|
|||||||
|
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -20,31 +20,33 @@ import org.springframework.cloud.task.repository.database.PagingQueryProvider;
|
|||||||
import org.springframework.data.domain.Pageable;
|
import org.springframework.data.domain.Pageable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sql Server implementation of a {@link PagingQueryProvider} using database specific features.
|
* Sql Server implementation of a {@link PagingQueryProvider} using database specific
|
||||||
|
* features.
|
||||||
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider{
|
public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getPageQuery(Pageable pageable) {
|
public String getPageQuery(Pageable pageable) {
|
||||||
long offset = pageable.getOffset()+1;
|
long offset = pageable.getOffset() + 1;
|
||||||
return generateRowNumSqlQueryWithNesting(getSelectClause(), false, "TMP_ROW_NUM >= "
|
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
|
||||||
+ offset + " AND TMP_ROW_NUM < " + (offset+pageable.getPageSize()));
|
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < "
|
||||||
|
+ (offset + pageable.getPageSize()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateRowNumSqlQueryWithNesting(String selectClause,
|
private String generateRowNumSqlQueryWithNesting(String selectClause,
|
||||||
boolean remainingPageQuery,
|
boolean remainingPageQuery, String rowNumClause) {
|
||||||
String rowNumClause) {
|
|
||||||
StringBuilder sql = new StringBuilder();
|
StringBuilder sql = new StringBuilder();
|
||||||
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause)
|
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ")
|
||||||
.append(", ").append("ROW_NUMBER() OVER (ORDER BY ")
|
.append(selectClause).append(", ").append("ROW_NUMBER() OVER (ORDER BY ")
|
||||||
.append(SqlPagingQueryUtils.buildSortClause(this))
|
.append(SqlPagingQueryUtils.buildSortClause(this))
|
||||||
.append(") AS TMP_ROW_NUM ")
|
.append(") AS TMP_ROW_NUM ").append(" FROM ").append(getFromClause());
|
||||||
.append(" FROM ").append(getFromClause());
|
|
||||||
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
||||||
sql.append(") TASK_EXECUTION_PAGE ");
|
sql.append(") TASK_EXECUTION_PAGE ");
|
||||||
sql.append(" WHERE ").append(rowNumClause);
|
sql.append(" WHERE ").append(rowNumClause);
|
||||||
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
|
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
|
||||||
return sql.toString();
|
return sql.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -25,63 +25,107 @@ import org.springframework.jdbc.support.JdbcUtils;
|
|||||||
import org.springframework.jdbc.support.MetaDataAccessException;
|
import org.springframework.jdbc.support.MetaDataAccessException;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum representing a database type, such as DB2 or oracle. The type also
|
* Enum representing a database type, such as DB2 or oracle. The type also contains a
|
||||||
* contains a product name, which is expected to be the same as the product name
|
* product name, which is expected to be the same as the product name provided by the
|
||||||
* provided by the database driver's metadata.
|
* database driver's metadata.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public enum DatabaseType {
|
public enum DatabaseType {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* HSQL DB.
|
||||||
|
*/
|
||||||
HSQL("HSQL Database Engine"),
|
HSQL("HSQL Database Engine"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* H2 DB.
|
||||||
|
*/
|
||||||
H2("H2"),
|
H2("H2"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Oracle DB.
|
||||||
|
*/
|
||||||
ORACLE("Oracle"),
|
ORACLE("Oracle"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MySQL DB.
|
||||||
|
*/
|
||||||
MYSQL("MySQL"),
|
MYSQL("MySQL"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PostgreSQL DB.
|
||||||
|
*/
|
||||||
POSTGRES("PostgreSQL"),
|
POSTGRES("PostgreSQL"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Microsoft SQL Server DB.
|
||||||
|
*/
|
||||||
SQLSERVER("Microsoft SQL Server"),
|
SQLSERVER("Microsoft SQL Server"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB2 DB.
|
||||||
|
*/
|
||||||
DB2("DB2"),
|
DB2("DB2"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB2VSE DB.
|
||||||
|
*/
|
||||||
DB2VSE("DB2VSE"),
|
DB2VSE("DB2VSE"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB2ZOS DB.
|
||||||
|
*/
|
||||||
DB2ZOS("DB2ZOS"),
|
DB2ZOS("DB2ZOS"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DB2AS400 DB.
|
||||||
|
*/
|
||||||
DB2AS400("DB2AS400");
|
DB2AS400("DB2AS400");
|
||||||
|
|
||||||
private static final Map<String, DatabaseType> dbNameMap;
|
private static final Map<String, DatabaseType> dbNameMap;
|
||||||
|
|
||||||
|
static {
|
||||||
|
dbNameMap = new HashMap<>();
|
||||||
|
for (DatabaseType type : values()) {
|
||||||
|
dbNameMap.put(type.getProductName(), type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private final String productName;
|
private final String productName;
|
||||||
|
|
||||||
DatabaseType(String productName) {
|
DatabaseType(String productName) {
|
||||||
this.productName = productName;
|
this.productName = productName;
|
||||||
}
|
}
|
||||||
|
|
||||||
static{
|
|
||||||
dbNameMap = new HashMap<String, DatabaseType>();
|
|
||||||
for(DatabaseType type: values()){
|
|
||||||
dbNameMap.put(type.getProductName(), type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method that pulls a database product name from the DataSource's metadata.
|
* Convenience method that pulls a database product name from the DataSource's
|
||||||
*
|
* metadata.
|
||||||
* @param dataSource the datasource used to extact metadata.
|
* @param dataSource the datasource used to extact metadata.
|
||||||
* @return DatabaseType The database type associated with the datasource.
|
* @return DatabaseType The database type associated with the datasource.
|
||||||
* @throws MetaDataAccessException thrown if failure occurs on metadata lookup.
|
* @throws MetaDataAccessException thrown if failure occurs on metadata lookup.
|
||||||
*/
|
*/
|
||||||
public static DatabaseType fromMetaData(DataSource dataSource) throws MetaDataAccessException {
|
public static DatabaseType fromMetaData(DataSource dataSource)
|
||||||
String databaseProductName =
|
throws MetaDataAccessException {
|
||||||
JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductName").toString();
|
String databaseProductName = JdbcUtils
|
||||||
if (StringUtils.hasText(databaseProductName) && !databaseProductName.equals("DB2/Linux") && databaseProductName.startsWith("DB2")) {
|
.extractDatabaseMetaData(dataSource, "getDatabaseProductName").toString();
|
||||||
String databaseProductVersion =
|
if (StringUtils.hasText(databaseProductName)
|
||||||
JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion").toString();
|
&& !databaseProductName.equals("DB2/Linux")
|
||||||
|
&& databaseProductName.startsWith("DB2")) {
|
||||||
|
String databaseProductVersion = JdbcUtils
|
||||||
|
.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion")
|
||||||
|
.toString();
|
||||||
if (databaseProductVersion.startsWith("ARI")) {
|
if (databaseProductVersion.startsWith("ARI")) {
|
||||||
databaseProductName = "DB2VSE";
|
databaseProductName = "DB2VSE";
|
||||||
}
|
}
|
||||||
else if (databaseProductVersion.startsWith("DSN")) {
|
else if (databaseProductVersion.startsWith("DSN")) {
|
||||||
databaseProductName = "DB2ZOS";
|
databaseProductName = "DB2ZOS";
|
||||||
}
|
}
|
||||||
else if (databaseProductName.indexOf("AS") != -1 && (databaseProductVersion.startsWith("QSQ") ||
|
else if (databaseProductName.indexOf("AS") != -1
|
||||||
databaseProductVersion.substring(databaseProductVersion.indexOf('V')).matches("V\\dR\\d[mM]\\d"))) {
|
&& (databaseProductVersion.startsWith("QSQ") || databaseProductVersion
|
||||||
|
.substring(databaseProductVersion.indexOf('V'))
|
||||||
|
.matches("V\\dR\\d[mM]\\d"))) {
|
||||||
databaseProductName = "DB2AS400";
|
databaseProductName = "DB2AS400";
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -96,23 +140,22 @@ public enum DatabaseType {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Static method to obtain a DatabaseType from the provided product name.
|
* Static method to obtain a DatabaseType from the provided product name.
|
||||||
*
|
|
||||||
* @param productName the name of the database.
|
* @param productName the name of the database.
|
||||||
* @return DatabaseType for given product name.
|
* @return DatabaseType for given product name.
|
||||||
* @throws IllegalArgumentException if none is found.
|
* @throws IllegalArgumentException if none is found.
|
||||||
*/
|
*/
|
||||||
public static DatabaseType fromProductName(String productName){
|
public static DatabaseType fromProductName(String productName) {
|
||||||
if(!dbNameMap.containsKey(productName)){
|
if (!dbNameMap.containsKey(productName)) {
|
||||||
throw new IllegalArgumentException("DatabaseType not found for product name: [" +
|
throw new IllegalArgumentException(
|
||||||
productName + "]");
|
"DatabaseType not found for product name: [" + productName + "]");
|
||||||
}
|
}
|
||||||
else{
|
else {
|
||||||
return dbNameMap.get(productName);
|
return dbNameMap.get(productName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getProductName() {
|
private String getProductName() {
|
||||||
return productName;
|
return this.productName;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -39,7 +39,8 @@ public class SimpleTaskExplorer implements TaskExplorer {
|
|||||||
private TaskExecutionDao taskExecutionDao;
|
private TaskExecutionDao taskExecutionDao;
|
||||||
|
|
||||||
public SimpleTaskExplorer(TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean) {
|
public SimpleTaskExplorer(TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean) {
|
||||||
Assert.notNull(taskExecutionDaoFactoryBean, "taskExecutionDaoFactoryBean must not be null");
|
Assert.notNull(taskExecutionDaoFactoryBean,
|
||||||
|
"taskExecutionDaoFactoryBean must not be null");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.taskExecutionDao = taskExecutionDaoFactoryBean.getObject();
|
this.taskExecutionDao = taskExecutionDaoFactoryBean.getObject();
|
||||||
@@ -51,62 +52,64 @@ public class SimpleTaskExplorer implements TaskExplorer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution getTaskExecution(long executionId) {
|
public TaskExecution getTaskExecution(long executionId) {
|
||||||
return taskExecutionDao.getTaskExecution(executionId);
|
return this.taskExecutionDao.getTaskExecution(executionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
|
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
|
||||||
return taskExecutionDao.findRunningTaskExecutions(taskName, pageable);
|
Pageable pageable) {
|
||||||
|
return this.taskExecutionDao.findRunningTaskExecutions(taskName, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> getTaskNames() {
|
public List<String> getTaskNames() {
|
||||||
return taskExecutionDao.getTaskNames();
|
return this.taskExecutionDao.getTaskNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTaskExecutionCountByTaskName(String taskName) {
|
public long getTaskExecutionCountByTaskName(String taskName) {
|
||||||
return taskExecutionDao.getTaskExecutionCountByTaskName(taskName);
|
return this.taskExecutionDao.getTaskExecutionCountByTaskName(taskName);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getTaskExecutionCount() {
|
public long getTaskExecutionCount() {
|
||||||
return taskExecutionDao.getTaskExecutionCount();
|
return this.taskExecutionDao.getTaskExecutionCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long getRunningTaskExecutionCount() {
|
public long getRunningTaskExecutionCount() {
|
||||||
return taskExecutionDao.getRunningTaskExecutionCount();
|
return this.taskExecutionDao.getRunningTaskExecutionCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
|
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
|
||||||
return taskExecutionDao.findTaskExecutionsByName(taskName, pageable);
|
Pageable pageable) {
|
||||||
|
return this.taskExecutionDao.findTaskExecutionsByName(taskName, pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Page<TaskExecution> findAll(Pageable pageable) {
|
public Page<TaskExecution> findAll(Pageable pageable) {
|
||||||
return taskExecutionDao.findAll(pageable);
|
return this.taskExecutionDao.findAll(pageable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
|
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
|
||||||
return taskExecutionDao.getTaskExecutionIdByJobExecutionId(jobExecutionId);
|
return this.taskExecutionDao.getTaskExecutionIdByJobExecutionId(jobExecutionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
||||||
return taskExecutionDao.getJobExecutionIdsByTaskExecutionId(taskExecutionId);
|
return this.taskExecutionDao.getJobExecutionIdsByTaskExecutionId(taskExecutionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames) {
|
public List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames) {
|
||||||
return taskExecutionDao.getLatestTaskExecutionsByTaskNames(taskNames);
|
return this.taskExecutionDao.getLatestTaskExecutionsByTaskNames(taskNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
|
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
|
||||||
return taskExecutionDao.getLatestTaskExecutionForTaskName(taskName);
|
return this.taskExecutionDao.getLatestTaskExecutionForTaskName(taskName);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.repository.support;
|
package org.springframework.cloud.task.repository.support;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
@@ -23,11 +24,11 @@ import org.springframework.context.ApplicationContextAware;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple implementation of the {@link TaskNameResolver} interface. Names the task based
|
* Simple implementation of the {@link TaskNameResolver} interface. Names the task based
|
||||||
* on the following order of precidence:
|
* on the following order of precidence:
|
||||||
* <ol>
|
* <ol>
|
||||||
* <li>A configured property <code>spring.cloud.task.name</code></li>
|
* <li>A configured property <code>spring.cloud.task.name</code></li>
|
||||||
* <li>The {@link ApplicationContext}'s id.</li>
|
* <li>The {@link ApplicationContext}'s id.</li>
|
||||||
* </ol>
|
* </ol>
|
||||||
*
|
*
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
@@ -45,17 +46,19 @@ public class SimpleTaskNameResolver implements TaskNameResolver, ApplicationCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
public void setApplicationContext(ApplicationContext applicationContext)
|
||||||
|
throws BeansException {
|
||||||
this.context = applicationContext;
|
this.context = applicationContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getTaskName() {
|
public String getTaskName() {
|
||||||
if(StringUtils.hasText(configuredName)) {
|
if (StringUtils.hasText(this.configuredName)) {
|
||||||
return configuredName;
|
return this.configuredName;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return context.getId().replace(":", "_");
|
return this.context.getId().replace(":", "_");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2017 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -31,15 +31,27 @@ import org.springframework.util.Assert;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Records the task execution information to the log and to TaskExecutionDao provided.
|
* Records the task execution information to the log and to TaskExecutionDao provided.
|
||||||
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class SimpleTaskRepository implements TaskRepository {
|
public class SimpleTaskRepository implements TaskRepository {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max exit message size.
|
||||||
|
*/
|
||||||
public static final int MAX_EXIT_MESSAGE_SIZE = 2500;
|
public static final int MAX_EXIT_MESSAGE_SIZE = 2500;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max task name size.
|
||||||
|
*/
|
||||||
public static final int MAX_TASK_NAME_SIZE = 100;
|
public static final int MAX_TASK_NAME_SIZE = 100;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Max error message size.
|
||||||
|
*/
|
||||||
public static final int MAX_ERROR_MESSAGE_SIZE = 2500;
|
public static final int MAX_ERROR_MESSAGE_SIZE = 2500;
|
||||||
|
|
||||||
private static final Log logger = LogFactory.getLog(SimpleTaskRepository.class);
|
private static final Log logger = LogFactory.getLog(SimpleTaskRepository.class);
|
||||||
|
|
||||||
private TaskExecutionDao taskExecutionDao;
|
private TaskExecutionDao taskExecutionDao;
|
||||||
|
|
||||||
@@ -53,63 +65,63 @@ public class SimpleTaskRepository implements TaskRepository {
|
|||||||
|
|
||||||
private int maxErrorMessageSize = MAX_ERROR_MESSAGE_SIZE;
|
private int maxErrorMessageSize = MAX_ERROR_MESSAGE_SIZE;
|
||||||
|
|
||||||
public SimpleTaskRepository(FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean){
|
public SimpleTaskRepository(
|
||||||
Assert.notNull(taskExecutionDaoFactoryBean, "A FactoryBean that provides a TaskExecutionDao is required");
|
FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean) {
|
||||||
|
Assert.notNull(taskExecutionDaoFactoryBean,
|
||||||
|
"A FactoryBean that provides a TaskExecutionDao is required");
|
||||||
|
|
||||||
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
|
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SimpleTaskRepository(FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean, Integer maxExitMessageSize,
|
public SimpleTaskRepository(FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean,
|
||||||
Integer maxTaskNameSize, Integer maxErrorMessageSize){
|
Integer maxExitMessageSize, Integer maxTaskNameSize,
|
||||||
Assert.notNull(taskExecutionDaoFactoryBean, "A FactoryBean that provides a TaskExecutionDao is required");
|
Integer maxErrorMessageSize) {
|
||||||
if(maxTaskNameSize != null) {
|
Assert.notNull(taskExecutionDaoFactoryBean,
|
||||||
|
"A FactoryBean that provides a TaskExecutionDao is required");
|
||||||
|
if (maxTaskNameSize != null) {
|
||||||
this.maxTaskNameSize = maxTaskNameSize;
|
this.maxTaskNameSize = maxTaskNameSize;
|
||||||
}
|
}
|
||||||
if(maxExitMessageSize != null) {
|
if (maxExitMessageSize != null) {
|
||||||
this.maxExitMessageSize = maxExitMessageSize;
|
this.maxExitMessageSize = maxExitMessageSize;
|
||||||
}
|
}
|
||||||
if(maxErrorMessageSize != null) {
|
if (maxErrorMessageSize != null) {
|
||||||
this.maxErrorMessageSize = maxErrorMessageSize;
|
this.maxErrorMessageSize = maxErrorMessageSize;
|
||||||
}
|
}
|
||||||
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
|
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage) {
|
public TaskExecution completeTaskExecution(long executionId, Integer exitCode,
|
||||||
|
Date endTime, String exitMessage) {
|
||||||
return completeTaskExecution(executionId, exitCode, endTime, exitMessage, null);
|
return completeTaskExecution(executionId, exitCode, endTime, exitMessage, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
public TaskExecution completeTaskExecution(long executionId, Integer exitCode,
|
||||||
String exitMessage, String errorMessage) {
|
Date endTime, String exitMessage, String errorMessage) {
|
||||||
initialize();
|
initialize();
|
||||||
|
|
||||||
validateCompletedTaskExitInformation(executionId, exitCode, endTime);
|
validateCompletedTaskExitInformation(executionId, exitCode, endTime);
|
||||||
exitMessage = trimMessage(exitMessage, this.maxExitMessageSize);
|
exitMessage = trimMessage(exitMessage, this.maxExitMessageSize);
|
||||||
errorMessage = trimMessage(errorMessage, this.maxErrorMessageSize);
|
errorMessage = trimMessage(errorMessage, this.maxErrorMessageSize);
|
||||||
taskExecutionDao.completeTaskExecution(executionId, exitCode, endTime, exitMessage, errorMessage);
|
this.taskExecutionDao.completeTaskExecution(executionId, exitCode, endTime,
|
||||||
logger.debug("Updating: TaskExecution with executionId="+executionId
|
exitMessage, errorMessage);
|
||||||
+ " with the following {"
|
logger.debug("Updating: TaskExecution with executionId=" + executionId
|
||||||
+ "exitCode=" + exitCode
|
+ " with the following {" + "exitCode=" + exitCode + ", endTime="
|
||||||
+ ", endTime=" + endTime
|
+ endTime + ", exitMessage='" + exitMessage + '\'' + ", errorMessage='"
|
||||||
+ ", exitMessage='" + exitMessage + '\''
|
+ errorMessage + '\'' + '}');
|
||||||
+ ", errorMessage='" + errorMessage + '\''
|
|
||||||
+ '}');
|
|
||||||
|
|
||||||
return taskExecutionDao.getTaskExecution(executionId);
|
return this.taskExecutionDao.getTaskExecution(executionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution createTaskExecution(TaskExecution taskExecution) {
|
public TaskExecution createTaskExecution(TaskExecution taskExecution) {
|
||||||
initialize();
|
initialize();
|
||||||
validateCreateInformation(taskExecution);
|
validateCreateInformation(taskExecution);
|
||||||
TaskExecution daoTaskExecution =
|
TaskExecution daoTaskExecution = this.taskExecutionDao.createTaskExecution(
|
||||||
taskExecutionDao.createTaskExecution(
|
taskExecution.getTaskName(), taskExecution.getStartTime(),
|
||||||
taskExecution.getTaskName(),
|
taskExecution.getArguments(), taskExecution.getExternalExecutionId(),
|
||||||
taskExecution.getStartTime(),
|
taskExecution.getParentExecutionId());
|
||||||
taskExecution.getArguments(),
|
|
||||||
taskExecution.getExternalExecutionId(),
|
|
||||||
taskExecution.getParentExecutionId());
|
|
||||||
logger.debug("Creating: " + taskExecution.toString());
|
logger.debug("Creating: " + taskExecution.toString());
|
||||||
return daoTaskExecution;
|
return daoTaskExecution;
|
||||||
}
|
}
|
||||||
@@ -117,21 +129,20 @@ public class SimpleTaskRepository implements TaskRepository {
|
|||||||
@Override
|
@Override
|
||||||
public TaskExecution createTaskExecution(String name) {
|
public TaskExecution createTaskExecution(String name) {
|
||||||
initialize();
|
initialize();
|
||||||
TaskExecution taskExecution =
|
TaskExecution taskExecution = this.taskExecutionDao.createTaskExecution(name,
|
||||||
taskExecutionDao.createTaskExecution(name, null,
|
null, Collections.<String>emptyList(), null);
|
||||||
Collections.<String>emptyList(), null);
|
|
||||||
logger.debug("Creating: " + taskExecution.toString());
|
logger.debug("Creating: " + taskExecution.toString());
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution createTaskExecution() {
|
public TaskExecution createTaskExecution() {
|
||||||
return createTaskExecution((String)null);
|
return createTaskExecution((String) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecution startTaskExecution(long executionid, String taskName, Date startTime, List<String> arguments,
|
public TaskExecution startTaskExecution(long executionid, String taskName,
|
||||||
String externalExecutionId) {
|
Date startTime, List<String> arguments, String externalExecutionId) {
|
||||||
return startTaskExecution(executionid, taskName, startTime, arguments,
|
return startTaskExecution(executionid, taskName, startTime, arguments,
|
||||||
externalExecutionId, null);
|
externalExecutionId, null);
|
||||||
}
|
}
|
||||||
@@ -139,7 +150,7 @@ public class SimpleTaskRepository implements TaskRepository {
|
|||||||
@Override
|
@Override
|
||||||
public void updateExternalExecutionId(long executionid, String externalExecutionId) {
|
public void updateExternalExecutionId(long executionid, String externalExecutionId) {
|
||||||
initialize();
|
initialize();
|
||||||
taskExecutionDao.updateExternalExecutionId(executionid, externalExecutionId);
|
this.taskExecutionDao.updateExternalExecutionId(executionid, externalExecutionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -147,10 +158,9 @@ public class SimpleTaskRepository implements TaskRepository {
|
|||||||
Date startTime, List<String> arguments, String externalExecutionId,
|
Date startTime, List<String> arguments, String externalExecutionId,
|
||||||
Long parentExecutionId) {
|
Long parentExecutionId) {
|
||||||
initialize();
|
initialize();
|
||||||
TaskExecution taskExecution =
|
TaskExecution taskExecution = this.taskExecutionDao.startTaskExecution(
|
||||||
taskExecutionDao.startTaskExecution(executionid, taskName,
|
executionid, taskName, startTime, arguments, externalExecutionId,
|
||||||
startTime, arguments, externalExecutionId,
|
parentExecutionId);
|
||||||
parentExecutionId);
|
|
||||||
logger.debug("Starting: " + taskExecution.toString());
|
logger.debug("Starting: " + taskExecution.toString());
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
@@ -161,44 +171,47 @@ public class SimpleTaskRepository implements TaskRepository {
|
|||||||
*/
|
*/
|
||||||
public TaskExecutionDao getTaskExecutionDao() {
|
public TaskExecutionDao getTaskExecutionDao() {
|
||||||
initialize();
|
initialize();
|
||||||
return taskExecutionDao;
|
return this.taskExecutionDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
if(!initialized) {
|
if (!this.initialized) {
|
||||||
try {
|
try {
|
||||||
this.taskExecutionDao = this.taskExecutionDaoFactoryBean.getObject();
|
this.taskExecutionDao = this.taskExecutionDaoFactoryBean.getObject();
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
}
|
}
|
||||||
catch (Exception e) {
|
catch (Exception e) {
|
||||||
throw new IllegalStateException("Unable to create the TaskExecutionDao", e);
|
throw new IllegalStateException("Unable to create the TaskExecutionDao",
|
||||||
|
e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validate startTime and taskName are valid.
|
* Validate startTime and taskName are valid.
|
||||||
|
* @param taskExecution task execution to validate
|
||||||
*/
|
*/
|
||||||
private void validateCreateInformation(TaskExecution taskExecution) {
|
private void validateCreateInformation(TaskExecution taskExecution) {
|
||||||
Assert.notNull(taskExecution.getStartTime(), "TaskExecution start time cannot be null.");
|
Assert.notNull(taskExecution.getStartTime(),
|
||||||
|
"TaskExecution start time cannot be null.");
|
||||||
|
|
||||||
if (taskExecution.getTaskName() != null &&
|
if (taskExecution.getTaskName() != null
|
||||||
taskExecution.getTaskName().length() > this.maxTaskNameSize) {
|
&& taskExecution.getTaskName().length() > this.maxTaskNameSize) {
|
||||||
throw new IllegalArgumentException("TaskName length exceeds "
|
throw new IllegalArgumentException(
|
||||||
+ this.maxTaskNameSize + " characters");
|
"TaskName length exceeds " + this.maxTaskNameSize + " characters");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateCompletedTaskExitInformation(long executionId, Integer exitCode, Date endTime){
|
private void validateCompletedTaskExitInformation(long executionId, Integer exitCode,
|
||||||
|
Date endTime) {
|
||||||
Assert.notNull(exitCode, "exitCode should not be null");
|
Assert.notNull(exitCode, "exitCode should not be null");
|
||||||
Assert.isTrue(exitCode >= 0, "exit code must be greater than or equal to zero");
|
Assert.isTrue(exitCode >= 0, "exit code must be greater than or equal to zero");
|
||||||
Assert.notNull(endTime, "TaskExecution endTime cannot be null.");
|
Assert.notNull(endTime, "TaskExecution endTime cannot be null.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String trimMessage(String exitMessage, int maxSize){
|
private String trimMessage(String exitMessage, int maxSize) {
|
||||||
String result = exitMessage;
|
String result = exitMessage;
|
||||||
if(exitMessage != null &&
|
if (exitMessage != null && exitMessage.length() > maxSize) {
|
||||||
exitMessage.length() > maxSize) {
|
|
||||||
result = exitMessage.substring(0, maxSize);
|
result = exitMessage.substring(0, maxSize);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -215,4 +228,5 @@ public class SimpleTaskRepository implements TaskRepository {
|
|||||||
public void setMaxErrorMessageSize(int maxErrorMessageSize) {
|
public void setMaxErrorMessageSize(int maxErrorMessageSize) {
|
||||||
this.maxErrorMessageSize = maxErrorMessageSize;
|
this.maxErrorMessageSize = maxErrorMessageSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.repository.support;
|
package org.springframework.cloud.task.repository.support;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
@@ -43,7 +44,7 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
|||||||
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor will result in a Map based TaskExecutionDao. <b>This is only
|
* Default constructor will result in a Map based TaskExecutionDao. <b>This is only
|
||||||
* intended for testing purposes.</b>
|
* intended for testing purposes.</b>
|
||||||
*/
|
*/
|
||||||
public TaskExecutionDaoFactoryBean() {
|
public TaskExecutionDaoFactoryBean() {
|
||||||
@@ -51,7 +52,6 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link DataSource} to be used.
|
* {@link DataSource} to be used.
|
||||||
*
|
|
||||||
* @param dataSource {@link DataSource} to be used.
|
* @param dataSource {@link DataSource} to be used.
|
||||||
* @param tablePrefix the table prefix to use for this dao.
|
* @param tablePrefix the table prefix to use for this dao.
|
||||||
*/
|
*/
|
||||||
@@ -63,7 +63,6 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link DataSource} to be used.
|
* {@link DataSource} to be used.
|
||||||
*
|
|
||||||
* @param dataSource {@link DataSource} to be used.
|
* @param dataSource {@link DataSource} to be used.
|
||||||
*/
|
*/
|
||||||
public TaskExecutionDaoFactoryBean(DataSource dataSource) {
|
public TaskExecutionDaoFactoryBean(DataSource dataSource) {
|
||||||
@@ -74,7 +73,7 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TaskExecutionDao getObject() throws Exception {
|
public TaskExecutionDao getObject() throws Exception {
|
||||||
if(this.dao == null) {
|
if (this.dao == null) {
|
||||||
if (this.dataSource != null) {
|
if (this.dataSource != null) {
|
||||||
buildTaskExecutionDao(this.dataSource);
|
buildTaskExecutionDao(this.dataSource);
|
||||||
}
|
}
|
||||||
@@ -97,15 +96,19 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void buildTaskExecutionDao(DataSource dataSource) {
|
private void buildTaskExecutionDao(DataSource dataSource) {
|
||||||
DataFieldMaxValueIncrementerFactory incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource);
|
DataFieldMaxValueIncrementerFactory incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(
|
||||||
|
dataSource);
|
||||||
this.dao = new JdbcTaskExecutionDao(dataSource, this.tablePrefix);
|
this.dao = new JdbcTaskExecutionDao(dataSource, this.tablePrefix);
|
||||||
String databaseType;
|
String databaseType;
|
||||||
try {
|
try {
|
||||||
databaseType = org.springframework.batch.support.DatabaseType.fromMetaData(dataSource).name();
|
databaseType = org.springframework.batch.support.DatabaseType
|
||||||
|
.fromMetaData(dataSource).name();
|
||||||
}
|
}
|
||||||
catch (MetaDataAccessException e) {
|
catch (MetaDataAccessException e) {
|
||||||
throw new IllegalStateException(e);
|
throw new IllegalStateException(e);
|
||||||
}
|
}
|
||||||
((JdbcTaskExecutionDao) this.dao).setTaskIncrementer(incrementerFactory.getIncrementer(databaseType, this.tablePrefix + "SEQ"));
|
((JdbcTaskExecutionDao) this.dao).setTaskIncrementer(incrementerFactory
|
||||||
|
.getIncrementer(databaseType, this.tablePrefix + "SEQ"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -32,11 +32,11 @@ import org.springframework.jdbc.support.MetaDataAccessException;
|
|||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility for initializing the Task Repository's datasource. If a single
|
* Utility for initializing the Task Repository's datasource. If a single
|
||||||
* {@link DataSource} is available in the current context, and functionality is enabled
|
* {@link DataSource} is available in the current context, and functionality is enabled
|
||||||
* (as it is by default), this will initialize the database. If more than one DataSource
|
* (as it is by default), this will initialize the database. If more than one DataSource
|
||||||
* is available in the current context, custom configuration of this is required
|
* is available in the current context, custom configuration of this is required (if
|
||||||
* (if desired).
|
* desired).
|
||||||
*
|
*
|
||||||
* By default, initialization of the database can be disabled by configuring the property
|
* By default, initialization of the database can be disabled by configuring the property
|
||||||
* <code>spring.cloud.task.initialize.enable</code> to false.
|
* <code>spring.cloud.task.initialize.enable</code> to false.
|
||||||
@@ -67,7 +67,7 @@ public final class TaskRepositoryInitializer implements InitializingBean {
|
|||||||
@Value("${spring.cloud.task.tablePrefix:#{null}}")
|
@Value("${spring.cloud.task.tablePrefix:#{null}}")
|
||||||
private String tablePrefix;
|
private String tablePrefix;
|
||||||
|
|
||||||
public TaskRepositoryInitializer(){
|
public TaskRepositoryInitializer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDataSource(DataSource dataSource) {
|
public void setDataSource(DataSource dataSource) {
|
||||||
@@ -81,7 +81,9 @@ public final class TaskRepositoryInitializer implements InitializingBean {
|
|||||||
|
|
||||||
private String getDatabaseType(DataSource dataSource) {
|
private String getDatabaseType(DataSource dataSource) {
|
||||||
try {
|
try {
|
||||||
return JdbcUtils.commonDatabaseName(DatabaseType.fromMetaData(dataSource).toString()).toLowerCase();
|
return JdbcUtils
|
||||||
|
.commonDatabaseName(DatabaseType.fromMetaData(dataSource).toString())
|
||||||
|
.toLowerCase();
|
||||||
}
|
}
|
||||||
catch (MetaDataAccessException ex) {
|
catch (MetaDataAccessException ex) {
|
||||||
throw new IllegalStateException("Unable to detect database type", ex);
|
throw new IllegalStateException("Unable to detect database type", ex);
|
||||||
@@ -90,10 +92,9 @@ public final class TaskRepositoryInitializer implements InitializingBean {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
if (dataSource != null &&
|
if (this.dataSource != null && this.taskInitializationEnable
|
||||||
taskInitializationEnable &&
|
&& !StringUtils.hasText(this.tablePrefix)) {
|
||||||
!StringUtils.hasText(this.tablePrefix)) {
|
String platform = getDatabaseType(this.dataSource);
|
||||||
String platform = getDatabaseType(dataSource);
|
|
||||||
if ("hsql".equals(platform)) {
|
if ("hsql".equals(platform)) {
|
||||||
platform = "hsqldb";
|
platform = "hsqldb";
|
||||||
}
|
}
|
||||||
@@ -106,17 +107,18 @@ public final class TaskRepositoryInitializer implements InitializingBean {
|
|||||||
if ("mysql".equals(platform)) {
|
if ("mysql".equals(platform)) {
|
||||||
platform = "mysql";
|
platform = "mysql";
|
||||||
}
|
}
|
||||||
if ("sqlserver".equals(platform)){
|
if ("sqlserver".equals(platform)) {
|
||||||
platform = "sqlserver";
|
platform = "sqlserver";
|
||||||
}
|
}
|
||||||
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
|
||||||
String schemaLocation = schema;
|
String schemaLocation = schema;
|
||||||
schemaLocation = schemaLocation.replace("@@platform@@", platform);
|
schemaLocation = schemaLocation.replace("@@platform@@", platform);
|
||||||
populator.addScript(resourceLoader.getResource(schemaLocation));
|
populator.addScript(this.resourceLoader.getResource(schemaLocation));
|
||||||
populator.setContinueOnError(true);
|
populator.setContinueOnError(true);
|
||||||
logger.debug(String.format("Initializing task schema for %s database",
|
logger.debug(
|
||||||
platform));
|
String.format("Initializing task schema for %s database", platform));
|
||||||
DatabasePopulatorUtils.execute(populator, dataSource);
|
DatabasePopulatorUtils.execute(populator, this.dataSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Classes used for setting up and supporting a task repositories.
|
* Classes used for setting up and supporting a task repositories.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"properties": [
|
"properties": [
|
||||||
{
|
{
|
||||||
"defaultValue": false,
|
"defaultValue": false,
|
||||||
"name": "spring.cloud.task.single-instance-enabled",
|
"name": "spring.cloud.task.single-instance-enabled",
|
||||||
"description": "This property is used to determine if a task will execute if another task with the same app name is running.",
|
"description": "This property is used to determine if a task will execute if another task with the same app name is running.",
|
||||||
"type": "java.lang.Boolean"
|
"type": "java.lang.Boolean"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task;
|
package org.springframework.cloud.task;
|
||||||
@@ -25,8 +25,7 @@ import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
|
|||||||
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
|
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
|
||||||
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
|
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the beans created by the SimpleSingleTaskAutoConfigurationConfiguration
|
* Verifies that the beans created by the SimpleSingleTaskAutoConfigurationConfiguration
|
||||||
@@ -43,15 +42,18 @@ public class SimpleSingleTaskAutoConfigurationTests {
|
|||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
SingleTaskConfiguration.class))
|
|
||||||
.withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
|
.withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
|
||||||
applicationContextRunner.run((context) -> {
|
applicationContextRunner.run((context) -> {
|
||||||
SingleInstanceTaskListener singleInstanceTaskListener = context.getBean(SingleInstanceTaskListener.class);
|
SingleInstanceTaskListener singleInstanceTaskListener = context
|
||||||
|
.getBean(SingleInstanceTaskListener.class);
|
||||||
|
|
||||||
assertNotNull("singleInstanceTaskListener should not be null", singleInstanceTaskListener);
|
assertThat(singleInstanceTaskListener)
|
||||||
|
.as("singleInstanceTaskListener should not be null").isNotNull();
|
||||||
|
|
||||||
assertEquals(singleInstanceTaskListener.getClass(), SingleInstanceTaskListener.class); });
|
assertThat(SingleInstanceTaskListener.class)
|
||||||
|
.isEqualTo(singleInstanceTaskListener.getClass());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task;
|
package org.springframework.cloud.task;
|
||||||
@@ -26,8 +26,7 @@ import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
|
|||||||
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
|
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
|
||||||
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
|
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the beans created by the SimpleSingleTaskAutoConfigurationConfiguration
|
* Verifies that the beans created by the SimpleSingleTaskAutoConfigurationConfiguration
|
||||||
@@ -44,16 +43,19 @@ public class SimpleSingleTaskAutoConfigurationWithDataSourceTests {
|
|||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class,
|
||||||
SingleTaskConfiguration.class,
|
|
||||||
EmbeddedDataSourceConfiguration.class))
|
EmbeddedDataSourceConfiguration.class))
|
||||||
.withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
|
.withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
|
||||||
applicationContextRunner.run((context) -> {
|
applicationContextRunner.run((context) -> {
|
||||||
SingleInstanceTaskListener singleInstanceTaskListener = context.getBean(SingleInstanceTaskListener.class);
|
SingleInstanceTaskListener singleInstanceTaskListener = context
|
||||||
|
.getBean(SingleInstanceTaskListener.class);
|
||||||
|
|
||||||
assertNotNull("singleInstanceTaskListener should not be null", singleInstanceTaskListener);
|
assertThat(singleInstanceTaskListener)
|
||||||
|
.as("singleInstanceTaskListener should not be null").isNotNull();
|
||||||
|
|
||||||
assertEquals(singleInstanceTaskListener.getClass(), SingleInstanceTaskListener.class);
|
assertThat(SingleInstanceTaskListener.class)
|
||||||
|
.isEqualTo(singleInstanceTaskListener.getClass());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -48,7 +48,7 @@ import org.springframework.context.annotation.Bean;
|
|||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -71,10 +71,10 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testRepository() {
|
public void testRepository() {
|
||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class,
|
||||||
SingleTaskConfiguration.class));
|
SingleTaskConfiguration.class));
|
||||||
applicationContextRunner.run((context) -> {
|
applicationContextRunner.run((context) -> {
|
||||||
|
|
||||||
TaskRepository taskRepository = context.getBean(TaskRepository.class);
|
TaskRepository taskRepository = context.getBean(TaskRepository.class);
|
||||||
@@ -89,50 +89,50 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
SingleTaskConfiguration.class))
|
|
||||||
.withPropertyValues("spring.cloud.task.autoconfiguration.enabled=false");
|
.withPropertyValues("spring.cloud.task.autoconfiguration.enabled=false");
|
||||||
Executable executable = () -> {
|
Executable executable = () -> {
|
||||||
applicationContextRunner.run((context) -> {
|
applicationContextRunner.run((context) -> {
|
||||||
context.getBean(TaskRepository.class);
|
context.getBean(TaskRepository.class);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
verifyExceptionThrown(NoSuchBeanDefinitionException.class, "No qualifying " +
|
verifyExceptionThrown(NoSuchBeanDefinitionException.class, "No qualifying "
|
||||||
"bean of type 'org.springframework.cloud.task.repository.TaskRepository' " +
|
+ "bean of type 'org.springframework.cloud.task.repository.TaskRepository' "
|
||||||
"available", executable);
|
+ "available", executable);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRepositoryInitialized() {
|
public void testRepositoryInitialized() {
|
||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
|
.withConfiguration(AutoConfigurations.of(
|
||||||
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
SingleTaskConfiguration.class))
|
|
||||||
.withUserConfiguration(TaskLifecycleListenerConfiguration.class);
|
.withUserConfiguration(TaskLifecycleListenerConfiguration.class);
|
||||||
applicationContextRunner.run((context) -> {
|
applicationContextRunner.run((context) -> {
|
||||||
TaskExplorer taskExplorer = context.getBean(TaskExplorer.class);
|
TaskExplorer taskExplorer = context.getBean(TaskExplorer.class);
|
||||||
assertThat(taskExplorer.getTaskExecutionCount()).isEqualTo(1l);
|
assertThat(taskExplorer.getTaskExecutionCount()).isEqualTo(1L);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRepositoryNotInitialized() {
|
public void testRepositoryNotInitialized() {
|
||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
|
.withConfiguration(AutoConfigurations.of(
|
||||||
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
SingleTaskConfiguration.class))
|
|
||||||
.withUserConfiguration(TaskLifecycleListenerConfiguration.class)
|
.withUserConfiguration(TaskLifecycleListenerConfiguration.class)
|
||||||
.withPropertyValues("spring.cloud.task.tablePrefix=foobarless");
|
.withPropertyValues("spring.cloud.task.tablePrefix=foobarless");
|
||||||
|
|
||||||
verifyExceptionThrownDefaultExecutable(ApplicationContextException.class, "Failed to start " +
|
verifyExceptionThrownDefaultExecutable(ApplicationContextException.class,
|
||||||
"bean 'taskLifecycleListener'; nested exception is " +
|
"Failed to start " + "bean 'taskLifecycleListener'; nested exception is "
|
||||||
"org.springframework.dao.DataAccessResourceFailureException: " +
|
+ "org.springframework.dao.DataAccessResourceFailureException: "
|
||||||
"Could not obtain sequence value; nested exception is org.h2.jdbc.JdbcSQLException: " +
|
+ "Could not obtain sequence value; nested exception is org.h2.jdbc.JdbcSQLException: "
|
||||||
"Syntax error in SQL statement \"SELECT FOOBARLESSSEQ.NEXTVAL FROM[*] DUAL \"; " +
|
+ "Syntax error in SQL statement \"SELECT FOOBARLESSSEQ.NEXTVAL FROM[*] DUAL \"; "
|
||||||
"expected \"identifier\"; SQL statement:\n" +
|
+ "expected \"identifier\"; SQL statement:\n"
|
||||||
"select foobarlessSEQ.nextval from dual [42001-197]", applicationContextRunner);
|
+ "select foobarlessSEQ.nextval from dual [42001-197]",
|
||||||
|
applicationContextRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -140,29 +140,32 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
SingleTaskConfiguration.class))
|
|
||||||
.withUserConfiguration(MultipleConfigurers.class);
|
.withUserConfiguration(MultipleConfigurers.class);
|
||||||
|
|
||||||
verifyExceptionThrownDefaultExecutable(BeanCreationException.class, "Error creating bean " +
|
verifyExceptionThrownDefaultExecutable(BeanCreationException.class,
|
||||||
"with name 'simpleTaskAutoConfiguration': Invocation of init " +
|
"Error creating bean "
|
||||||
"method failed; nested exception is java.lang.IllegalStateException:" +
|
+ "with name 'simpleTaskAutoConfiguration': Invocation of init "
|
||||||
" Expected one TaskConfigurer but found 2", applicationContextRunner);
|
+ "method failed; nested exception is java.lang.IllegalStateException:"
|
||||||
|
+ " Expected one TaskConfigurer but found 2",
|
||||||
|
applicationContextRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMultipleDataSources() {
|
public void testMultipleDataSources() {
|
||||||
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
|
||||||
.withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class,
|
.withConfiguration(AutoConfigurations.of(
|
||||||
SimpleTaskAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SingleTaskConfiguration.class))
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
.withUserConfiguration(MultipleDataSources.class);
|
.withUserConfiguration(MultipleDataSources.class);
|
||||||
|
|
||||||
verifyExceptionThrownDefaultExecutable(BeanCreationException.class, "Error creating bean " +
|
verifyExceptionThrownDefaultExecutable(BeanCreationException.class,
|
||||||
"with name 'simpleTaskAutoConfiguration': Invocation of init method " +
|
"Error creating bean "
|
||||||
"failed; nested exception is java.lang.IllegalStateException: To use " +
|
+ "with name 'simpleTaskAutoConfiguration': Invocation of init method "
|
||||||
"the default TaskConfigurer the context must contain no more than " +
|
+ "failed; nested exception is java.lang.IllegalStateException: To use "
|
||||||
"one DataSource, found 2", applicationContextRunner);
|
+ "the default TaskConfigurer the context must contain no more than "
|
||||||
|
+ "one DataSource, found 2",
|
||||||
|
applicationContextRunner);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,14 +181,15 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
verifyExceptionThrown(classToCheck, message, executable);
|
verifyExceptionThrown(classToCheck, message, executable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void verifyExceptionThrown(Class classToCheck, String message, Executable executable) {
|
public void verifyExceptionThrown(Class classToCheck, String message,
|
||||||
Throwable exception = assertThrows(classToCheck, executable);
|
Executable executable) {
|
||||||
assertThat(exception.getMessage()).isEqualTo(message);
|
assertThatExceptionOfType(classToCheck).isThrownBy(executable::execute)
|
||||||
|
.withMessage(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that the verifyEnvironment method skips DataSource Proxy Beans when determining
|
* Verify that the verifyEnvironment method skips DataSource Proxy Beans when
|
||||||
* the number of available dataSources.
|
* determining the number of available dataSources.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testWithDataSourceProxy() {
|
public void testWithDataSourceProxy() {
|
||||||
@@ -193,12 +197,12 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
.withConfiguration(AutoConfigurations.of(
|
.withConfiguration(AutoConfigurations.of(
|
||||||
EmbeddedDataSourceConfiguration.class,
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class,
|
PropertyPlaceholderAutoConfiguration.class,
|
||||||
SimpleTaskAutoConfiguration.class,
|
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
|
||||||
SingleTaskConfiguration.class))
|
|
||||||
.withUserConfiguration(DataSourceProxyConfiguration.class);
|
.withUserConfiguration(DataSourceProxyConfiguration.class);
|
||||||
applicationContextRunner.run((context) -> {
|
applicationContextRunner.run((context) -> {
|
||||||
assertThat(context.getBeanNamesForType(DataSource.class).length).isEqualTo(2);
|
assertThat(context.getBeanNamesForType(DataSource.class).length).isEqualTo(2);
|
||||||
SimpleTaskAutoConfiguration taskConfiguration = context.getBean(SimpleTaskAutoConfiguration.class);
|
SimpleTaskAutoConfiguration taskConfiguration = context
|
||||||
|
.getBean(SimpleTaskAutoConfiguration.class);
|
||||||
assertThat(taskConfiguration).isNotNull();
|
assertThat(taskConfiguration).isNotNull();
|
||||||
assertThat(taskConfiguration.taskExplorer()).isNotNull();
|
assertThat(taskConfiguration.taskExplorer()).isNotNull();
|
||||||
});
|
});
|
||||||
@@ -216,6 +220,7 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
public TaskConfigurer taskConfigurer2() {
|
public TaskConfigurer taskConfigurer2() {
|
||||||
return new DefaultTaskConfigurer((DataSource) null);
|
return new DefaultTaskConfigurer((DataSource) null);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -243,9 +248,10 @@ public class SimpleTaskAutoConfigurationTests {
|
|||||||
public BeanDefinitionHolder proxyDataSource() {
|
public BeanDefinitionHolder proxyDataSource() {
|
||||||
GenericBeanDefinition proxyBeanDefinition = new GenericBeanDefinition();
|
GenericBeanDefinition proxyBeanDefinition = new GenericBeanDefinition();
|
||||||
proxyBeanDefinition.setBeanClassName("javax.sql.DataSource");
|
proxyBeanDefinition.setBeanClassName("javax.sql.DataSource");
|
||||||
BeanDefinitionHolder myDataSource = new BeanDefinitionHolder(proxyBeanDefinition, "dataSource2");
|
BeanDefinitionHolder myDataSource = new BeanDefinitionHolder(
|
||||||
ScopedProxyUtils.createScopedProxy(myDataSource, (BeanDefinitionRegistry) this.context.getBeanFactory(),
|
proxyBeanDefinition, "dataSource2");
|
||||||
true);
|
ScopedProxyUtils.createScopedProxy(myDataSource,
|
||||||
|
(BeanDefinitionRegistry) this.context.getBeanFactory(), true);
|
||||||
return myDataSource;
|
return myDataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -31,7 +31,7 @@ import org.springframework.context.ApplicationContextException;
|
|||||||
import org.springframework.context.ConfigurableApplicationContext;
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies core behavior for Tasks.
|
* Verifies core behavior for Tasks.
|
||||||
@@ -41,42 +41,49 @@ import static org.junit.Assert.assertTrue;
|
|||||||
public class TaskCoreTests {
|
public class TaskCoreTests {
|
||||||
|
|
||||||
private static final String TASK_NAME = "taskEventTest";
|
private static final String TASK_NAME = "taskEventTest";
|
||||||
private static final String EXCEPTION_MESSAGE = "FOO EXCEPTION";
|
|
||||||
private static final String CREATE_TASK_MESSAGE = "Creating: TaskExecution{executionId=";
|
|
||||||
private static final String UPDATE_TASK_MESSAGE = "Updating: TaskExecution with executionId=";
|
|
||||||
private static final String SUCCESS_EXIT_CODE_MESSAGE = "with the following {exitCode=0";
|
|
||||||
private static final String EXCEPTION_EXIT_CODE_MESSAGE = "with the following {exitCode=1";
|
|
||||||
private static final String EXCEPTION_INVALID_TASK_EXECUTION_ID =
|
|
||||||
"java.lang.IllegalArgumentException: Invalid TaskExecution, ID 55 not found";
|
|
||||||
private static final String ERROR_MESSAGE =
|
|
||||||
"errorMessage='java.lang.IllegalStateException: Failed to execute CommandLineRunner";
|
|
||||||
|
|
||||||
private ConfigurableApplicationContext applicationContext;
|
private static final String EXCEPTION_MESSAGE = "FOO EXCEPTION";
|
||||||
|
|
||||||
|
private static final String CREATE_TASK_MESSAGE = "Creating: TaskExecution{executionId=";
|
||||||
|
|
||||||
|
private static final String UPDATE_TASK_MESSAGE = "Updating: TaskExecution with executionId=";
|
||||||
|
|
||||||
|
private static final String SUCCESS_EXIT_CODE_MESSAGE = "with the following {exitCode=0";
|
||||||
|
|
||||||
|
private static final String EXCEPTION_EXIT_CODE_MESSAGE = "with the following {exitCode=1";
|
||||||
|
|
||||||
|
private static final String EXCEPTION_INVALID_TASK_EXECUTION_ID = "java.lang.IllegalArgumentException: "
|
||||||
|
+ "Invalid TaskExecution, ID 55 not found";
|
||||||
|
|
||||||
|
private static final String ERROR_MESSAGE = "errorMessage='java.lang.IllegalStateException: "
|
||||||
|
+ "Failed to execute CommandLineRunner";
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public OutputCapture outputCapture = new OutputCapture();
|
public OutputCapture outputCapture = new OutputCapture();
|
||||||
|
|
||||||
|
private ConfigurableApplicationContext applicationContext;
|
||||||
|
|
||||||
@After
|
@After
|
||||||
public void teardown() {
|
public void teardown() {
|
||||||
if (applicationContext != null && applicationContext.isActive()) {
|
if (this.applicationContext != null && this.applicationContext.isActive()) {
|
||||||
applicationContext.close();
|
this.applicationContext.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void successfulTaskTest() {
|
public void successfulTaskTest() {
|
||||||
this.applicationContext = SpringApplication.run( TaskConfiguration.class,
|
this.applicationContext = SpringApplication.run(TaskConfiguration.class,
|
||||||
"--spring.cloud.task.closecontext.enable=false",
|
"--spring.cloud.task.closecontext.enable=false",
|
||||||
"--spring.cloud.task.name=" + TASK_NAME,
|
"--spring.cloud.task.name=" + TASK_NAME,
|
||||||
"--spring.main.web-environment=false");
|
"--spring.main.web-environment=false");
|
||||||
|
|
||||||
String output = this.outputCapture.toString();
|
String output = this.outputCapture.toString();
|
||||||
assertTrue("Test results do not show create task message: " + output,
|
assertThat(output.contains(CREATE_TASK_MESSAGE))
|
||||||
output.contains(CREATE_TASK_MESSAGE));
|
.as("Test results do not show create task message: " + output).isTrue();
|
||||||
assertTrue("Test results do not show success message: " + output,
|
assertThat(output.contains(UPDATE_TASK_MESSAGE))
|
||||||
output.contains(UPDATE_TASK_MESSAGE));
|
.as("Test results do not show success message: " + output).isTrue();
|
||||||
assertTrue("Test results have incorrect exit code: " + output,
|
assertThat(output.contains(SUCCESS_EXIT_CODE_MESSAGE))
|
||||||
output.contains(SUCCESS_EXIT_CODE_MESSAGE));
|
.as("Test results have incorrect exit code: " + output).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,25 +91,27 @@ public class TaskCoreTests {
|
|||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void successfulTaskTestWithAnnotation() {
|
public void successfulTaskTestWithAnnotation() {
|
||||||
this.applicationContext = SpringApplication.run( TaskConfigurationWithAnotation.class,
|
this.applicationContext = SpringApplication.run(
|
||||||
|
TaskConfigurationWithAnotation.class,
|
||||||
"--spring.cloud.task.closecontext.enable=false",
|
"--spring.cloud.task.closecontext.enable=false",
|
||||||
"--spring.cloud.task.name=" + TASK_NAME,
|
"--spring.cloud.task.name=" + TASK_NAME,
|
||||||
"--spring.main.web-environment=false");
|
"--spring.main.web-environment=false");
|
||||||
|
|
||||||
String output = this.outputCapture.toString();
|
String output = this.outputCapture.toString();
|
||||||
assertTrue("Test results do not show create task message: " + output,
|
assertThat(output.contains(CREATE_TASK_MESSAGE))
|
||||||
output.contains(CREATE_TASK_MESSAGE));
|
.as("Test results do not show create task message: " + output).isTrue();
|
||||||
assertTrue("Test results do not show success message: " + output,
|
assertThat(output.contains(UPDATE_TASK_MESSAGE))
|
||||||
output.contains(UPDATE_TASK_MESSAGE));
|
.as("Test results do not show success message: " + output).isTrue();
|
||||||
assertTrue("Test results have incorrect exit code: " + output,
|
assertThat(output.contains(SUCCESS_EXIT_CODE_MESSAGE))
|
||||||
output.contains(SUCCESS_EXIT_CODE_MESSAGE));
|
.as("Test results have incorrect exit code: " + output).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void exceptionTaskTest() {
|
public void exceptionTaskTest() {
|
||||||
boolean exceptionFired = false;
|
boolean exceptionFired = false;
|
||||||
try {
|
try {
|
||||||
this.applicationContext = SpringApplication.run( TaskExceptionConfiguration.class,
|
this.applicationContext = SpringApplication.run(
|
||||||
|
TaskExceptionConfiguration.class,
|
||||||
"--spring.cloud.task.closecontext.enable=false",
|
"--spring.cloud.task.closecontext.enable=false",
|
||||||
"--spring.cloud.task.name=" + TASK_NAME,
|
"--spring.cloud.task.name=" + TASK_NAME,
|
||||||
"--spring.main.web-environment=false");
|
"--spring.main.web-environment=false");
|
||||||
@@ -110,19 +119,20 @@ public class TaskCoreTests {
|
|||||||
catch (IllegalStateException exception) {
|
catch (IllegalStateException exception) {
|
||||||
exceptionFired = true;
|
exceptionFired = true;
|
||||||
}
|
}
|
||||||
assertTrue("An IllegalStateException should have been thrown", exceptionFired);
|
assertThat(exceptionFired).as("An IllegalStateException should have been thrown")
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
String output = this.outputCapture.toString();
|
String output = this.outputCapture.toString();
|
||||||
assertTrue("Test results do not show create task message: " + output,
|
assertThat(output.contains(CREATE_TASK_MESSAGE))
|
||||||
output.contains(CREATE_TASK_MESSAGE));
|
.as("Test results do not show create task message: " + output).isTrue();
|
||||||
assertTrue("Test results do not show success message: " + output,
|
assertThat(output.contains(UPDATE_TASK_MESSAGE))
|
||||||
output.contains(UPDATE_TASK_MESSAGE));
|
.as("Test results do not show success message: " + output).isTrue();
|
||||||
assertTrue("Test results have incorrect exit code: " + output,
|
assertThat(output.contains(EXCEPTION_EXIT_CODE_MESSAGE))
|
||||||
output.contains(EXCEPTION_EXIT_CODE_MESSAGE));
|
.as("Test results have incorrect exit code: " + output).isTrue();
|
||||||
assertTrue("Test results have incorrect exit message: " + output,
|
assertThat(output.contains(ERROR_MESSAGE))
|
||||||
output.contains(ERROR_MESSAGE));
|
.as("Test results have incorrect exit message: " + output).isTrue();
|
||||||
assertTrue("Test results have exception message: " + output,
|
assertThat(output.contains(EXCEPTION_MESSAGE))
|
||||||
output.contains(EXCEPTION_MESSAGE));
|
.as("Test results have exception message: " + output).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -130,7 +140,8 @@ public class TaskCoreTests {
|
|||||||
boolean exceptionFired = false;
|
boolean exceptionFired = false;
|
||||||
try {
|
try {
|
||||||
this.applicationContext = SpringApplication.run(
|
this.applicationContext = SpringApplication.run(
|
||||||
TaskExceptionConfiguration.class, "--spring.cloud.task.closecontext.enable=false",
|
TaskExceptionConfiguration.class,
|
||||||
|
"--spring.cloud.task.closecontext.enable=false",
|
||||||
"--spring.cloud.task.name=" + TASK_NAME,
|
"--spring.cloud.task.name=" + TASK_NAME,
|
||||||
"--spring.main.web-environment=false",
|
"--spring.main.web-environment=false",
|
||||||
"--spring.cloud.task.executionid=55");
|
"--spring.cloud.task.executionid=55");
|
||||||
@@ -138,15 +149,18 @@ public class TaskCoreTests {
|
|||||||
catch (ApplicationContextException exception) {
|
catch (ApplicationContextException exception) {
|
||||||
exceptionFired = true;
|
exceptionFired = true;
|
||||||
}
|
}
|
||||||
assertTrue("An ApplicationContextException should have been thrown", exceptionFired);
|
assertThat(exceptionFired)
|
||||||
|
.as("An ApplicationContextException should have been thrown").isTrue();
|
||||||
|
|
||||||
String output = this.outputCapture.toString();
|
String output = this.outputCapture.toString();
|
||||||
assertTrue("Test results do not show the correct exception message: " + output,
|
assertThat(output.contains(EXCEPTION_INVALID_TASK_EXECUTION_ID))
|
||||||
output.contains(EXCEPTION_INVALID_TASK_EXECUTION_ID));
|
.as("Test results do not show the correct exception message: " + output)
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
@EnableTask
|
||||||
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
|
@ImportAutoConfiguration({ SimpleTaskAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class })
|
||||||
public static class TaskConfiguration {
|
public static class TaskConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -157,10 +171,12 @@ public class TaskCoreTests {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
@EnableTask
|
||||||
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
|
@ImportAutoConfiguration({ SimpleTaskAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class })
|
||||||
public static class TaskConfigurationWithAnotation {
|
public static class TaskConfigurationWithAnotation {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -171,10 +187,12 @@ public class TaskCoreTests {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@EnableTask
|
@EnableTask
|
||||||
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
|
@ImportAutoConfiguration({ SimpleTaskAutoConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class })
|
||||||
public static class TaskExceptionConfiguration {
|
public static class TaskExceptionConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
@@ -186,5 +204,7 @@ public class TaskCoreTests {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task;
|
package org.springframework.cloud.task;
|
||||||
@@ -36,15 +36,15 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that TaskRepositoryInitializer creates tables if a {@link TaskConfigurer}
|
* Verifies that TaskRepositoryInitializer creates tables if a {@link TaskConfigurer} has
|
||||||
* has a {@link DataSource}.
|
* a {@link DataSource}.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = {SimpleTaskAutoConfiguration.class,
|
@ContextConfiguration(classes = { SimpleTaskAutoConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class})
|
EmbeddedDataSourceConfiguration.class })
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public class TaskRepositoryInitializerDefaultTaskConfigurerTests {
|
public class TaskRepositoryInitializerDefaultTaskConfigurerTests {
|
||||||
|
|
||||||
@@ -53,8 +53,9 @@ public class TaskRepositoryInitializerDefaultTaskConfigurerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTablesCreated() {
|
public void testTablesCreated() {
|
||||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
|
||||||
List<Map<String, Object>> rows= jdbcTemplate.queryForList("SHOW TABLES");
|
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SHOW TABLES");
|
||||||
assertThat(rows.size()).isEqualTo(4);
|
assertThat(rows.size()).isEqualTo(4);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task;
|
package org.springframework.cloud.task;
|
||||||
@@ -37,16 +37,16 @@ import org.springframework.test.context.junit4.SpringRunner;
|
|||||||
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that TaskRepositoryInitializer does not create tables if a {@link TaskConfigurer}
|
* Verifies that TaskRepositoryInitializer does not create tables if a
|
||||||
* has no {@link DataSource}.
|
* {@link TaskConfigurer} has no {@link DataSource}.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @since 2.0.0
|
* @since 2.0.0
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = {SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class,
|
@ContextConfiguration(classes = { SimpleTaskAutoConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class,
|
SingleTaskConfiguration.class, EmbeddedDataSourceConfiguration.class,
|
||||||
DefaultTaskConfigurer.class})
|
DefaultTaskConfigurer.class })
|
||||||
public class TaskRepositoryInitializerNoDataSourceTaskConfigurerTests {
|
public class TaskRepositoryInitializerNoDataSourceTaskConfigurerTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -54,8 +54,9 @@ public class TaskRepositoryInitializerNoDataSourceTaskConfigurerTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoTablesCreated() {
|
public void testNoTablesCreated() {
|
||||||
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
|
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
|
||||||
List<Map<String, Object>> rows= jdbcTemplate.queryForList("SHOW TABLES");
|
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SHOW TABLES");
|
||||||
assertThat(rows.size()).isEqualTo(0);
|
assertThat(rows.size()).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
@@ -31,11 +31,7 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import static org.hamcrest.CoreMatchers.equalTo;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
|
||||||
import static org.hamcrest.CoreMatchers.nullValue;
|
|
||||||
import static org.hamcrest.core.IsNull.notNullValue;
|
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,64 +50,80 @@ public class DefaultTaskConfigurerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void resourcelessTransactionManagerTest() {
|
public void resourcelessTransactionManagerTest() {
|
||||||
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer();
|
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer();
|
||||||
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
|
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
|
||||||
is("org.springframework.batch.support.transaction.ResourcelessTransactionManager"));
|
.isEqualTo(
|
||||||
|
"org.springframework.batch.support.transaction.ResourcelessTransactionManager");
|
||||||
defaultTaskConfigurer = new DefaultTaskConfigurer("foo");
|
defaultTaskConfigurer = new DefaultTaskConfigurer("foo");
|
||||||
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
|
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
|
||||||
is("org.springframework.batch.support.transaction.ResourcelessTransactionManager"));
|
.isEqualTo(
|
||||||
|
"org.springframework.batch.support.transaction.ResourcelessTransactionManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDefaultContext() throws Exception {
|
public void testDefaultContext() throws Exception {
|
||||||
AnnotationConfigApplicationContext localContext = new AnnotationConfigApplicationContext();
|
AnnotationConfigApplicationContext localContext = new AnnotationConfigApplicationContext();
|
||||||
localContext.register(EmbeddedDataSourceConfiguration.class,EntityManagerConfiguration.class);
|
localContext.register(EmbeddedDataSourceConfiguration.class,
|
||||||
|
EntityManagerConfiguration.class);
|
||||||
localContext.refresh();
|
localContext.refresh();
|
||||||
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, localContext);
|
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
|
||||||
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(), is(equalTo("org.springframework.orm.jpa.JpaTransactionManager")));
|
this.dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, localContext);
|
||||||
|
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
|
||||||
|
.isEqualTo("org.springframework.orm.jpa.JpaTransactionManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void dataSourceTransactionManagerTest() {
|
public void dataSourceTransactionManagerTest() {
|
||||||
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
|
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
|
||||||
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
|
this.dataSource);
|
||||||
is("org.springframework.jdbc.datasource.DataSourceTransactionManager"));
|
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
|
||||||
defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource, "FOO", null);
|
.isEqualTo(
|
||||||
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
|
"org.springframework.jdbc.datasource.DataSourceTransactionManager");
|
||||||
is("org.springframework.jdbc.datasource.DataSourceTransactionManager"));
|
defaultTaskConfigurer = new DefaultTaskConfigurer(this.dataSource, "FOO", null);
|
||||||
defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource, "FOO", context);
|
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
|
||||||
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
|
.isEqualTo(
|
||||||
is("org.springframework.jdbc.datasource.DataSourceTransactionManager"));
|
"org.springframework.jdbc.datasource.DataSourceTransactionManager");
|
||||||
|
defaultTaskConfigurer = new DefaultTaskConfigurer(this.dataSource, "FOO",
|
||||||
|
this.context);
|
||||||
|
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
|
||||||
|
.isEqualTo(
|
||||||
|
"org.springframework.jdbc.datasource.DataSourceTransactionManager");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void taskExplorerTest() {
|
public void taskExplorerTest() {
|
||||||
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
|
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
|
||||||
assertThat(defaultTaskConfigurer.getTaskExplorer(), is(notNullValue()));
|
this.dataSource);
|
||||||
|
assertThat(defaultTaskConfigurer.getTaskExplorer()).isNotNull();
|
||||||
defaultTaskConfigurer = new DefaultTaskConfigurer();
|
defaultTaskConfigurer = new DefaultTaskConfigurer();
|
||||||
assertThat(defaultTaskConfigurer.getTaskExplorer(), is(notNullValue()));
|
assertThat(defaultTaskConfigurer.getTaskExplorer()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void taskRepositoryTest() {
|
public void taskRepositoryTest() {
|
||||||
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
|
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
|
||||||
assertThat(defaultTaskConfigurer.getTaskRepository(), is(notNullValue()));
|
this.dataSource);
|
||||||
|
assertThat(defaultTaskConfigurer.getTaskRepository()).isNotNull();
|
||||||
defaultTaskConfigurer = new DefaultTaskConfigurer();
|
defaultTaskConfigurer = new DefaultTaskConfigurer();
|
||||||
assertThat(defaultTaskConfigurer.getTaskRepository(), is(notNullValue()));
|
assertThat(defaultTaskConfigurer.getTaskRepository()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void taskDataSource() {
|
public void taskDataSource() {
|
||||||
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
|
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
|
||||||
assertThat(defaultTaskConfigurer.getTaskDataSource(), is(notNullValue()));
|
this.dataSource);
|
||||||
|
assertThat(defaultTaskConfigurer.getTaskDataSource()).isNotNull();
|
||||||
defaultTaskConfigurer = new DefaultTaskConfigurer();
|
defaultTaskConfigurer = new DefaultTaskConfigurer();
|
||||||
assertThat(defaultTaskConfigurer.getTaskDataSource(), is(nullValue()));
|
assertThat(defaultTaskConfigurer.getTaskDataSource()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class EntityManagerConfiguration {
|
public static class EntityManagerConfiguration {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public EntityManager entityManager() {
|
public EntityManager entityManager() {
|
||||||
return mock(EntityManager.class);
|
return mock(EntityManager.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -27,36 +27,37 @@ import org.springframework.context.annotation.Configuration;
|
|||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import static org.hamcrest.core.Is.is;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertThat;
|
|
||||||
|
|
||||||
|
|
||||||
@RunWith(Suite.class)
|
@RunWith(Suite.class)
|
||||||
@SuiteClasses({
|
@SuiteClasses({ TaskPropertiesTests.CloseContextEnabledTest.class
|
||||||
TaskPropertiesTests.CloseContextEnabledTest.class
|
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public class TaskPropertiesTests {
|
public class TaskPropertiesTests {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
TaskProperties taskProperties;
|
TaskProperties taskProperties;
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() {
|
public void test() {
|
||||||
assertThat(taskProperties.getClosecontextEnabled(), is(false));
|
assertThat(this.taskProperties.getClosecontextEnabled()).isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@SpringBootTest(classes={TaskPropertiesTests.Config.class,
|
@SpringBootTest(classes = { TaskPropertiesTests.Config.class,
|
||||||
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class},
|
SimpleTaskAutoConfiguration.class,
|
||||||
properties = { "spring.cloud.task.closecontextEnabled=false" })
|
SingleTaskConfiguration.class }, properties = {
|
||||||
|
"spring.cloud.task.closecontextEnabled=false" })
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public static class CloseContextEnabledTest extends TaskPropertiesTests {}
|
public static class CloseContextEnabledTest extends TaskPropertiesTests {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
public static class Config {
|
public static class Config {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2016 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.configuration;
|
package org.springframework.cloud.task.configuration;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
@@ -63,27 +64,29 @@ public class TestConfiguration implements InitializingBean {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public TaskRepository taskRepository(){
|
public TaskRepository taskRepository() {
|
||||||
return new SimpleTaskRepository(this.taskExecutionDaoFactoryBean);
|
return new SimpleTaskRepository(this.taskExecutionDaoFactoryBean);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public PlatformTransactionManager transactionManager() {
|
public PlatformTransactionManager transactionManager() {
|
||||||
if(dataSource == null) {
|
if (this.dataSource == null) {
|
||||||
return new ResourcelessTransactionManager();
|
return new ResourcelessTransactionManager();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new DataSourceTransactionManager(dataSource);
|
return new DataSourceTransactionManager(this.dataSource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterPropertiesSet() throws Exception {
|
public void afterPropertiesSet() throws Exception {
|
||||||
if(this.dataSource != null) {
|
if (this.dataSource != null) {
|
||||||
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(this.dataSource);
|
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(
|
||||||
|
this.dataSource);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
|
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,24 @@
|
|||||||
/*
|
/*
|
||||||
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.listener;
|
package org.springframework.cloud.task.listener;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
@@ -31,24 +30,25 @@ public class TaskExceptionTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testTaskException() {
|
public void testTaskException() {
|
||||||
TaskException taskException = new TaskException(ERROR_MESSAGE);
|
TaskException taskException = new TaskException(ERROR_MESSAGE);
|
||||||
assertEquals(ERROR_MESSAGE, taskException.getMessage());
|
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
|
||||||
|
|
||||||
taskException = new TaskException(ERROR_MESSAGE,
|
taskException = new TaskException(ERROR_MESSAGE,
|
||||||
new IllegalStateException(ERROR_MESSAGE));
|
new IllegalStateException(ERROR_MESSAGE));
|
||||||
assertEquals(ERROR_MESSAGE, taskException.getMessage());
|
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
|
||||||
assertNotNull(taskException.getCause());
|
assertThat(taskException.getCause()).isNotNull();
|
||||||
assertEquals(ERROR_MESSAGE, taskException.getCause().getMessage());
|
assertThat(taskException.getCause().getMessage()).isEqualTo(ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTaskExecutionException() {
|
public void testTaskExecutionException() {
|
||||||
TaskExecutionException taskException = new TaskExecutionException(ERROR_MESSAGE);
|
TaskExecutionException taskException = new TaskExecutionException(ERROR_MESSAGE);
|
||||||
assertEquals(ERROR_MESSAGE, taskException.getMessage());
|
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
|
||||||
|
|
||||||
taskException = new TaskExecutionException(ERROR_MESSAGE,
|
taskException = new TaskExecutionException(ERROR_MESSAGE,
|
||||||
new IllegalStateException(ERROR_MESSAGE));
|
new IllegalStateException(ERROR_MESSAGE));
|
||||||
assertEquals(ERROR_MESSAGE, taskException.getMessage());
|
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
|
||||||
assertNotNull(taskException.getCause());
|
assertThat(taskException.getCause()).isNotNull();
|
||||||
assertEquals(ERROR_MESSAGE, taskException.getCause().getMessage());
|
assertThat(taskException.getCause().getMessage()).isEqualTo(ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -37,10 +37,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
|
|||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the TaskExecutionListener invocations occur at the appropriate task
|
* Verifies that the TaskExecutionListener invocations occur at the appropriate task
|
||||||
@@ -49,14 +46,17 @@ import static org.junit.Assert.assertTrue;
|
|||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
*/
|
*/
|
||||||
public class TaskExecutionListenerTests {
|
public class TaskExecutionListenerTests {
|
||||||
private AnnotationConfigApplicationContext context;
|
|
||||||
|
|
||||||
private static final String EXCEPTION_MESSAGE = "This was expected";
|
private static final String EXCEPTION_MESSAGE = "This was expected";
|
||||||
|
|
||||||
private static boolean beforeTaskDidFireOnError = false;
|
private static boolean beforeTaskDidFireOnError = false;
|
||||||
|
|
||||||
private static boolean endTaskDidFireOnError = false;
|
private static boolean endTaskDidFireOnError = false;
|
||||||
|
|
||||||
private static boolean failedTaskDidFireOnError = false;
|
private static boolean failedTaskDidFireOnError = false;
|
||||||
|
|
||||||
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
@BeforeTask
|
@BeforeTask
|
||||||
public void setup() {
|
public void setup() {
|
||||||
beforeTaskDidFireOnError = false;
|
beforeTaskDidFireOnError = false;
|
||||||
@@ -66,27 +66,29 @@ public class TaskExecutionListenerTests {
|
|||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
if(context != null && context.isActive()) {
|
if (this.context != null && this.context.isActive()) {
|
||||||
context.close();
|
this.context.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that if a TaskExecutionListener Bean is present that the onTaskStartup method
|
* Verify that if a TaskExecutionListener Bean is present that the onTaskStartup
|
||||||
* is called.
|
* method is called.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTaskCreate() {
|
public void testTaskCreate() {
|
||||||
setupContextForTaskExecutionListener();
|
setupContextForTaskExecutionListener();
|
||||||
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
|
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener = this.context
|
||||||
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
.getBean(
|
||||||
TaskExecution taskExecution = new TaskExecution(0, null, "wombat",
|
DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
||||||
new Date(), new Date(), null, new ArrayList<>(), null, null);
|
TaskExecution taskExecution = new TaskExecution(0, null, "wombat", new Date(),
|
||||||
verifyListenerResults(false, false, taskExecution,taskExecutionListener);
|
new Date(), null, new ArrayList<>(), null, null);
|
||||||
|
verifyListenerResults(false, false, taskExecution, taskExecutionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that if a LifecycleProcessor executes all TaskExecutionListeners if BeforeTask throws exception.
|
* Verify that if a LifecycleProcessor executes all TaskExecutionListeners if
|
||||||
|
* BeforeTask throws exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testBeforeTaskErrorCreate() {
|
public void testBeforeTaskErrorCreate() {
|
||||||
@@ -97,14 +99,18 @@ public class TaskExecutionListenerTests {
|
|||||||
catch (Exception exception) {
|
catch (Exception exception) {
|
||||||
exceptionFired = true;
|
exceptionFired = true;
|
||||||
}
|
}
|
||||||
assertTrue("Exception should have fired", exceptionFired);
|
assertThat(exceptionFired).as("Exception should have fired").isTrue();
|
||||||
assertTrue("BeforeTask Listener should have executed", beforeTaskDidFireOnError);
|
assertThat(beforeTaskDidFireOnError)
|
||||||
assertTrue("EndTask Listener should have executed", endTaskDidFireOnError);
|
.as("BeforeTask Listener should have executed").isTrue();
|
||||||
assertTrue("FailedTask Listener should have executed", failedTaskDidFireOnError);
|
assertThat(endTaskDidFireOnError).as("EndTask Listener should have executed")
|
||||||
|
.isTrue();
|
||||||
|
assertThat(failedTaskDidFireOnError)
|
||||||
|
.as("FailedTask Listener should have executed").isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that if a LifecycleProcessor executes AfterTask TaskExecutionListeners if FailedTask throws exception.
|
* Verify that if a LifecycleProcessor executes AfterTask TaskExecutionListeners if
|
||||||
|
* FailedTask throws exception.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testFailedTaskErrorCreate() {
|
public void testFailedTaskErrorCreate() {
|
||||||
@@ -115,42 +121,52 @@ public class TaskExecutionListenerTests {
|
|||||||
catch (Exception exception) {
|
catch (Exception exception) {
|
||||||
exceptionFired = true;
|
exceptionFired = true;
|
||||||
}
|
}
|
||||||
assertTrue("Exception should have fired", exceptionFired);
|
assertThat(exceptionFired).as("Exception should have fired").isTrue();
|
||||||
assertTrue("EndTask Listener should have executed", endTaskDidFireOnError);
|
assertThat(endTaskDidFireOnError).as("EndTask Listener should have executed")
|
||||||
assertTrue("FailedTask Listener should not have executed", failedTaskDidFireOnError);
|
.isTrue();
|
||||||
|
assertThat(failedTaskDidFireOnError)
|
||||||
|
.as("FailedTask Listener should not have executed").isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that if a LifecycleProcessor stores the correct exit code if AfterTask listener fails.
|
* Verify that if a LifecycleProcessor stores the correct exit code if AfterTask
|
||||||
|
* listener fails.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testAfterTaskErrorCreate() {
|
public void testAfterTaskErrorCreate() {
|
||||||
setupContextForAfterTaskErrorAnnotatedListener();
|
setupContextForAfterTaskErrorAnnotatedListener();
|
||||||
AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener taskExecutionListener =
|
AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener taskExecutionListener = this.context
|
||||||
context.getBean(AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener.class);
|
.getBean(
|
||||||
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
|
AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener.class);
|
||||||
|
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
|
||||||
|
new String[0], this.context));
|
||||||
|
|
||||||
assertTrue(taskExecutionListener.isTaskStartup());
|
assertThat(taskExecutionListener.isTaskStartup()).isTrue();
|
||||||
assertTrue(taskExecutionListener.isTaskEnd());
|
assertThat(taskExecutionListener.isTaskEnd()).isTrue();
|
||||||
assertEquals(TestListener.END_MESSAGE, taskExecutionListener.getTaskExecution().getExitMessage());
|
assertThat(taskExecutionListener.getTaskExecution().getExitMessage())
|
||||||
assertTrue(taskExecutionListener.getTaskExecution().getErrorMessage().contains("Failed to process @BeforeTask or @AfterTask annotation because: AfterTaskFailure"));
|
.isEqualTo(TestListener.END_MESSAGE);
|
||||||
assertNull(taskExecutionListener.getThrowable());
|
assertThat(taskExecutionListener.getTaskExecution().getErrorMessage().contains(
|
||||||
|
"Failed to process @BeforeTask or @AfterTask annotation because: AfterTaskFailure"))
|
||||||
|
.isTrue();
|
||||||
|
assertThat(taskExecutionListener.getThrowable()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify that if a TaskExecutionListener Bean is present that the onTaskEnd method
|
* Verify that if a TaskExecutionListener Bean is present that the onTaskEnd method is
|
||||||
* is called.
|
* called.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
public void testTaskUpdate() {
|
public void testTaskUpdate() {
|
||||||
setupContextForTaskExecutionListener();
|
setupContextForTaskExecutionListener();
|
||||||
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
|
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener = this.context
|
||||||
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
.getBean(
|
||||||
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
|
DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
||||||
|
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
|
||||||
|
new String[0], this.context));
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat",
|
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat", new Date(),
|
||||||
new Date(), new Date(), null, new ArrayList<>(), null, null);
|
new Date(), null, new ArrayList<>(), null, null);
|
||||||
verifyListenerResults(true, false, taskExecution,taskExecutionListener);
|
verifyListenerResults(true, false, taskExecution, taskExecutionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -162,14 +178,17 @@ public class TaskExecutionListenerTests {
|
|||||||
RuntimeException exception = new RuntimeException(EXCEPTION_MESSAGE);
|
RuntimeException exception = new RuntimeException(EXCEPTION_MESSAGE);
|
||||||
setupContextForTaskExecutionListener();
|
setupContextForTaskExecutionListener();
|
||||||
SpringApplication application = new SpringApplication();
|
SpringApplication application = new SpringApplication();
|
||||||
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
|
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener = this.context
|
||||||
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
.getBean(
|
||||||
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
|
DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
|
||||||
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
|
this.context.publishEvent(new ApplicationFailedEvent(application, new String[0],
|
||||||
|
this.context, exception));
|
||||||
|
this.context.publishEvent(
|
||||||
|
new ApplicationReadyEvent(application, new String[0], this.context));
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(0, 1, "wombat", new Date(),
|
TaskExecution taskExecution = new TaskExecution(0, 1, "wombat", new Date(),
|
||||||
new Date(), null, new ArrayList<>(), null, null);
|
new Date(), null, new ArrayList<>(), null, null);
|
||||||
verifyListenerResults(true, true, taskExecution,taskExecutionListener);
|
verifyListenerResults(true, true, taskExecution, taskExecutionListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -179,11 +198,11 @@ public class TaskExecutionListenerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testAnnotationCreate() {
|
public void testAnnotationCreate() {
|
||||||
setupContextForAnnotatedListener();
|
setupContextForAnnotatedListener();
|
||||||
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
|
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener = this.context
|
||||||
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
||||||
TaskExecution taskExecution = new TaskExecution(0, null, "wombat",
|
TaskExecution taskExecution = new TaskExecution(0, null, "wombat", new Date(),
|
||||||
new Date(), new Date(), null, new ArrayList<>(), null, null);
|
new Date(), null, new ArrayList<>(), null, null);
|
||||||
verifyListenerResults(false, false, taskExecution,annotatedListener);
|
verifyListenerResults(false, false, taskExecution, annotatedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -193,13 +212,14 @@ public class TaskExecutionListenerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testAnnotationUpdate() {
|
public void testAnnotationUpdate() {
|
||||||
setupContextForAnnotatedListener();
|
setupContextForAnnotatedListener();
|
||||||
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
|
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener = this.context
|
||||||
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
||||||
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
|
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
|
||||||
|
new String[0], this.context));
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat",
|
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat", new Date(),
|
||||||
new Date(), new Date(), null, new ArrayList<>(), null, null);
|
new Date(), null, new ArrayList<>(), null, null);
|
||||||
verifyListenerResults(true, false, taskExecution,annotatedListener);
|
verifyListenerResults(true, false, taskExecution, annotatedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -211,73 +231,91 @@ public class TaskExecutionListenerTests {
|
|||||||
RuntimeException exception = new RuntimeException(EXCEPTION_MESSAGE);
|
RuntimeException exception = new RuntimeException(EXCEPTION_MESSAGE);
|
||||||
setupContextForAnnotatedListener();
|
setupContextForAnnotatedListener();
|
||||||
SpringApplication application = new SpringApplication();
|
SpringApplication application = new SpringApplication();
|
||||||
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
|
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener = this.context
|
||||||
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
|
||||||
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
|
this.context.publishEvent(new ApplicationFailedEvent(application, new String[0],
|
||||||
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
|
this.context, exception));
|
||||||
|
this.context.publishEvent(
|
||||||
|
new ApplicationReadyEvent(application, new String[0], this.context));
|
||||||
|
|
||||||
TaskExecution taskExecution = new TaskExecution(0, 1, "wombat", new Date(),
|
TaskExecution taskExecution = new TaskExecution(0, 1, "wombat", new Date(),
|
||||||
new Date(), null, new ArrayList<>(), null, null);
|
new Date(), null, new ArrayList<>(), null, null);
|
||||||
verifyListenerResults(true, true, taskExecution,annotatedListener);
|
verifyListenerResults(true, true, taskExecution, annotatedListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyListenerResults(boolean isTaskEnd,
|
private void verifyListenerResults(boolean isTaskEnd, boolean isTaskFailed,
|
||||||
boolean isTaskFailed, TaskExecution taskExecution,
|
TaskExecution taskExecution, TestListener actualListener) {
|
||||||
TestListener actualListener){
|
assertThat(actualListener.isTaskStartup()).isTrue();
|
||||||
assertTrue(actualListener.isTaskStartup());
|
assertThat(actualListener.isTaskEnd()).isEqualTo(isTaskEnd);
|
||||||
assertEquals(isTaskEnd,actualListener.isTaskEnd());
|
assertThat(actualListener.isTaskFailed()).isEqualTo(isTaskFailed);
|
||||||
assertEquals(isTaskFailed,actualListener.isTaskFailed());
|
if (isTaskFailed) {
|
||||||
if(isTaskFailed){
|
assertThat(actualListener.getTaskExecution().getExitMessage())
|
||||||
assertEquals(TestListener.END_MESSAGE, actualListener.getTaskExecution().getExitMessage());
|
.isEqualTo(TestListener.END_MESSAGE);
|
||||||
assertNotNull(actualListener.getThrowable());
|
assertThat(actualListener.getThrowable()).isNotNull();
|
||||||
assertTrue(actualListener.getThrowable() instanceof RuntimeException);
|
assertThat(actualListener.getThrowable() instanceof RuntimeException)
|
||||||
assertTrue(actualListener.getTaskExecution().getErrorMessage().startsWith("java.lang.RuntimeException: This was expected"));
|
.isTrue();
|
||||||
|
assertThat(actualListener.getTaskExecution().getErrorMessage()
|
||||||
|
.startsWith("java.lang.RuntimeException: This was expected"))
|
||||||
|
.isTrue();
|
||||||
}
|
}
|
||||||
else if(isTaskEnd){
|
else if (isTaskEnd) {
|
||||||
assertEquals(TestListener.END_MESSAGE, actualListener.getTaskExecution().getExitMessage());
|
assertThat(actualListener.getTaskExecution().getExitMessage())
|
||||||
assertEquals(taskExecution.getErrorMessage(), actualListener.getTaskExecution().getErrorMessage());
|
.isEqualTo(TestListener.END_MESSAGE);
|
||||||
assertNull(actualListener.getThrowable());
|
assertThat(actualListener.getTaskExecution().getErrorMessage())
|
||||||
|
.isEqualTo(taskExecution.getErrorMessage());
|
||||||
|
assertThat(actualListener.getThrowable()).isNull();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assertEquals(TestListener.START_MESSAGE, actualListener.getTaskExecution().getExitMessage());
|
assertThat(actualListener.getTaskExecution().getExitMessage())
|
||||||
assertNull(actualListener.getTaskExecution().getErrorMessage());
|
.isEqualTo(TestListener.START_MESSAGE);
|
||||||
assertNull(actualListener.getThrowable());
|
assertThat(actualListener.getTaskExecution().getErrorMessage()).isNull();
|
||||||
|
assertThat(actualListener.getThrowable()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(taskExecution.getExecutionId(), actualListener.getTaskExecution().getExecutionId());
|
assertThat(actualListener.getTaskExecution().getExecutionId())
|
||||||
assertEquals(taskExecution.getExitCode(), actualListener.getTaskExecution().getExitCode());
|
.isEqualTo(taskExecution.getExecutionId());
|
||||||
assertEquals(taskExecution.getExternalExecutionId(), actualListener.getTaskExecution().getExternalExecutionId());
|
assertThat(actualListener.getTaskExecution().getExitCode())
|
||||||
|
.isEqualTo(taskExecution.getExitCode());
|
||||||
|
assertThat(actualListener.getTaskExecution().getExternalExecutionId())
|
||||||
|
.isEqualTo(taskExecution.getExternalExecutionId());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupContextForTaskExecutionListener(){
|
private void setupContextForTaskExecutionListener() {
|
||||||
context = new AnnotationConfigApplicationContext(DefaultTaskListenerConfiguration.class,
|
this.context = new AnnotationConfigApplicationContext(
|
||||||
|
DefaultTaskListenerConfiguration.class, TestDefaultConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.setId("testTask");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupContextForAnnotatedListener() {
|
||||||
|
this.context = new AnnotationConfigApplicationContext(
|
||||||
|
TestDefaultConfiguration.class, DefaultAnnotationConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
|
this.context.setId("annotatedTask");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setupContextForBeforeTaskErrorAnnotatedListener() {
|
||||||
|
this.context = new AnnotationConfigApplicationContext(
|
||||||
TestDefaultConfiguration.class,
|
TestDefaultConfiguration.class,
|
||||||
|
BeforeTaskErrorAnnotationConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
context.setId("testTask");
|
this.context.setId("beforeTaskAnnotatedTask");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupContextForAnnotatedListener(){
|
private void setupContextForFailedTaskErrorAnnotatedListener() {
|
||||||
context = new AnnotationConfigApplicationContext(TestDefaultConfiguration.class, DefaultAnnotationConfiguration.class,
|
this.context = new AnnotationConfigApplicationContext(
|
||||||
|
TestDefaultConfiguration.class,
|
||||||
|
FailedTaskErrorAnnotationConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
context.setId("annotatedTask");
|
this.context.setId("failedTaskAnnotatedTask");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupContextForBeforeTaskErrorAnnotatedListener(){
|
private void setupContextForAfterTaskErrorAnnotatedListener() {
|
||||||
context = new AnnotationConfigApplicationContext(TestDefaultConfiguration.class, BeforeTaskErrorAnnotationConfiguration.class,
|
this.context = new AnnotationConfigApplicationContext(
|
||||||
|
TestDefaultConfiguration.class,
|
||||||
|
AfterTaskErrorAnnotationConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
context.setId("beforeTaskAnnotatedTask");
|
this.context.setId("afterTaskAnnotatedTask");
|
||||||
}
|
|
||||||
|
|
||||||
private void setupContextForFailedTaskErrorAnnotatedListener(){
|
|
||||||
context = new AnnotationConfigApplicationContext(TestDefaultConfiguration.class, FailedTaskErrorAnnotationConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
|
||||||
context.setId("failedTaskAnnotatedTask");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setupContextForAfterTaskErrorAnnotatedListener(){
|
|
||||||
context = new AnnotationConfigApplicationContext(TestDefaultConfiguration.class, AfterTaskErrorAnnotationConfiguration.class,
|
|
||||||
PropertyPlaceholderAutoConfiguration.class);
|
|
||||||
context.setId("afterTaskAnnotatedTask");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -292,14 +330,14 @@ public class TaskExecutionListenerTests {
|
|||||||
|
|
||||||
@BeforeTask
|
@BeforeTask
|
||||||
public void methodA(TaskExecution taskExecution) {
|
public void methodA(TaskExecution taskExecution) {
|
||||||
isTaskStartup = true;
|
this.isTaskStartup = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.taskExecution.setExitMessage(START_MESSAGE);
|
this.taskExecution.setExitMessage(START_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTask
|
@AfterTask
|
||||||
public void methodB(TaskExecution taskExecution) {
|
public void methodB(TaskExecution taskExecution) {
|
||||||
isTaskEnd = true;
|
this.isTaskEnd = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.taskExecution.setExitMessage(END_MESSAGE);
|
this.taskExecution.setExitMessage(END_MESSAGE);
|
||||||
|
|
||||||
@@ -307,12 +345,14 @@ public class TaskExecutionListenerTests {
|
|||||||
|
|
||||||
@FailedTask
|
@FailedTask
|
||||||
public void methodC(TaskExecution taskExecution, Throwable throwable) {
|
public void methodC(TaskExecution taskExecution, Throwable throwable) {
|
||||||
isTaskFailed = true;
|
this.isTaskFailed = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.throwable = throwable;
|
this.throwable = throwable;
|
||||||
this.taskExecution.setExitMessage(ERROR_MESSAGE);
|
this.taskExecution.setExitMessage(ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -345,7 +385,9 @@ public class TaskExecutionListenerTests {
|
|||||||
public void methodC(TaskExecution taskExecution, Throwable throwable) {
|
public void methodC(TaskExecution taskExecution, Throwable throwable) {
|
||||||
failedTaskDidFireOnError = true;
|
failedTaskDidFireOnError = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -356,7 +398,6 @@ public class TaskExecutionListenerTests {
|
|||||||
return new AnnotatedTaskListener();
|
return new AnnotatedTaskListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static class AnnotatedTaskListener {
|
public static class AnnotatedTaskListener {
|
||||||
|
|
||||||
@BeforeTask
|
@BeforeTask
|
||||||
@@ -375,7 +416,9 @@ public class TaskExecutionListenerTests {
|
|||||||
failedTaskDidFireOnError = true;
|
failedTaskDidFireOnError = true;
|
||||||
throw new TaskExecutionException("FailedTaskFailure");
|
throw new TaskExecutionException("FailedTaskFailure");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -386,21 +429,23 @@ public class TaskExecutionListenerTests {
|
|||||||
return new AnnotatedTaskListener();
|
return new AnnotatedTaskListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AnnotatedTaskListener extends TestListener{
|
public static class AnnotatedTaskListener extends TestListener {
|
||||||
|
|
||||||
@BeforeTask
|
@BeforeTask
|
||||||
public void methodA(TaskExecution taskExecution) {
|
public void methodA(TaskExecution taskExecution) {
|
||||||
isTaskStartup = true;
|
this.isTaskStartup = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTask
|
@AfterTask
|
||||||
public void methodB(TaskExecution taskExecution) {
|
public void methodB(TaskExecution taskExecution) {
|
||||||
isTaskEnd = true;
|
this.isTaskEnd = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.taskExecution.setExitMessage(END_MESSAGE);
|
this.taskExecution.setExitMessage(END_MESSAGE);
|
||||||
throw new TaskExecutionException("AfterTaskFailure");
|
throw new TaskExecutionException("AfterTaskFailure");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -411,31 +456,33 @@ public class TaskExecutionListenerTests {
|
|||||||
return new TestTaskExecutionListener();
|
return new TestTaskExecutionListener();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TestTaskExecutionListener extends TestListener implements TaskExecutionListener {
|
public static class TestTaskExecutionListener extends TestListener
|
||||||
|
implements TaskExecutionListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskStartup(TaskExecution taskExecution) {
|
public void onTaskStartup(TaskExecution taskExecution) {
|
||||||
isTaskStartup = true;
|
this.isTaskStartup = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.taskExecution.setExitMessage(START_MESSAGE);
|
this.taskExecution.setExitMessage(START_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskEnd(TaskExecution taskExecution) {
|
public void onTaskEnd(TaskExecution taskExecution) {
|
||||||
isTaskEnd = true;
|
this.isTaskEnd = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.taskExecution.setExitMessage(END_MESSAGE);
|
this.taskExecution.setExitMessage(END_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
||||||
isTaskFailed = true;
|
this.isTaskFailed = true;
|
||||||
this.taskExecution = taskExecution;
|
this.taskExecution = taskExecution;
|
||||||
this.throwable = throwable;
|
this.throwable = throwable;
|
||||||
this.taskExecution.setExitMessage(ERROR_MESSAGE);
|
this.taskExecution.setExitMessage(ERROR_MESSAGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -51,32 +51,30 @@ import org.springframework.data.domain.Page;
|
|||||||
import org.springframework.data.domain.PageRequest;
|
import org.springframework.data.domain.PageRequest;
|
||||||
import org.springframework.data.domain.Sort;
|
import org.springframework.data.domain.Sort;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verifies that the TaskLifecycleListener Methods record the appropriate log header entries and
|
* Verifies that the TaskLifecycleListener Methods record the appropriate log header
|
||||||
* result codes.
|
* entries and result codes.
|
||||||
*
|
*
|
||||||
* @author Glenn Renfro
|
* @author Glenn Renfro
|
||||||
* @author Michael Minella
|
* @author Michael Minella
|
||||||
*/
|
*/
|
||||||
public class TaskLifecycleListenerTests {
|
public class TaskLifecycleListenerTests {
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
public OutputCapture outputCapture = new OutputCapture();
|
||||||
|
|
||||||
private AnnotationConfigApplicationContext context;
|
private AnnotationConfigApplicationContext context;
|
||||||
|
|
||||||
private TaskExplorer taskExplorer;
|
private TaskExplorer taskExplorer;
|
||||||
|
|
||||||
@Rule
|
|
||||||
public OutputCapture outputCapture = new OutputCapture();
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
context = new AnnotationConfigApplicationContext();
|
this.context = new AnnotationConfigApplicationContext();
|
||||||
context.setId("testTask");
|
this.context.setId("testTask");
|
||||||
context.register(TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
|
this.context.register(TestDefaultConfiguration.class,
|
||||||
|
PropertyPlaceholderAutoConfiguration.class);
|
||||||
TestListener.getStartupOrderList().clear();
|
TestListener.getStartupOrderList().clear();
|
||||||
TestListener.getFailOrderList().clear();
|
TestListener.getFailOrderList().clear();
|
||||||
TestListener.getEndOrderList().clear();
|
TestListener.getEndOrderList().clear();
|
||||||
@@ -85,44 +83,47 @@ public class TaskLifecycleListenerTests {
|
|||||||
|
|
||||||
@After
|
@After
|
||||||
public void tearDown() {
|
public void tearDown() {
|
||||||
if(context != null && context.isActive()) {
|
if (this.context != null && this.context.isActive()) {
|
||||||
context.close();
|
this.context.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTaskCreate() {
|
public void testTaskCreate() {
|
||||||
context.refresh();
|
this.context.refresh();
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
verifyTaskExecution(0, false);
|
verifyTaskExecution(0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTaskCreateWithArgs() {
|
public void testTaskCreateWithArgs() {
|
||||||
context.register(ArgsConfiguration.class);
|
this.context.register(ArgsConfiguration.class);
|
||||||
context.refresh();
|
this.context.refresh();
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
verifyTaskExecution(2, false);
|
verifyTaskExecution(2, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTaskUpdate() {
|
public void testTaskUpdate() {
|
||||||
context.refresh();
|
this.context.refresh();
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
|
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
|
||||||
|
new String[0], this.context));
|
||||||
|
|
||||||
verifyTaskExecution(0, true, 0);
|
verifyTaskExecution(0, true, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testTaskFailedUpdate() {
|
public void testTaskFailedUpdate() {
|
||||||
context.refresh();
|
this.context.refresh();
|
||||||
RuntimeException exception = new RuntimeException("This was expected");
|
RuntimeException exception = new RuntimeException("This was expected");
|
||||||
SpringApplication application = new SpringApplication();
|
SpringApplication application = new SpringApplication();
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
|
this.context.publishEvent(new ApplicationFailedEvent(application, new String[0],
|
||||||
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
|
this.context, exception));
|
||||||
|
this.context.publishEvent(
|
||||||
|
new ApplicationReadyEvent(application, new String[0], this.context));
|
||||||
|
|
||||||
verifyTaskExecution(0, true, 1, exception, null);
|
verifyTaskExecution(0, true, 1, exception, null);
|
||||||
}
|
}
|
||||||
@@ -130,38 +131,44 @@ public class TaskLifecycleListenerTests {
|
|||||||
@Test
|
@Test
|
||||||
public void testTaskFailedWithExitCodeEvent() {
|
public void testTaskFailedWithExitCodeEvent() {
|
||||||
final int exitCode = 10;
|
final int exitCode = 10;
|
||||||
context.register(TestListener.class);
|
this.context.register(TestListener.class);
|
||||||
context.register(TestListener2.class);
|
this.context.register(TestListener2.class);
|
||||||
|
|
||||||
context.refresh();
|
this.context.refresh();
|
||||||
RuntimeException exception = new RuntimeException("This was expected");
|
RuntimeException exception = new RuntimeException("This was expected");
|
||||||
SpringApplication application = new SpringApplication();
|
SpringApplication application = new SpringApplication();
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
context.publishEvent(new ExitCodeEvent(context, exitCode));
|
this.context.publishEvent(new ExitCodeEvent(this.context, exitCode));
|
||||||
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
|
this.context.publishEvent(new ApplicationFailedEvent(application, new String[0],
|
||||||
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
|
this.context, exception));
|
||||||
|
this.context.publishEvent(
|
||||||
|
new ApplicationReadyEvent(application, new String[0], this.context));
|
||||||
|
|
||||||
verifyTaskExecution(0, true, exitCode, exception, null);
|
verifyTaskExecution(0, true, exitCode, exception, null);
|
||||||
assertEquals(2, TestListener.getStartupOrderList().size());
|
assertThat(TestListener.getStartupOrderList().size()).isEqualTo(2);
|
||||||
assertEquals(Integer.valueOf(2), TestListener.getStartupOrderList().get(0));
|
assertThat(TestListener.getStartupOrderList().get(0))
|
||||||
assertEquals(Integer.valueOf(1), TestListener.getStartupOrderList().get(1));
|
.isEqualTo(Integer.valueOf(2));
|
||||||
|
assertThat(TestListener.getStartupOrderList().get(1))
|
||||||
|
.isEqualTo(Integer.valueOf(1));
|
||||||
|
|
||||||
assertEquals(2, TestListener.getEndOrderList().size());
|
assertThat(TestListener.getEndOrderList().size()).isEqualTo(2);
|
||||||
assertEquals(Integer.valueOf(1), TestListener.getEndOrderList().get(0));
|
assertThat(TestListener.getEndOrderList().get(0)).isEqualTo(Integer.valueOf(1));
|
||||||
assertEquals(Integer.valueOf(2), TestListener.getEndOrderList().get(1));
|
assertThat(TestListener.getEndOrderList().get(1)).isEqualTo(Integer.valueOf(2));
|
||||||
|
|
||||||
assertEquals(2, TestListener.getFailOrderList().size());
|
assertThat(TestListener.getFailOrderList().size()).isEqualTo(2);
|
||||||
assertEquals(Integer.valueOf(1), TestListener.getFailOrderList().get(0));
|
assertThat(TestListener.getFailOrderList().get(0)).isEqualTo(Integer.valueOf(1));
|
||||||
assertEquals(Integer.valueOf(2), TestListener.getFailOrderList().get(1));
|
assertThat(TestListener.getFailOrderList().get(1)).isEqualTo(Integer.valueOf(2));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoClosingOfContext() {
|
public void testNoClosingOfContext() {
|
||||||
|
|
||||||
try (ConfigurableApplicationContext applicationContext = SpringApplication.run(new Class[] {TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class},
|
try (ConfigurableApplicationContext applicationContext = SpringApplication.run(
|
||||||
new String[] {"--spring.cloud.task.closecontext_enabled=false"})) {
|
new Class[] { TestDefaultConfiguration.class,
|
||||||
assertTrue(applicationContext.isActive());
|
PropertyPlaceholderAutoConfiguration.class },
|
||||||
|
new String[] { "--spring.cloud.task.closecontext_enabled=false" })) {
|
||||||
|
assertThat(applicationContext.isActive()).isTrue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,20 +178,21 @@ public class TaskLifecycleListenerTests {
|
|||||||
MutablePropertySources propertySources = environment.getPropertySources();
|
MutablePropertySources propertySources = environment.getPropertySources();
|
||||||
Map<String, Object> myMap = new HashMap<>();
|
Map<String, Object> myMap = new HashMap<>();
|
||||||
myMap.put("spring.cloud.task.executionid", "55");
|
myMap.put("spring.cloud.task.executionid", "55");
|
||||||
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
|
propertySources
|
||||||
context.setEnvironment(environment);
|
.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
|
||||||
context.refresh();
|
this.context.setEnvironment(environment);
|
||||||
|
this.context.refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testRestartExistingTask() {
|
public void testRestartExistingTask() {
|
||||||
context.refresh();
|
this.context.refresh();
|
||||||
TaskLifecycleListener taskLifecycleListener =
|
TaskLifecycleListener taskLifecycleListener = this.context
|
||||||
context.getBean(TaskLifecycleListener.class);
|
.getBean(TaskLifecycleListener.class);
|
||||||
taskLifecycleListener.start();
|
taskLifecycleListener.start();
|
||||||
String output = this.outputCapture.toString();
|
String output = this.outputCapture.toString();
|
||||||
assertTrue("Test results do not show error message: " + output,
|
assertThat(output.contains("Multiple start events have been received"))
|
||||||
output.contains("Multiple start events have been received"));
|
.as("Test results do not show error message: " + output).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -193,10 +201,11 @@ public class TaskLifecycleListenerTests {
|
|||||||
MutablePropertySources propertySources = environment.getPropertySources();
|
MutablePropertySources propertySources = environment.getPropertySources();
|
||||||
Map<String, Object> myMap = new HashMap<>();
|
Map<String, Object> myMap = new HashMap<>();
|
||||||
myMap.put("spring.cloud.task.external-execution-id", "myid");
|
myMap.put("spring.cloud.task.external-execution-id", "myid");
|
||||||
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
|
propertySources
|
||||||
context.setEnvironment(environment);
|
.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
|
||||||
context.refresh();
|
this.context.setEnvironment(environment);
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.context.refresh();
|
||||||
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
verifyTaskExecution(0, false, null, null, "myid");
|
verifyTaskExecution(0, false, null, null, "myid");
|
||||||
}
|
}
|
||||||
@@ -207,15 +216,17 @@ public class TaskLifecycleListenerTests {
|
|||||||
MutablePropertySources propertySources = environment.getPropertySources();
|
MutablePropertySources propertySources = environment.getPropertySources();
|
||||||
Map<String, Object> myMap = new HashMap<>();
|
Map<String, Object> myMap = new HashMap<>();
|
||||||
myMap.put("spring.cloud.task.parentExecutionId", 789);
|
myMap.put("spring.cloud.task.parentExecutionId", 789);
|
||||||
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
|
propertySources
|
||||||
context.setEnvironment(environment);
|
.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
|
||||||
context.refresh();
|
this.context.setEnvironment(environment);
|
||||||
this.taskExplorer = context.getBean(TaskExplorer.class);
|
this.context.refresh();
|
||||||
|
this.taskExplorer = this.context.getBean(TaskExplorer.class);
|
||||||
|
|
||||||
verifyTaskExecution(0, false, null, null, null, 789L);
|
verifyTaskExecution(0, false, null, null, null, 789L);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyTaskExecution(int numberOfParams, boolean update, Integer exitCode) {
|
private void verifyTaskExecution(int numberOfParams, boolean update,
|
||||||
|
Integer exitCode) {
|
||||||
verifyTaskExecution(numberOfParams, update, exitCode, null, null);
|
verifyTaskExecution(numberOfParams, update, exitCode, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -223,47 +234,48 @@ public class TaskLifecycleListenerTests {
|
|||||||
verifyTaskExecution(numberOfParams, update, null, null, null);
|
verifyTaskExecution(numberOfParams, update, null, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyTaskExecution(int numberOfParams, boolean update,
|
private void verifyTaskExecution(int numberOfParams, boolean update, Integer exitCode,
|
||||||
Integer exitCode, Throwable exception, String externalExecutionId) {
|
Throwable exception, String externalExecutionId) {
|
||||||
verifyTaskExecution(numberOfParams, update, exitCode, exception,
|
verifyTaskExecution(numberOfParams, update, exitCode, exception,
|
||||||
externalExecutionId, null);
|
externalExecutionId, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyTaskExecution(int numberOfParams, boolean update,
|
private void verifyTaskExecution(int numberOfParams, boolean update, Integer exitCode,
|
||||||
Integer exitCode, Throwable exception, String externalExecutionId,
|
Throwable exception, String externalExecutionId, Long parentExecutionId) {
|
||||||
Long parentExecutionId) {
|
|
||||||
|
|
||||||
Sort sort = Sort.by("id");
|
Sort sort = Sort.by("id");
|
||||||
|
|
||||||
PageRequest request = PageRequest.of(0, Integer.MAX_VALUE, sort);
|
PageRequest request = PageRequest.of(0, Integer.MAX_VALUE, sort);
|
||||||
|
|
||||||
Page<TaskExecution> taskExecutionsByName = this.taskExplorer.findTaskExecutionsByName("testTask",
|
Page<TaskExecution> taskExecutionsByName = this.taskExplorer
|
||||||
request);
|
.findTaskExecutionsByName("testTask", request);
|
||||||
assertTrue(taskExecutionsByName.iterator().hasNext());
|
assertThat(taskExecutionsByName.iterator().hasNext()).isTrue();
|
||||||
TaskExecution taskExecution = taskExecutionsByName.iterator().next();
|
TaskExecution taskExecution = taskExecutionsByName.iterator().next();
|
||||||
|
|
||||||
assertEquals(numberOfParams, taskExecution.getArguments().size());
|
assertThat(taskExecution.getArguments().size()).isEqualTo(numberOfParams);
|
||||||
assertEquals(exitCode, taskExecution.getExitCode());
|
assertThat(taskExecution.getExitCode()).isEqualTo(exitCode);
|
||||||
assertEquals(externalExecutionId, taskExecution.getExternalExecutionId());
|
assertThat(taskExecution.getExternalExecutionId()).isEqualTo(externalExecutionId);
|
||||||
assertEquals(parentExecutionId, taskExecution.getParentExecutionId());
|
assertThat(taskExecution.getParentExecutionId()).isEqualTo(parentExecutionId);
|
||||||
|
|
||||||
if(exception != null) {
|
if (exception != null) {
|
||||||
assertTrue(taskExecution.getErrorMessage().length() > exception.getStackTrace().length);
|
assertThat(taskExecution.getErrorMessage()
|
||||||
|
.length() > exception.getStackTrace().length).isTrue();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assertNull(taskExecution.getExitMessage());
|
assertThat(taskExecution.getExitMessage()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(update) {
|
if (update) {
|
||||||
assertTrue(taskExecution.getEndTime().getTime() >= taskExecution.getStartTime().getTime());
|
assertThat(taskExecution.getEndTime().getTime() >= taskExecution
|
||||||
assertNotNull(taskExecution.getExitCode());
|
.getStartTime().getTime()).isTrue();
|
||||||
|
assertThat(taskExecution.getExitCode()).isNotNull();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
assertNull(taskExecution.getEndTime());
|
assertThat(taskExecution.getEndTime()).isNull();
|
||||||
assertTrue(taskExecution.getExitCode() == null);
|
assertThat(taskExecution.getExitCode() == null).isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("testTask", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("testTask");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Configuration
|
@Configuration
|
||||||
@@ -278,23 +290,25 @@ public class TaskLifecycleListenerTests {
|
|||||||
|
|
||||||
return new SimpleApplicationArgs(args);
|
return new SimpleApplicationArgs(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SimpleApplicationArgs implements ApplicationArguments {
|
private static class SimpleApplicationArgs implements ApplicationArguments {
|
||||||
|
|
||||||
private Map<String, String> args;
|
private Map<String, String> args;
|
||||||
|
|
||||||
public SimpleApplicationArgs(Map<String, String> args) {
|
SimpleApplicationArgs(Map<String, String> args) {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getSourceArgs() {
|
public String[] getSourceArgs() {
|
||||||
String [] sourceArgs = new String[this.args.size()];
|
String[] sourceArgs = new String[this.args.size()];
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (Map.Entry<String, String> stringStringEntry : args.entrySet()) {
|
for (Map.Entry<String, String> stringStringEntry : this.args.entrySet()) {
|
||||||
sourceArgs[i] = "--" + stringStringEntry.getKey() + "=" + stringStringEntry.getValue();
|
sourceArgs[i] = "--" + stringStringEntry.getKey() + "="
|
||||||
|
+ stringStringEntry.getValue();
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -320,6 +334,7 @@ public class TaskLifecycleListenerTests {
|
|||||||
public List<String> getNonOptionArgs() {
|
public List<String> getNonOptionArgs() {
|
||||||
throw new UnsupportedOperationException("Not supported at this time.");
|
throw new UnsupportedOperationException("Not supported at this time.");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class TestListener2 extends TestListener {
|
private static class TestListener2 extends TestListener {
|
||||||
@@ -328,34 +343,17 @@ public class TaskLifecycleListenerTests {
|
|||||||
|
|
||||||
private static class TestListener implements TaskExecutionListener {
|
private static class TestListener implements TaskExecutionListener {
|
||||||
|
|
||||||
|
static List<Integer> startupOrderList = new ArrayList<>();
|
||||||
|
static List<Integer> endOrderList = new ArrayList<>();
|
||||||
|
static List<Integer> failOrderList = new ArrayList<>();
|
||||||
|
|
||||||
private static int currentCount = 0;
|
private static int currentCount = 0;
|
||||||
|
|
||||||
private int id = 0;
|
private int id = 0;
|
||||||
|
|
||||||
static List<Integer> startupOrderList = new ArrayList<>();
|
TestListener() {
|
||||||
|
|
||||||
static List<Integer> endOrderList = new ArrayList<>();
|
|
||||||
|
|
||||||
static List<Integer> failOrderList = new ArrayList<>();
|
|
||||||
|
|
||||||
public TestListener() {
|
|
||||||
currentCount++;
|
currentCount++;
|
||||||
id = currentCount;
|
this.id = currentCount;
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTaskStartup(TaskExecution taskExecution) {
|
|
||||||
startupOrderList.add(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTaskEnd(TaskExecution taskExecution) {
|
|
||||||
endOrderList.add(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
|
||||||
failOrderList.add(id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Integer> getStartupOrderList() {
|
public static List<Integer> getStartupOrderList() {
|
||||||
@@ -369,5 +367,22 @@ public class TaskLifecycleListenerTests {
|
|||||||
public static List<Integer> getFailOrderList() {
|
public static List<Integer> getFailOrderList() {
|
||||||
return failOrderList;
|
return failOrderList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskStartup(TaskExecution taskExecution) {
|
||||||
|
startupOrderList.add(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskEnd(TaskExecution taskExecution) {
|
||||||
|
endOrderList.add(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
||||||
|
failOrderList.add(this.id);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* 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
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.cloud.task.listener;
|
package org.springframework.cloud.task.listener;
|
||||||
@@ -46,7 +46,8 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||||||
* @since 2.1.0
|
* @since 2.1.0
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = { TaskListenerExecutorObjectFactoryTests.TaskExecutionListenerConfiguration.class })
|
@ContextConfiguration(classes = {
|
||||||
|
TaskListenerExecutorObjectFactoryTests.TaskExecutionListenerConfiguration.class })
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public class TaskListenerExecutorObjectFactoryTests {
|
public class TaskListenerExecutorObjectFactoryTests {
|
||||||
|
|
||||||
@@ -68,13 +69,15 @@ public class TaskListenerExecutorObjectFactoryTests {
|
|||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
taskExecutionListenerResults.clear();
|
taskExecutionListenerResults.clear();
|
||||||
this.taskListenerExecutorObjectFactory = new TaskListenerExecutorObjectFactory(this.context);
|
this.taskListenerExecutorObjectFactory = new TaskListenerExecutorObjectFactory(
|
||||||
|
this.context);
|
||||||
this.taskListenerExecutor = this.taskListenerExecutorObjectFactory.getObject();
|
this.taskListenerExecutor = this.taskListenerExecutorObjectFactory.getObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyTaskStartupListener() {
|
public void verifyTaskStartupListener() {
|
||||||
this.taskListenerExecutor.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
|
this.taskListenerExecutor
|
||||||
|
.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
|
||||||
validateSingleEntry(BEFORE_LISTENER);
|
validateSingleEntry(BEFORE_LISTENER);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,14 +96,18 @@ public class TaskListenerExecutorObjectFactoryTests {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void verifyAllListener() {
|
public void verifyAllListener() {
|
||||||
this.taskListenerExecutor.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
|
this.taskListenerExecutor
|
||||||
|
.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
|
||||||
this.taskListenerExecutor.onTaskFailed(createSampleTaskExecution(FAIL_LISTENER),
|
this.taskListenerExecutor.onTaskFailed(createSampleTaskExecution(FAIL_LISTENER),
|
||||||
new IllegalStateException("oops"));
|
new IllegalStateException("oops"));
|
||||||
this.taskListenerExecutor.onTaskEnd(createSampleTaskExecution(AFTER_LISTENER));
|
this.taskListenerExecutor.onTaskEnd(createSampleTaskExecution(AFTER_LISTENER));
|
||||||
assertThat(taskExecutionListenerResults.size()).isEqualTo(3);
|
assertThat(taskExecutionListenerResults.size()).isEqualTo(3);
|
||||||
assertThat(taskExecutionListenerResults.get(0).getTaskName()).isEqualTo(BEFORE_LISTENER);
|
assertThat(taskExecutionListenerResults.get(0).getTaskName())
|
||||||
assertThat(taskExecutionListenerResults.get(1).getTaskName()).isEqualTo(FAIL_LISTENER);
|
.isEqualTo(BEFORE_LISTENER);
|
||||||
assertThat(taskExecutionListenerResults.get(2).getTaskName()).isEqualTo(AFTER_LISTENER);
|
assertThat(taskExecutionListenerResults.get(1).getTaskName())
|
||||||
|
.isEqualTo(FAIL_LISTENER);
|
||||||
|
assertThat(taskExecutionListenerResults.get(2).getTaskName())
|
||||||
|
.isEqualTo(AFTER_LISTENER);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskExecution createSampleTaskExecution(String taskName) {
|
private TaskExecution createSampleTaskExecution(String taskName) {
|
||||||
@@ -121,23 +128,29 @@ public class TaskListenerExecutorObjectFactoryTests {
|
|||||||
public TaskRunComponent taskRunComponent() {
|
public TaskRunComponent taskRunComponent() {
|
||||||
return new TaskRunComponent();
|
return new TaskRunComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class TaskRunComponent {
|
public static class TaskRunComponent {
|
||||||
|
|
||||||
@BeforeTask
|
@BeforeTask
|
||||||
public void initBeforeListener(TaskExecution taskExecution) {
|
public void initBeforeListener(TaskExecution taskExecution) {
|
||||||
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
|
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults
|
||||||
|
.add(taskExecution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@AfterTask
|
@AfterTask
|
||||||
public void initAfterListener(TaskExecution taskExecution) {
|
public void initAfterListener(TaskExecution taskExecution) {
|
||||||
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
|
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults
|
||||||
|
.add(taskExecution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@FailedTask
|
@FailedTask
|
||||||
public void initFailedListener(TaskExecution taskExecution, Throwable exception) {
|
public void initFailedListener(TaskExecution taskExecution, Throwable exception) {
|
||||||
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
|
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults
|
||||||
|
.add(taskExecution);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* 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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -18,22 +18,20 @@ package org.springframework.cloud.task.repository.dao;
|
|||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.GregorianCalendar;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.cloud.task.repository.TaskExecution;
|
import org.springframework.cloud.task.repository.TaskExecution;
|
||||||
import org.springframework.test.annotation.DirtiesContext;
|
import org.springframework.test.annotation.DirtiesContext;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.assertj.core.api.Assertions.fail;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines test cases that shall be shared between {@link JdbcTaskExecutionDaoTests} and {@link MapTaskExecutionDaoTests}.
|
* Defines test cases that shall be shared between {@link JdbcTaskExecutionDaoTests} and
|
||||||
|
* {@link MapTaskExecutionDaoTests}.
|
||||||
*
|
*
|
||||||
* @author Gunnar Hillert
|
* @author Gunnar Hillert
|
||||||
*/
|
*/
|
||||||
@@ -43,12 +41,13 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionsByTaskNamesWithNullParameter() {
|
public void getLatestTaskExecutionsByTaskNamesWithNullParameter() {
|
||||||
try {
|
try {
|
||||||
dao.getLatestTaskExecutionsByTaskNames(null);
|
this.dao.getLatestTaskExecutionsByTaskNames(null);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
assertEquals("At least 1 task name must be provided.", e.getMessage());
|
assertThat(e.getMessage())
|
||||||
|
.isEqualTo("At least 1 task name must be provided.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected an IllegalArgumentException to be thrown.");
|
fail("Expected an IllegalArgumentException to be thrown.");
|
||||||
@@ -56,12 +55,13 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionsByTaskNamesWithEmptyArrayParameter() {
|
public void getLatestTaskExecutionsByTaskNamesWithEmptyArrayParameter() {
|
||||||
try {
|
try {
|
||||||
dao.getLatestTaskExecutionsByTaskNames(new String[0]);
|
this.dao.getLatestTaskExecutionsByTaskNames(new String[0]);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
assertEquals("At least 1 task name must be provided.", e.getMessage());
|
assertThat(e.getMessage())
|
||||||
|
.isEqualTo("At least 1 task name must be provided.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected an IllegalArgumentException to be thrown.");
|
fail("Expected an IllegalArgumentException to be thrown.");
|
||||||
@@ -69,12 +69,13 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionsByTaskNamesWithArrayParametersContainingNullAndEmptyValues() {
|
public void getLatestTaskExecutionsByTaskNamesWithArrayParametersContainingNullAndEmptyValues() {
|
||||||
try {
|
try {
|
||||||
dao.getLatestTaskExecutionsByTaskNames("foo", null, "bar", " ");
|
this.dao.getLatestTaskExecutionsByTaskNames("foo", null, "bar", " ");
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
assertEquals("Task names must not contain any empty elements but 2 of 4 were empty or null.", e.getMessage());
|
assertThat(e.getMessage()).isEqualTo(
|
||||||
|
"Task names must not contain any empty elements but 2 of 4 were empty or null.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected an IllegalArgumentException to be thrown.");
|
fail("Expected an IllegalArgumentException to be thrown.");
|
||||||
@@ -82,95 +83,105 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionsByTaskNamesWithSingleTaskName() {
|
public void getLatestTaskExecutionsByTaskNamesWithSingleTaskName() {
|
||||||
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
final List<TaskExecution> latestTaskExecutions = dao.getLatestTaskExecutionsByTaskNames("FOO1");
|
final List<TaskExecution> latestTaskExecutions = this.dao
|
||||||
assertTrue("Expected only 1 taskExecution but got " + latestTaskExecutions.size(), latestTaskExecutions.size() == 1);
|
.getLatestTaskExecutionsByTaskNames("FOO1");
|
||||||
|
assertThat(latestTaskExecutions.size() == 1).as(
|
||||||
|
"Expected only 1 taskExecution but got " + latestTaskExecutions.size())
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
final TaskExecution lastTaskExecution = latestTaskExecutions.get(0);
|
final TaskExecution lastTaskExecution = latestTaskExecutions.get(0);
|
||||||
assertEquals("FOO1", lastTaskExecution.getTaskName());
|
assertThat(lastTaskExecution.getTaskName()).isEqualTo("FOO1");
|
||||||
|
|
||||||
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTime.setTime(lastTaskExecution.getStartTime());
|
dateTime.setTime(lastTaskExecution.getStartTime());
|
||||||
|
|
||||||
assertEquals(2015, dateTime.get(Calendar.YEAR));
|
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
|
||||||
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
|
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
|
||||||
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
|
||||||
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
|
||||||
assertEquals(59, dateTime.get(Calendar.MINUTE));
|
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
|
||||||
assertEquals(0, dateTime.get(Calendar.SECOND));
|
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionsByTaskNamesWithMultipleTaskNames() {
|
public void getLatestTaskExecutionsByTaskNamesWithMultipleTaskNames() {
|
||||||
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
final List<TaskExecution> latestTaskExecutions = dao.getLatestTaskExecutionsByTaskNames("FOO1", "FOO3", "FOO4");
|
final List<TaskExecution> latestTaskExecutions = this.dao
|
||||||
assertTrue("Expected 3 taskExecutions but got " + latestTaskExecutions.size(), latestTaskExecutions.size() == 3);
|
.getLatestTaskExecutionsByTaskNames("FOO1", "FOO3", "FOO4");
|
||||||
|
assertThat(latestTaskExecutions.size() == 3)
|
||||||
|
.as("Expected 3 taskExecutions but got " + latestTaskExecutions.size())
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
final Calendar dateTimeFoo3 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTimeFoo3 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTimeFoo3.setTime(latestTaskExecutions.get(0).getStartTime());
|
dateTimeFoo3.setTime(latestTaskExecutions.get(0).getStartTime());
|
||||||
|
|
||||||
assertEquals(2016, dateTimeFoo3.get(Calendar.YEAR));
|
assertThat(dateTimeFoo3.get(Calendar.YEAR)).isEqualTo(2016);
|
||||||
assertEquals(8, dateTimeFoo3.get(Calendar.MONTH) + 1);
|
assertThat(dateTimeFoo3.get(Calendar.MONTH) + 1).isEqualTo(8);
|
||||||
assertEquals(20, dateTimeFoo3.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTimeFoo3.get(Calendar.DAY_OF_MONTH)).isEqualTo(20);
|
||||||
assertEquals(14, dateTimeFoo3.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTimeFoo3.get(Calendar.HOUR_OF_DAY)).isEqualTo(14);
|
||||||
assertEquals(45, dateTimeFoo3.get(Calendar.MINUTE));
|
assertThat(dateTimeFoo3.get(Calendar.MINUTE)).isEqualTo(45);
|
||||||
assertEquals(0, dateTimeFoo3.get(Calendar.SECOND));
|
assertThat(dateTimeFoo3.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
|
|
||||||
final Calendar dateTimeFoo1 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTimeFoo1 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTimeFoo1.setTime(latestTaskExecutions.get(1).getStartTime());
|
dateTimeFoo1.setTime(latestTaskExecutions.get(1).getStartTime());
|
||||||
|
|
||||||
assertEquals(2015, dateTimeFoo1.get(Calendar.YEAR));
|
assertThat(dateTimeFoo1.get(Calendar.YEAR)).isEqualTo(2015);
|
||||||
assertEquals(2, dateTimeFoo1.get(Calendar.MONTH) + 1);
|
assertThat(dateTimeFoo1.get(Calendar.MONTH) + 1).isEqualTo(2);
|
||||||
assertEquals(22, dateTimeFoo1.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTimeFoo1.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
|
||||||
assertEquals(23, dateTimeFoo1.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTimeFoo1.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
|
||||||
assertEquals(59, dateTimeFoo1.get(Calendar.MINUTE));
|
assertThat(dateTimeFoo1.get(Calendar.MINUTE)).isEqualTo(59);
|
||||||
assertEquals(0, dateTimeFoo1.get(Calendar.SECOND));
|
assertThat(dateTimeFoo1.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
|
|
||||||
final Calendar dateTimeFoo4 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTimeFoo4 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTimeFoo4.setTime(latestTaskExecutions.get(2).getStartTime());
|
dateTimeFoo4.setTime(latestTaskExecutions.get(2).getStartTime());
|
||||||
|
|
||||||
assertEquals(2015, dateTimeFoo4.get(Calendar.YEAR));
|
assertThat(dateTimeFoo4.get(Calendar.YEAR)).isEqualTo(2015);
|
||||||
assertEquals(2, dateTimeFoo4.get(Calendar.MONTH) + 1);
|
assertThat(dateTimeFoo4.get(Calendar.MONTH) + 1).isEqualTo(2);
|
||||||
assertEquals(20, dateTimeFoo4.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTimeFoo4.get(Calendar.DAY_OF_MONTH)).isEqualTo(20);
|
||||||
assertEquals(14, dateTimeFoo4.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTimeFoo4.get(Calendar.HOUR_OF_DAY)).isEqualTo(14);
|
||||||
assertEquals(45, dateTimeFoo4.get(Calendar.MINUTE));
|
assertThat(dateTimeFoo4.get(Calendar.MINUTE)).isEqualTo(45);
|
||||||
assertEquals(0, dateTimeFoo4.get(Calendar.SECOND));
|
assertThat(dateTimeFoo4.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test is a special use-case. While not common, it is theoretically possible, that a task may have
|
* This test is a special use-case. While not common, it is theoretically possible,
|
||||||
* executed with the exact same start time multiple times. In that case we should still only get 1 returned
|
* that a task may have executed with the exact same start time multiple times. In
|
||||||
* {@link TaskExecution}.
|
* that case we should still only get 1 returned {@link TaskExecution}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionsByTaskNamesWithIdenticalTaskExecutions() {
|
public void getLatestTaskExecutionsByTaskNamesWithIdenticalTaskExecutions() {
|
||||||
long executionIdOffset = initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
long executionIdOffset = initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
final List<TaskExecution> latestTaskExecutions = dao.getLatestTaskExecutionsByTaskNames("FOO5");
|
final List<TaskExecution> latestTaskExecutions = this.dao
|
||||||
assertTrue("Expected only 1 taskExecution but got " + latestTaskExecutions.size(), latestTaskExecutions.size() == 1);
|
.getLatestTaskExecutionsByTaskNames("FOO5");
|
||||||
|
assertThat(latestTaskExecutions.size() == 1).as(
|
||||||
|
"Expected only 1 taskExecution but got " + latestTaskExecutions.size())
|
||||||
|
.isTrue();
|
||||||
|
|
||||||
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTime.setTime(latestTaskExecutions.get(0).getStartTime());
|
dateTime.setTime(latestTaskExecutions.get(0).getStartTime());
|
||||||
|
|
||||||
assertEquals(2015, dateTime.get(Calendar.YEAR));
|
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
|
||||||
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
|
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
|
||||||
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
|
||||||
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
|
||||||
assertEquals(59, dateTime.get(Calendar.MINUTE));
|
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
|
||||||
assertEquals(0, dateTime.get(Calendar.SECOND));
|
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
assertEquals(9 + executionIdOffset, latestTaskExecutions.get(0).getExecutionId());
|
assertThat(latestTaskExecutions.get(0).getExecutionId())
|
||||||
|
.isEqualTo(9 + executionIdOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionForTaskNameWithNullParameter() {
|
public void getLatestTaskExecutionForTaskNameWithNullParameter() {
|
||||||
try {
|
try {
|
||||||
dao.getLatestTaskExecutionForTaskName(null);
|
this.dao.getLatestTaskExecutionForTaskName(null);
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
assertEquals("The task name must not be empty.", e.getMessage());
|
assertThat(e.getMessage()).isEqualTo("The task name must not be empty.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected an IllegalArgumentException to be thrown.");
|
fail("Expected an IllegalArgumentException to be thrown.");
|
||||||
@@ -178,12 +189,12 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionForTaskNameWithEmptyStringParameter() {
|
public void getLatestTaskExecutionForTaskNameWithEmptyStringParameter() {
|
||||||
try {
|
try {
|
||||||
dao.getLatestTaskExecutionForTaskName("");
|
this.dao.getLatestTaskExecutionForTaskName("");
|
||||||
}
|
}
|
||||||
catch (IllegalArgumentException e) {
|
catch (IllegalArgumentException e) {
|
||||||
assertEquals("The task name must not be empty.", e.getMessage());
|
assertThat(e.getMessage()).isEqualTo("The task name must not be empty.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
fail("Expected an IllegalArgumentException to be thrown.");
|
fail("Expected an IllegalArgumentException to be thrown.");
|
||||||
@@ -191,61 +202,71 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionForNonExistingTaskName() {
|
public void getLatestTaskExecutionForNonExistingTaskName() {
|
||||||
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
final TaskExecution latestTaskExecution = dao.getLatestTaskExecutionForTaskName("Bar5");
|
final TaskExecution latestTaskExecution = this.dao
|
||||||
assertNull("Expected the latestTaskExecution to be null but got" + latestTaskExecution, latestTaskExecution);
|
.getLatestTaskExecutionForTaskName("Bar5");
|
||||||
|
assertThat(latestTaskExecution)
|
||||||
|
.as("Expected the latestTaskExecution to be null but got"
|
||||||
|
+ latestTaskExecution)
|
||||||
|
.isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionForExistingTaskName() {
|
public void getLatestTaskExecutionForExistingTaskName() {
|
||||||
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
final TaskExecution latestTaskExecution = dao.getLatestTaskExecutionForTaskName("FOO1");
|
final TaskExecution latestTaskExecution = this.dao
|
||||||
assertNotNull("Expected the latestTaskExecution not to be null", latestTaskExecution);
|
.getLatestTaskExecutionForTaskName("FOO1");
|
||||||
|
assertThat(latestTaskExecution)
|
||||||
|
.as("Expected the latestTaskExecution not to be null").isNotNull();
|
||||||
|
|
||||||
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTime.setTime(latestTaskExecution.getStartTime());
|
dateTime.setTime(latestTaskExecution.getStartTime());
|
||||||
|
|
||||||
assertEquals(2015, dateTime.get(Calendar.YEAR));
|
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
|
||||||
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
|
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
|
||||||
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
|
||||||
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
|
||||||
assertEquals(59, dateTime.get(Calendar.MINUTE));
|
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
|
||||||
assertEquals(0, dateTime.get(Calendar.SECOND));
|
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This test is a special use-case. While not common, it is theoretically possible, that a task may have
|
* This test is a special use-case. While not common, it is theoretically possible,
|
||||||
* executed with the exact same start time multiple times. In that case we should still only get 1 returned
|
* that a task may have executed with the exact same start time multiple times. In
|
||||||
* {@link TaskExecution}.
|
* that case we should still only get 1 returned {@link TaskExecution}.
|
||||||
*/
|
*/
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getLatestTaskExecutionForTaskNameWithIdenticalTaskExecutions() {
|
public void getLatestTaskExecutionForTaskNameWithIdenticalTaskExecutions() {
|
||||||
long executionIdOffset = initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
long executionIdOffset = initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
final TaskExecution latestTaskExecution = dao.getLatestTaskExecutionForTaskName("FOO5");
|
final TaskExecution latestTaskExecution = this.dao
|
||||||
assertNotNull("Expected the latestTaskExecution not to be null", latestTaskExecution);
|
.getLatestTaskExecutionForTaskName("FOO5");
|
||||||
|
assertThat(latestTaskExecution)
|
||||||
|
.as("Expected the latestTaskExecution not to be null").isNotNull();
|
||||||
|
|
||||||
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
|
||||||
dateTime.setTime(latestTaskExecution.getStartTime());
|
dateTime.setTime(latestTaskExecution.getStartTime());
|
||||||
|
|
||||||
assertEquals(2015, dateTime.get(Calendar.YEAR));
|
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
|
||||||
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
|
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
|
||||||
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
|
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
|
||||||
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
|
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
|
||||||
assertEquals(59, dateTime.get(Calendar.MINUTE));
|
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
|
||||||
assertEquals(0, dateTime.get(Calendar.SECOND));
|
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
|
||||||
assertEquals(9 + executionIdOffset, latestTaskExecution.getExecutionId());
|
assertThat(latestTaskExecution.getExecutionId()).isEqualTo(9 + executionIdOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void getRunningTaskExecutions() {
|
public void getRunningTaskExecutions() {
|
||||||
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
|
||||||
assertEquals(dao.getTaskExecutionCount(), dao.getRunningTaskExecutionCount());
|
assertThat(this.dao.getRunningTaskExecutionCount())
|
||||||
dao.completeTaskExecution(1, 0, new Date(), "c'est fini!" );
|
.isEqualTo(this.dao.getTaskExecutionCount());
|
||||||
assertEquals(dao.getTaskExecutionCount() - 1, dao.getRunningTaskExecutionCount());
|
this.dao.completeTaskExecution(1, 0, new Date(), "c'est fini!");
|
||||||
|
assertThat(this.dao.getRunningTaskExecutionCount())
|
||||||
|
.isEqualTo(this.dao.getTaskExecutionCount() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected long initializeRepositoryNotInOrderWithMultipleTaskExecutions() {
|
protected long initializeRepositoryNotInOrderWithMultipleTaskExecutions() {
|
||||||
@@ -304,7 +325,8 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private long createTaskExecution(TaskExecution te) {
|
private long createTaskExecution(TaskExecution te) {
|
||||||
return dao.createTaskExecution(te.getTaskName(), te.getStartTime(), te.getArguments(), te.getExternalExecutionId()).getExecutionId();
|
return this.dao.createTaskExecution(te.getTaskName(), te.getStartTime(),
|
||||||
|
te.getArguments(), te.getExternalExecutionId()).getExecutionId();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TaskExecution getTaskExecution(String taskName,
|
protected TaskExecution getTaskExecution(String taskName,
|
||||||
@@ -315,4 +337,5 @@ public class BaseTaskExecutionDaoTestCases {
|
|||||||
taskExecution.setStartTime(new Date());
|
taskExecution.setStartTime(new Date());
|
||||||
return taskExecution;
|
return taskExecution;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2015-2018 the original author or authors.
|
* Copyright 2015-2019 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (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 not use this file except in compliance with the License.
|
||||||
@@ -44,7 +44,7 @@ import org.springframework.test.annotation.DirtiesContext;
|
|||||||
import org.springframework.test.context.ContextConfiguration;
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
import org.springframework.test.context.junit4.SpringRunner;
|
import org.springframework.test.context.junit4.SpringRunner;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes unit tests on JdbcTaskExecutionDao.
|
* Executes unit tests on JdbcTaskExecutionDao.
|
||||||
@@ -53,83 +53,95 @@ import static org.junit.Assert.assertEquals;
|
|||||||
* @author Gunnar Hillert
|
* @author Gunnar Hillert
|
||||||
*/
|
*/
|
||||||
@RunWith(SpringRunner.class)
|
@RunWith(SpringRunner.class)
|
||||||
@ContextConfiguration(classes = {TestConfiguration.class,
|
@ContextConfiguration(classes = { TestConfiguration.class,
|
||||||
EmbeddedDataSourceConfiguration.class,
|
EmbeddedDataSourceConfiguration.class,
|
||||||
PropertyPlaceholderAutoConfiguration.class})
|
PropertyPlaceholderAutoConfiguration.class })
|
||||||
public class JdbcTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases {
|
public class JdbcTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases {
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private DataSource dataSource;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
TaskRepository repository;
|
TaskRepository repository;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup(){
|
public void setup() {
|
||||||
final JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
final JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(this.dataSource);
|
||||||
dao.setTaskIncrementer(TestDBUtils.getIncrementer(dataSource));
|
dao.setTaskIncrementer(TestDBUtils.getIncrementer(this.dataSource));
|
||||||
super.dao = dao;
|
super.dao = dao;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void testStartTaskExecution() {
|
public void testStartTaskExecution() {
|
||||||
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
|
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, null,
|
||||||
new ArrayList<String>(0), null);
|
new ArrayList<>(0), null);
|
||||||
|
|
||||||
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
|
expectedTaskExecution.setArguments(
|
||||||
|
Collections.singletonList("foo=" + UUID.randomUUID().toString()));
|
||||||
expectedTaskExecution.setStartTime(new Date());
|
expectedTaskExecution.setStartTime(new Date());
|
||||||
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
|
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
|
||||||
|
|
||||||
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
|
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
|
||||||
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
|
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
|
||||||
|
expectedTaskExecution.getArguments(),
|
||||||
expectedTaskExecution.getExternalExecutionId());
|
expectedTaskExecution.getExternalExecutionId());
|
||||||
|
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
||||||
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
|
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
|
||||||
|
expectedTaskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void createTaskExecution() {
|
public void createTaskExecution() {
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
|
TaskExecution expectedTaskExecution = TestVerifierUtils
|
||||||
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
|
.createSampleTaskExecutionNoArg();
|
||||||
expectedTaskExecution.getArguments(), expectedTaskExecution.getExternalExecutionId());
|
expectedTaskExecution = this.dao.createTaskExecution(
|
||||||
|
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
|
||||||
|
expectedTaskExecution.getArguments(),
|
||||||
|
expectedTaskExecution.getExternalExecutionId());
|
||||||
|
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
||||||
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
|
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
|
||||||
|
expectedTaskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void createEmptyTaskExecution() {
|
public void createEmptyTaskExecution() {
|
||||||
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
|
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, null,
|
||||||
new ArrayList<String>(0), null);
|
new ArrayList<>(0), null);
|
||||||
|
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
||||||
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
|
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
|
||||||
|
expectedTaskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void completeTaskExecution() {
|
public void completeTaskExecution() {
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.endSampleTaskExecutionNoArg();
|
TaskExecution expectedTaskExecution = TestVerifierUtils
|
||||||
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(),
|
.endSampleTaskExecutionNoArg();
|
||||||
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
|
expectedTaskExecution = this.dao.createTaskExecution(
|
||||||
|
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
|
||||||
|
expectedTaskExecution.getArguments(),
|
||||||
expectedTaskExecution.getExternalExecutionId());
|
expectedTaskExecution.getExternalExecutionId());
|
||||||
dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
|
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
|
||||||
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
|
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
|
||||||
expectedTaskExecution.getExitMessage());
|
expectedTaskExecution.getExitMessage());
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
||||||
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
|
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
|
||||||
|
expectedTaskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = IllegalStateException.class)
|
@Test(expected = IllegalStateException.class)
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void completeTaskExecutionWithNoCreate() {
|
public void completeTaskExecutionWithNoCreate() {
|
||||||
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
|
JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(this.dataSource);
|
||||||
|
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.endSampleTaskExecutionNoArg();
|
TaskExecution expectedTaskExecution = TestVerifierUtils
|
||||||
|
.endSampleTaskExecutionNoArg();
|
||||||
dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
|
dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
|
||||||
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
|
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
|
||||||
expectedTaskExecution.getExitMessage());
|
expectedTaskExecution.getExitMessage());
|
||||||
@@ -137,89 +149,90 @@ public class JdbcTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void testFindAllPageableSort() {
|
public void testFindAllPageableSort() {
|
||||||
initializeRepositoryNotInOrder();
|
initializeRepositoryNotInOrder();
|
||||||
Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC,
|
Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC, "EXTERNAL_EXECUTION_ID"));
|
||||||
"EXTERNAL_EXECUTION_ID"));
|
|
||||||
Iterator<TaskExecution> iter = getPageIterator(0, 2, sort);
|
Iterator<TaskExecution> iter = getPageIterator(0, 2, sort);
|
||||||
TaskExecution taskExecution = iter.next();
|
TaskExecution taskExecution = iter.next();
|
||||||
assertEquals("FOO2", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("FOO2");
|
||||||
taskExecution = iter.next();
|
taskExecution = iter.next();
|
||||||
assertEquals("FOO3", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("FOO3");
|
||||||
|
|
||||||
iter = getPageIterator(1, 2, sort);
|
iter = getPageIterator(1, 2, sort);
|
||||||
taskExecution = iter.next();
|
taskExecution = iter.next();
|
||||||
assertEquals("FOO1", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("FOO1");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void testFindAllDefaultSort() {
|
public void testFindAllDefaultSort() {
|
||||||
initializeRepository();
|
initializeRepository();
|
||||||
Iterator<TaskExecution> iter = getPageIterator(0, 2, null);
|
Iterator<TaskExecution> iter = getPageIterator(0, 2, null);
|
||||||
TaskExecution taskExecution = iter.next();
|
TaskExecution taskExecution = iter.next();
|
||||||
assertEquals("FOO1", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("FOO1");
|
||||||
taskExecution = iter.next();
|
taskExecution = iter.next();
|
||||||
assertEquals("FOO2", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("FOO2");
|
||||||
|
|
||||||
iter = getPageIterator(1, 2, null);
|
iter = getPageIterator(1, 2, null);
|
||||||
taskExecution = iter.next();
|
taskExecution = iter.next();
|
||||||
assertEquals("FOO3", taskExecution.getTaskName());
|
assertThat(taskExecution.getTaskName()).isEqualTo("FOO3");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void testStartExecutionWithNullExternalExecutionIdExisting() {
|
public void testStartExecutionWithNullExternalExecutionIdExisting() {
|
||||||
TaskExecution expectedTaskExecution =
|
TaskExecution expectedTaskExecution = initializeTaskExecutionWithExternalExecutionId();
|
||||||
initializeTaskExecutionWithExternalExecutionId();
|
|
||||||
|
|
||||||
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
|
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
|
||||||
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
|
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
|
||||||
null);
|
expectedTaskExecution.getArguments(), null);
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
||||||
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
|
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
|
||||||
|
expectedTaskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@DirtiesContext
|
@DirtiesContext
|
||||||
public void testStartExecutionWithNullExternalExecutionIdNonExisting() {
|
public void testStartExecutionWithNullExternalExecutionIdNonExisting() {
|
||||||
TaskExecution expectedTaskExecution =
|
TaskExecution expectedTaskExecution = initializeTaskExecutionWithExternalExecutionId();
|
||||||
initializeTaskExecutionWithExternalExecutionId();
|
|
||||||
|
|
||||||
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
|
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
|
||||||
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
|
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
|
||||||
"BAR");
|
expectedTaskExecution.getArguments(), "BAR");
|
||||||
expectedTaskExecution.setExternalExecutionId("BAR");
|
expectedTaskExecution.setExternalExecutionId("BAR");
|
||||||
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
|
||||||
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
|
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
|
||||||
|
expectedTaskExecution.getExecutionId()));
|
||||||
}
|
}
|
||||||
|
|
||||||
private TaskExecution initializeTaskExecutionWithExternalExecutionId() {
|
private TaskExecution initializeTaskExecutionWithExternalExecutionId() {
|
||||||
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
|
TaskExecution expectedTaskExecution = TestVerifierUtils
|
||||||
|
.createSampleTaskExecutionNoArg();
|
||||||
return this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
|
return this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
|
||||||
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
|
expectedTaskExecution.getStartTime(),
|
||||||
"FOO1");
|
expectedTaskExecution.getArguments(), "FOO1");
|
||||||
}
|
}
|
||||||
|
|
||||||
private Iterator<TaskExecution> getPageIterator(int pageNum, int pageSize, Sort sort) {
|
private Iterator<TaskExecution> getPageIterator(int pageNum, int pageSize,
|
||||||
Pageable pageable = (sort == null) ?
|
Sort sort) {
|
||||||
PageRequest.of(pageNum, pageSize) :
|
Pageable pageable = (sort == null) ? PageRequest.of(pageNum, pageSize)
|
||||||
PageRequest.of(pageNum, pageSize, sort);
|
: PageRequest.of(pageNum, pageSize, sort);
|
||||||
Page<TaskExecution> page = dao.findAll(pageable);
|
Page<TaskExecution> page = this.dao.findAll(pageable);
|
||||||
assertEquals(3, page.getTotalElements());
|
assertThat(page.getTotalElements()).isEqualTo(3);
|
||||||
assertEquals(2, page.getTotalPages());
|
assertThat(page.getTotalPages()).isEqualTo(2);
|
||||||
return page.iterator();
|
return page.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeRepository() {
|
private void initializeRepository() {
|
||||||
repository.createTaskExecution(getTaskExecution("FOO3", "externalA"));
|
this.repository.createTaskExecution(getTaskExecution("FOO3", "externalA"));
|
||||||
repository.createTaskExecution(getTaskExecution("FOO2", "externalB"));
|
this.repository.createTaskExecution(getTaskExecution("FOO2", "externalB"));
|
||||||
repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
|
this.repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initializeRepositoryNotInOrder() {
|
private void initializeRepositoryNotInOrder() {
|
||||||
repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
|
this.repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
|
||||||
repository.createTaskExecution(getTaskExecution("FOO2", "externalA"));
|
this.repository.createTaskExecution(getTaskExecution("FOO2", "externalA"));
|
||||||
repository.createTaskExecution(getTaskExecution("FOO3", "externalB"));
|
this.repository.createTaskExecution(getTaskExecution("FOO3", "externalB"));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user