Added checkstyle

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 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");
* 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;
/**
* Default implementation of the TaskConfigurer interface. If no {@link TaskConfigurer}
* implementation is present, then this configuration will be used.
* The following defaults will be used:
* Default implementation of the TaskConfigurer interface. If no {@link TaskConfigurer}
* implementation is present, then this configuration will be used. The following defaults
* will be used:
* <ul>
* <li>{@link SimpleTaskRepository} is the default {@link TaskRepository} returned.
* If a data source is present then a data will be stored in the database {@link JdbcTaskExecutionDao} else it will
* be stored in a map {@link MapTaskExecutionDao}.
* <li>{@link SimpleTaskRepository} is the default {@link TaskRepository} returned. If a
* data source is present then a data will be stored in the database
* {@link JdbcTaskExecutionDao} else it will be stored in a map
* {@link MapTaskExecutionDao}.
* </ul>
*
* @author Glenn Renfro
@@ -67,12 +68,11 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
}
/**
* Initializes the DefaultTaskConfigurer and sets the default table prefix
* to {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
*
* Initializes the DefaultTaskConfigurer and sets the default table prefix to
* {@link TaskProperties#DEFAULT_TABLE_PREFIX}.
* @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
* production use.
* repository. If none is provided, a Map will be used (not recommended for production
* use.
*/
public DefaultTaskConfigurer(DataSource dataSource) {
this(dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, null);
@@ -80,9 +80,8 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
/**
* Initializes the DefaultTaskConfigurer.
*
* @param tablePrefix the prefix to apply to the task table names used by
* task infrastructure.
* @param tablePrefix the prefix to apply to the task table names used by task
* infrastructure.
*/
public DefaultTaskConfigurer(String tablePrefix) {
this(null, tablePrefix, null);
@@ -90,23 +89,23 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
/**
* Initializes the DefaultTaskConfigurer.
*
* @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
* production use.
* @param tablePrefix the prefix to apply to the task table names used by
* task infrastructure.
* repository. If none is provided, a Map will be used (not recommended for production
* use.
* @param tablePrefix the prefix to apply to the task table names used by task
* infrastructure.
* @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.context = context;
TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean;
if(this.dataSource != null) {
taskExecutionDaoFactoryBean = new
TaskExecutionDaoFactoryBean(this.dataSource, tablePrefix);
if (this.dataSource != null) {
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(this.dataSource,
tablePrefix);
}
else {
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
@@ -137,22 +136,27 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
if (isDataSourceAvailable()) {
try {
Class.forName("javax.persistence.EntityManager");
if (this.context != null && this.context.getBeanNamesForType(EntityManager.class).length > 0) {
logger.debug("EntityManager was found, using JpaTransactionManager");
if (this.context != null && this.context
.getBeanNamesForType(EntityManager.class).length > 0) {
logger.debug(
"EntityManager was found, using JpaTransactionManager");
this.transactionManager = new JpaTransactionManager();
}
}
catch (ClassNotFoundException ignore) {
logger.debug("No EntityManager was found, using DataSourceTransactionManager");
logger.debug(
"No EntityManager was found, using DataSourceTransactionManager");
}
finally {
if (this.transactionManager == null) {
this.transactionManager = new DataSourceTransactionManager(this.dataSource);
this.transactionManager = new DataSourceTransactionManager(
this.dataSource);
}
}
}
else {
logger.debug("No DataSource was found, using ResourcelessTransactionManager");
logger.debug(
"No DataSource was found, using ResourcelessTransactionManager");
this.transactionManager = new ResourcelessTransactionManager();
}
}
@@ -163,4 +167,5 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
private boolean isDataSourceAvailable() {
return this.dataSource != null;
}
}

View File

@@ -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");
* 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.Target;
import org.springframework.cloud.task.repository.TaskRepository;
import org.springframework.context.annotation.Import;
/**
* <p>
* Enables the {@link org.springframework.cloud.task.listener.TaskLifecycleListener}
* so that the features of Spring Cloud Task will be applied.
* Enables the {@link org.springframework.cloud.task.listener.TaskLifecycleListener} so
* that the features of Spring Cloud Task will be applied.
*
* <pre class="code">
* &#064;Configuration
@@ -39,13 +38,14 @@ import org.springframework.context.annotation.Import;
* &#064;Bean
* public MyCommandLineRunner myCommandLineRunner() {
* return new MyCommandLineRunner()
* }
* }
* }
* </pre>
*
* Note that only one of your configuration classes needs to have the <code>&#064;EnableTask</code>
* annotation. Once you have an <code>&#064;EnableTask</code> class in your configuration
* the task will have the Spring Cloud Task features available.
* Note that only one of your configuration classes needs to have the
* <code>&#064;EnableTask</code> annotation. Once you have an
* <code>&#064;EnableTask</code> class in your configuration the task will have the Spring
* Cloud Task features available.
*
* @author Glenn Renfro
*
@@ -56,4 +56,5 @@ import org.springframework.context.annotation.Import;
@Inherited
@Import(TaskLifecycleConfiguration.class)
public @interface EnableTask {
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -54,10 +54,13 @@ import org.springframework.util.CollectionUtils;
@Configuration
@EnableTransactionManagement
@EnableConfigurationProperties(TaskProperties.class)
// @checkstyle:off
@ConditionalOnProperty(prefix = "spring.cloud.task.autoconfiguration", name = "enabled", havingValue = "true", matchIfMissing = true)
// @checkstyle:on
public class SimpleTaskAutoConfiguration {
protected static final Log logger = LogFactory.getLog(SimpleTaskAutoConfiguration.class);
protected static final Log logger = LogFactory
.getLog(SimpleTaskAutoConfiguration.class);
@Autowired(required = false)
private Collection<DataSource> dataSources;
@@ -80,7 +83,7 @@ public class SimpleTaskAutoConfiguration {
private TaskExplorer taskExplorer;
@Bean
public TaskRepository taskRepository(){
public TaskRepository taskRepository() {
return this.taskRepository;
}
@@ -104,7 +107,7 @@ public class SimpleTaskAutoConfiguration {
public TaskRepositoryInitializer taskRepositoryInitializer() {
TaskRepositoryInitializer taskRepositoryInitializer = new TaskRepositoryInitializer();
DataSource initializerDataSource = getDefaultConfigurer().getTaskDataSource();
if(initializerDataSource != null) {
if (initializerDataSource != null) {
taskRepositoryInitializer.setDataSource(initializerDataSource);
}
@@ -116,7 +119,7 @@ public class SimpleTaskAutoConfiguration {
*/
@PostConstruct
protected void initialize() {
if (initialized) {
if (this.initialized) {
return;
}
@@ -128,7 +131,7 @@ public class SimpleTaskAutoConfiguration {
this.taskRepository = taskConfigurer.getTaskRepository();
this.platformTransactionManager = taskConfigurer.getTransactionManager();
this.taskExplorer = taskConfigurer.getTaskExplorer();
initialized = true;
this.initialized = true;
}
private TaskConfigurer getDefaultConfigurer() {
@@ -138,36 +141,44 @@ public class SimpleTaskAutoConfiguration {
if (configurers < 1) {
TaskConfigurer taskConfigurer;
if(!CollectionUtils.isEmpty(this.dataSources) && this.dataSources.size() == 1) {
if (!CollectionUtils.isEmpty(this.dataSources)
&& this.dataSources.size() == 1) {
taskConfigurer = new DefaultTaskConfigurer(
this.dataSources.iterator().next(),
taskProperties.getTablePrefix(), context);
this.taskProperties.getTablePrefix(), this.context);
}
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;
}
else {
if(configurers == 1) {
if (configurers == 1) {
return this.context.getBean(TaskConfigurer.class);
}
else {
throw new IllegalStateException("Expected one TaskConfigurer but found " + configurers);
throw new IllegalStateException(
"Expected one TaskConfigurer but found " + configurers);
}
}
}
private void verifyEnvironment() {
int configurers = this.context.getBeanNamesForType(TaskConfigurer.class).length;
// retrieve the count of dataSources (without instantiating them) excluding DataSource proxy beans
long dataSources = Arrays.stream(this.context.getBeanNamesForType(DataSource.class))
// retrieve the count of dataSources (without instantiating them) excluding
// DataSource proxy beans
long dataSources = Arrays
.stream(this.context.getBeanNamesForType(DataSource.class))
.filter((name -> !ScopedProxyUtils.isScopedTarget(name))).count();
if(configurers == 0 && dataSources > 1) {
throw new IllegalStateException("To use the default TaskConfigurer the context must contain no more than" +
" one DataSource, found " + dataSources);
if (configurers == 0 && dataSources > 1) {
throw new IllegalStateException(
"To use the default TaskConfigurer the context must contain no more than"
+ " one DataSource, found " + dataSources);
}
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.configuration;
@@ -39,10 +39,10 @@ import org.springframework.integration.support.leader.LockRegistryLeaderInitiato
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
* based on the spring.cloud.task.name. If a lock already exists this Listener will throw
* a TaskExecutionException. If this listener is added manually, then it should
* be added as the first listener in the chain.
* When spring.cloud.task.single-instance-enabled is set to true this listener will create
* a lock for the task based on the spring.cloud.task.name. If a lock already exists this
* Listener will throw a TaskExecutionException. If this listener is added manually, then
* it should be added as the first listener in the chain.
*
* @author Glenn Renfro
* @since 2.0.0
@@ -68,19 +68,18 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
private TaskProperties taskProperties;
public SingleInstanceTaskListener(LockRegistry lockRegistry,
TaskNameResolver taskNameResolver,
TaskProperties taskProperties,
TaskNameResolver taskNameResolver, TaskProperties taskProperties,
ApplicationEventPublisher applicationEventPublisher) {
this.lockRegistry = lockRegistry;
this.taskNameResolver = taskNameResolver;
this.taskProperties = taskProperties;
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(this.lockRegistry);
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
this.lockRegistry);
this.applicationEventPublisher = applicationEventPublisher;
}
public SingleInstanceTaskListener(DataSource dataSource,
TaskNameResolver taskNameResolver,
TaskProperties taskProperties,
TaskNameResolver taskNameResolver, TaskProperties taskProperties,
ApplicationEventPublisher applicationEventPublisher) {
this.taskNameResolver = taskNameResolver;
this.applicationEventPublisher = applicationEventPublisher;
@@ -90,14 +89,15 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
@BeforeTask
public void lockTask(TaskExecution taskExecution) {
if(this.lockRegistry == null ) {
if (this.lockRegistry == null) {
this.lockRegistry = getDefaultLockRegistry(taskExecution.getExecutionId());
}
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
this.lockRegistry,
new DefaultCandidate(String.valueOf(taskExecution.getExecutionId()),
taskNameResolver.getTaskName()));
this.lockRegistryLeaderInitiator.setApplicationEventPublisher(this.applicationEventPublisher);
this.taskNameResolver.getTaskName()));
this.lockRegistryLeaderInitiator
.setApplicationEventPublisher(this.applicationEventPublisher);
this.lockRegistryLeaderInitiator.setPublishFailedEvents(true);
this.lockRegistryLeaderInitiator.start();
while (!this.lockReady) {
@@ -115,7 +115,8 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
this.lockRegistryLeaderInitiator.destroy();
}
catch (Exception exception) {
throw new TaskExecutionException("Failed to destroy lock.", exception);
throw new TaskExecutionException("Failed to destroy lock.",
exception);
}
throw new TaskExecutionException(errorMessage);
}
@@ -128,7 +129,8 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
}
@FailedTask
public void unlockTaskOnError(TaskExecution taskExecution, Throwable throwable) throws Exception {
public void unlockTaskOnError(TaskExecution taskExecution, Throwable throwable)
throws Exception {
this.lockRegistryLeaderInitiator.destroy();
}
@@ -142,13 +144,13 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
}
}
private LockRegistry getDefaultLockRegistry( long executionId) {
DefaultLockRepository lockRepository =
new DefaultLockRepository(this.dataSource, String.valueOf(
executionId));
private LockRegistry getDefaultLockRegistry(long executionId) {
DefaultLockRepository lockRepository = new DefaultLockRepository(this.dataSource,
String.valueOf(executionId));
lockRepository.setPrefix(this.taskProperties.getTablePrefix());
lockRepository.setTimeToLive(this.taskProperties.getSingleInstanceLockTtl());
lockRepository.afterPropertiesSet();
return new JdbcLockRegistry(lockRepository);
return new JdbcLockRegistry(lockRepository);
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.configuration;
@@ -47,17 +47,15 @@ public class SingleTaskConfiguration {
@Autowired
private TaskConfigurer taskConfigurer;
@Bean
public SingleInstanceTaskListener taskListener(TaskNameResolver resolver) {
if (taskConfigurer.getTaskDataSource() == null) {
return new SingleInstanceTaskListener(new PassThruLockRegistry(),
resolver, this.taskProperties, this.applicationEventPublisher);
if (this.taskConfigurer.getTaskDataSource() == null) {
return new SingleInstanceTaskListener(new PassThruLockRegistry(), resolver,
this.taskProperties, this.applicationEventPublisher);
}
return new SingleInstanceTaskListener(taskConfigurer.getTaskDataSource(),
resolver,
this.taskProperties,
this.applicationEventPublisher);
return new SingleInstanceTaskListener(this.taskConfigurer.getTaskDataSource(),
resolver, this.taskProperties, this.applicationEventPublisher);
}
}

View File

@@ -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");
* 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;
/**
* Provides a strategy interface for providing configuration
* customization to the task system. Users should not directly use getter methods
* from a <code>TaskConfigurer</code> directly unless they are using it to supply the implementations
* for Spring Beans.
* Provides a strategy interface for providing configuration customization to the task
* system. Users should not directly use getter methods from a <code>TaskConfigurer</code>
* directly unless they are using it to supply the implementations for Spring Beans.
*
* @author Glenn Renfro
*/
@@ -34,7 +33,6 @@ public interface TaskConfigurer {
/**
* Create a {@link TaskRepository} for the Task.
*
* @return A TaskRepository
*/
TaskRepository getTaskRepository();
@@ -42,23 +40,22 @@ public interface TaskConfigurer {
/**
* Create a {@link PlatformTransactionManager} for use with the
* <code>TaskRepository</code>.
*
* @return A <code>PlatformTransactionManager</code>
*/
PlatformTransactionManager getTransactionManager();
/**
* Create a {@link TaskExplorer} for the task.
*
* @return a <code>TaskExplorer</code>
*/
TaskExplorer getTaskExplorer();
/**
* Retrieves the {@link DataSource} that will be used for task operations. If a
* DataSource is not being used for the implemented TaskConfigurer this
* method will return null.
* Retrieves the {@link DataSource} that will be used for task operations. If a
* DataSource is not being used for the implemented TaskConfigurer this method will
* return null.
* @return {@link DataSource} that will be used for task operations.
*/
DataSource getTaskDataSource();
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.configuration;
@@ -43,7 +43,8 @@ import org.springframework.context.annotation.Configuration;
@Configuration
public class TaskLifecycleConfiguration {
protected static final Log logger = LogFactory.getLog(TaskLifecycleConfiguration.class);
protected static final Log logger = LogFactory
.getLog(TaskLifecycleConfiguration.class);
private TaskProperties taskProperties;
@@ -63,10 +64,8 @@ public class TaskLifecycleConfiguration {
@Autowired
public TaskLifecycleConfiguration(TaskProperties taskProperties,
ConfigurableApplicationContext context,
TaskRepository taskRepository,
TaskExplorer taskExplorer,
TaskNameResolver taskNameResolver,
ConfigurableApplicationContext context, TaskRepository taskRepository,
TaskExplorer taskExplorer, TaskNameResolver taskNameResolver,
ObjectProvider<ApplicationArguments> applicationArguments) {
this.taskProperties = taskProperties;
@@ -88,15 +87,13 @@ public class TaskLifecycleConfiguration {
@PostConstruct
protected void initialize() {
if (!this.initialized) {
this.taskLifecycleListener =
new TaskLifecycleListener(this.taskRepository,
this.taskNameResolver,
this.applicationArguments,
this.taskExplorer,
this.taskProperties,
new TaskListenerExecutorObjectFactory(context));
this.taskLifecycleListener = new TaskLifecycleListener(this.taskRepository,
this.taskNameResolver, this.applicationArguments, this.taskExplorer,
this.taskProperties,
new TaskListenerExecutorObjectFactory(this.context));
this.initialized = true;
}
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.configuration;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -32,11 +31,14 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "spring.cloud.task")
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 Log logger = LogFactory.getLog(TaskProperties.class);
public static final String DEFAULT_TABLE_PREFIX = "TASK_";
/**
* An id that can be associated with a task.
@@ -49,8 +51,8 @@ public class TaskProperties {
private Long executionid;
/**
* The id of the parent task execution id that launched this task execution.
* Defaults to null if task execution had no parent.
* The id of the parent task execution id that launched this task execution. Defaults
* to null if task execution had no parent.
*/
private Long parentExecutionId;
@@ -60,35 +62,34 @@ public class TaskProperties {
private String tablePrefix = DEFAULT_TABLE_PREFIX;
/**
* When set to true the context is closed at the end of the task. Else
* the context remains open.
* When set to true the context is closed at the end of the task. Else the context
* remains open.
*/
private Boolean closecontextEnabled = false;
/**
* When set to true it
* will check to see if a task execution with the same task name is already
* running. If a task is still running then it will throw a
* {@link org.springframework.cloud.task.listener.TaskExecutionException}.
* When task execution ends the lock is released.
* When set to true it will check to see if a task execution with the same task name
* is already running. If a task is still running then it will throw a
* {@link org.springframework.cloud.task.listener.TaskExecutionException}. When task
* execution ends the lock is released.
*/
private boolean singleInstanceEnabled = false;
/**
* Declares the maximum amount of time (in millis) that a task execution can
* hold a lock to prevent another task from executing with a specific task
* name when the single-instance-enabled is set to true. Default time is: Integer.MAX_VALUE.
* Declares the maximum amount of time (in millis) that a task execution can hold a
* lock to prevent another task from executing with a specific task name when the
* single-instance-enabled is set to true. Default time is: Integer.MAX_VALUE.
*/
private int singleInstanceLockTtl = Integer.MAX_VALUE;
/**
* Declares the time (in millis) that a task execution will wait between
* checks. Default time is: 500 millis.
* Declares the time (in millis) that a task execution will wait between checks.
* Default time is: 500 millis.
*/
private int singleInstanceLockCheckInterval = DEFAULT_CHECK_INTERVAL;
public String getExternalExecutionId() {
return externalExecutionId;
return this.externalExecutionId;
}
public void setExternalExecutionId(String externalExecutionId) {
@@ -96,7 +97,7 @@ public class TaskProperties {
}
public Long getExecutionid() {
return executionid;
return this.executionid;
}
public void setExecutionid(Long executionid) {
@@ -104,7 +105,7 @@ public class TaskProperties {
}
public Boolean getClosecontextEnabled() {
return closecontextEnabled;
return this.closecontextEnabled;
}
public void setClosecontextEnabled(Boolean closecontextEnabled) {
@@ -112,7 +113,7 @@ public class TaskProperties {
}
public String getTablePrefix() {
return tablePrefix;
return this.tablePrefix;
}
public void setTablePrefix(String tablePrefix) {
@@ -120,7 +121,7 @@ public class TaskProperties {
}
public Long getParentExecutionId() {
return parentExecutionId;
return this.parentExecutionId;
}
public void setParentExecutionId(Long parentExecutionId) {
@@ -128,7 +129,7 @@ public class TaskProperties {
}
public boolean getSingleInstanceEnabled() {
return singleInstanceEnabled;
return this.singleInstanceEnabled;
}
public void setSingleInstanceEnabled(boolean singleInstanceEnabled) {
@@ -136,7 +137,7 @@ public class TaskProperties {
}
public int getSingleInstanceLockTtl() {
return singleInstanceLockTtl;
return this.singleInstanceLockTtl;
}
public void setSingleInstanceLockTtl(int singleInstanceLockTtl) {
@@ -144,10 +145,11 @@ public class TaskProperties {
}
public int getSingleInstanceLockCheckInterval() {
return singleInstanceLockCheckInterval;
return this.singleInstanceLockCheckInterval;
}
public void setSingleInstanceLockCheckInterval(int singleInstanceLockCheckInterval) {
this.singleInstanceLockCheckInterval = singleInstanceLockCheckInterval;
}
}

View File

@@ -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.
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,15 +18,16 @@ package org.springframework.cloud.task.listener;
/**
* Base Exception for any Task issues.
*
* @author Glenn Renfro
*/
public class TaskException extends RuntimeException {
public TaskException(String message, Throwable e){
public TaskException(String message, Throwable e) {
super(message, e);
}
public TaskException(String message){
public TaskException(String message) {
super(message);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -23,11 +23,12 @@ package org.springframework.cloud.task.listener;
*/
public class TaskExecutionException extends TaskException {
public TaskExecutionException(String message){
public TaskExecutionException(String message) {
super(message);
}
public TaskExecutionException(String message, Throwable throwable){
public TaskExecutionException(String message, Throwable throwable) {
super(message, throwable);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,29 +21,32 @@ import org.springframework.cloud.task.repository.TaskRepository;
/**
* The listener interface for receiving task execution events.
*
* @author Glenn Renfro
*/
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.
*/
void onTaskStartup(TaskExecution taskExecution);
/**
* Invoked before the {@link TaskExecution} has been updated in the {@link TaskRepository}
* upon task end.
* Invoked before the {@link TaskExecution} has been updated in the
* {@link TaskRepository} upon task end.
* @param taskExecution instance containing the information about the current task.
*/
void onTaskEnd(TaskExecution taskExecution);
/**
* 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}
* and before the onTaskEnd is called.
* 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} and before the onTaskEnd is called.
* @param taskExecution instance containing the information about the current task.
* @param throwable the uncaught exception that was thrown during task execution.
*/
void onTaskFailed(TaskExecution taskExecution, Throwable throwable);
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.listener;
import org.springframework.cloud.task.repository.TaskExecution;
@@ -25,6 +26,7 @@ import org.springframework.cloud.task.repository.TaskExecution;
* @since 1.2
*/
public class TaskExecutionListenerSupport implements TaskExecutionListener {
@Override
public void onTaskStartup(TaskExecution taskExecution) {
@@ -39,4 +41,5 @@ public class TaskExecutionListenerSupport implements TaskExecutionListener {
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.listener;
import java.io.PrintWriter;
@@ -49,33 +50,42 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
/**
* Monitors the lifecycle of a task. This listener will record both the start and end of
* a task in the registered {@link TaskRepository}.
* Monitors the lifecycle of a task. This listener will record both the start and end of a
* task in the registered {@link TaskRepository}.
*
* The following events are used to identify the start and end of a task:
*
* <ul>
* <li>{@link SmartLifecycle#start()} - Used to identify the start of a task. A task
* is expected to contain a single application context.</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 SmartLifecycle#stop()} - Used to identify the end of a task,
* if the {@link ApplicationReadyEvent} or {@link ApplicationFailedEvent}
* is not emitted. This can occur if an error occurs while executing a BeforeTask.
* </li>
* <li>{@link SmartLifecycle#start()} - Used to identify the start of a task. A task is
* expected to contain a single application context.</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 SmartLifecycle#stop()} - Used to identify the end of a task, if the
* {@link ApplicationReadyEvent} or {@link ApplicationFailedEvent} is not emitted. This
* can occur if an error occurs while executing a BeforeTask.</li>
* </ul>
*
* <b>Note:</b> By default, the context will close at the completion of the task unless other non-daemon
* threads keep it running. Programatic closing of the context can be configured via the
* property <code>spring.cloud.task.closecontext.enabled</code> (defaults to false).
* If the <code>spring.cloud.task.closecontext.enabled</code> is set to true,
* then the context will be closed upon task completion regardless if non-daemon threads are still running.
* Also if the context did not start, the FailedTask and TaskEnd may not have all the dependencies met.
* <b>Note:</b> By default, the context will close at the completion of the task unless
* other non-daemon threads keep it running. Programatic closing of the context can be
* configured via the property <code>spring.cloud.task.closecontext.enabled</code>
* (defaults to false). If the <code>spring.cloud.task.closecontext.enabled</code> is set
* to true, then the context will be closed upon task completion regardless if non-daemon
* 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 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
private ConfigurableApplicationContext context;
@@ -85,14 +95,6 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
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 TaskProperties taskProperties;
@@ -115,22 +117,25 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
/**
* @param taskRepository {@link TaskRepository} to record executions.
* @param taskNameResolver {@link TaskNameResolver} used to determine task name for task execution.
* @param applicationArguments {@link ApplicationArguments} to be used for task execution.
* @param taskNameResolver {@link TaskNameResolver} used to determine task name for
* task execution.
* @param applicationArguments {@link ApplicationArguments} 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 taskListenerExecutorObjectFactory {@link TaskListenerExecutorObjectFactory} to initialize TaskListenerExecutor for a task
* @param taskListenerExecutorObjectFactory {@link TaskListenerExecutorObjectFactory}
* to initialize TaskListenerExecutor for a task
*/
public TaskLifecycleListener(TaskRepository taskRepository,
TaskNameResolver taskNameResolver,
ApplicationArguments applicationArguments, TaskExplorer taskExplorer,
TaskProperties taskProperties,
TaskNameResolver taskNameResolver, ApplicationArguments applicationArguments,
TaskExplorer taskExplorer, TaskProperties taskProperties,
TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory) {
Assert.notNull(taskRepository, "A taskRepository is required");
Assert.notNull(taskNameResolver, "A taskNameResolver is required");
Assert.notNull(taskExplorer, "A taskExplorer 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.taskNameResolver = taskNameResolver;
@@ -141,25 +146,25 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
}
/**
* Utilizes {@link ApplicationEvent}s to determine the end and failure of a
* task. Specifically:
* Utilizes {@link ApplicationEvent}s to determine the end and failure of a task.
* Specifically:
* <ul>
* <li>{@link ApplicationReadyEvent} - Successful end of a task</li>
* <li>{@link ApplicationFailedEvent} - Failure of a task</li>
* <li>{@link ApplicationReadyEvent} - Successful end of a task</li>
* <li>{@link ApplicationFailedEvent} - Failure of a task</li>
* </ul>
*
* @param applicationEvent The application being listened for.
*/
@Override
public void onApplicationEvent(ApplicationEvent applicationEvent) {
if(applicationEvent instanceof ApplicationFailedEvent) {
this.applicationFailedException = ((ApplicationFailedEvent) applicationEvent).getException();
if (applicationEvent instanceof ApplicationFailedEvent) {
this.applicationFailedException = ((ApplicationFailedEvent) applicationEvent)
.getException();
doTaskEnd();
}
else if(applicationEvent instanceof ExitCodeEvent){
else if (applicationEvent instanceof ExitCodeEvent) {
this.exitCodeEvent = (ExitCodeEvent) applicationEvent;
}
else if(applicationEvent instanceof ApplicationReadyEvent) {
else if (applicationEvent instanceof ApplicationReadyEvent) {
doTaskEnd();
}
}
@@ -174,37 +179,41 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
}
private void doTaskEnd() {
if((this.listenerFailed || this.started) && !this.finished) {
if ((this.listenerFailed || this.started) && !this.finished) {
this.taskExecution.setEndTime(new Date());
if(this.applicationFailedException != null) {
this.taskExecution.setErrorMessage(stackTraceToString(this.applicationFailedException));
if (this.applicationFailedException != null) {
this.taskExecution.setErrorMessage(
stackTraceToString(this.applicationFailedException));
}
this.taskExecution.setExitCode(calcExitStatus());
if (this.applicationFailedException != null) {
setExitMessage(invokeOnTaskError(this.taskExecution, this.applicationFailedException));
setExitMessage(invokeOnTaskError(this.taskExecution,
this.applicationFailedException));
}
setExitMessage(invokeOnTaskEnd(this.taskExecution));
this.taskRepository.completeTaskExecution(this.taskExecution.getExecutionId(), this.taskExecution.getExitCode(),
this.taskExecution.getEndTime(), this.taskExecution.getExitMessage(), this.taskExecution.getErrorMessage());
this.taskRepository.completeTaskExecution(this.taskExecution.getExecutionId(),
this.taskExecution.getExitCode(), this.taskExecution.getEndTime(),
this.taskExecution.getExitMessage(),
this.taskExecution.getErrorMessage());
this.finished = true;
if(this.taskProperties.getClosecontextEnabled() && this.context.isActive()) {
if (this.taskProperties.getClosecontextEnabled() && this.context.isActive()) {
this.context.close();
}
}
else if(!this.started){
logger.error("An event to end a task has been received for a task that has " +
"not yet started.");
else if (!this.started) {
logger.error("An event to end a task has been received for a task that has "
+ "not yet started.");
}
}
private void setExitMessage(TaskExecution taskExecutionParam) {
if(taskExecutionParam.getExitMessage() != null) {
if (taskExecutionParam.getExitMessage() != null) {
this.taskExecution.setExitMessage(taskExecutionParam.getExitMessage());
}
}
@@ -218,10 +227,12 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
Throwable exception = this.listenerException;
if (exception instanceof TaskExecutionException) {
TaskExecutionException taskExecutionException = (TaskExecutionException) exception;
if (taskExecutionException.getCause() instanceof InvocationTargetException) {
if (taskExecutionException
.getCause() instanceof InvocationTargetException) {
InvocationTargetException invocationTargetException = (InvocationTargetException) taskExecutionException
.getCause();
if(invocationTargetException != null && invocationTargetException.getTargetException() != null) {
if (invocationTargetException != null
&& invocationTargetException.getTargetException() != null) {
exception = invocationTargetException.getTargetException();
}
}
@@ -240,25 +251,32 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
private void doTaskStart() {
try {
if(!this.started) {
if (!this.started) {
this.taskExecutionListeners = new ArrayList<>();
this.taskListenerExecutorObjectFactory.getObject();
if(!CollectionUtils.isEmpty(this.taskExecutionListenersFromContext)) {
this.taskExecutionListeners.addAll(this.taskExecutionListenersFromContext);
if (!CollectionUtils.isEmpty(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);
if(this.applicationArguments != null) {
if (this.applicationArguments != null) {
args = Arrays.asList(this.applicationArguments.getSourceArgs());
}
if(this.taskProperties.getExecutionid() != null) {
TaskExecution taskExecution = this.taskExplorer.getTaskExecution(this.taskProperties.getExecutionid());
Assert.notNull(taskExecution, String.format("Invalid TaskExecution, ID %s not found", this.taskProperties.getExecutionid()));
if (this.taskProperties.getExecutionid() != null) {
TaskExecution taskExecution = this.taskExplorer
.getTaskExecution(this.taskProperties.getExecutionid());
Assert.notNull(taskExecution,
String.format("Invalid TaskExecution, ID %s not found",
this.taskProperties.getExecutionid()));
Assert.isNull(taskExecution.getEndTime(), String.format(
"Invalid TaskExecution, ID %s task is already complete", this.taskProperties.getExecutionid()));
this.taskExecution = this.taskRepository.startTaskExecution(this.taskProperties.getExecutionid(),
"Invalid TaskExecution, ID %s task is already complete",
this.taskProperties.getExecutionid()));
this.taskExecution = this.taskRepository.startTaskExecution(
this.taskProperties.getExecutionid(),
this.taskNameResolver.getTaskName(), new Date(), args,
this.taskProperties.getExternalExecutionId(),
this.taskProperties.getParentExecutionId());
@@ -268,15 +286,18 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
taskExecution.setTaskName(this.taskNameResolver.getTaskName());
taskExecution.setStartTime(new Date());
taskExecution.setArguments(args);
taskExecution.setExternalExecutionId(this.taskProperties.getExternalExecutionId());
taskExecution.setParentExecutionId(this.taskProperties.getParentExecutionId());
this.taskExecution = this.taskRepository.createTaskExecution(
taskExecution);
taskExecution.setExternalExecutionId(
this.taskProperties.getExternalExecutionId());
taskExecution.setParentExecutionId(
this.taskProperties.getParentExecutionId());
this.taskExecution = this.taskRepository
.createTaskExecution(taskExecution);
}
}
else {
logger.error("Multiple start events have been received. The first one was " +
"recorded.");
logger.error(
"Multiple start events have been received. The first one was "
+ "recorded.");
}
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);
List<TaskExecutionListener> startupListenerList = new ArrayList<>(this.taskExecutionListeners);
List<TaskExecutionListener> startupListenerList = new ArrayList<>(
this.taskExecutionListeners);
if (!CollectionUtils.isEmpty(startupListenerList)) {
try {
Collections.reverse(startupListenerList);
@@ -310,7 +332,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
return listenerTaskExecution;
}
private TaskExecution invokeOnTaskEnd(TaskExecution taskExecution){
private TaskExecution invokeOnTaskEnd(TaskExecution taskExecution) {
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
if (this.taskExecutionListeners != null) {
try {
@@ -321,7 +343,8 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
catch (Throwable listenerException) {
String errorMessage = stackTraceToString(listenerException);
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);
listenerTaskExecution.setErrorMessage(errorMessage);
@@ -331,7 +354,8 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
return listenerTaskExecution;
}
private TaskExecution invokeOnTaskError(TaskExecution taskExecution, Throwable throwable){
private TaskExecution invokeOnTaskError(TaskExecution taskExecution,
Throwable throwable) {
TaskExecution listenerTaskExecution = getTaskExecutionCopy(taskExecution);
if (this.taskExecutionListeners != null) {
try {
@@ -342,9 +366,9 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
catch (Throwable listenerException) {
this.listenerFailed = true;
String errorMessage;
if(StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
errorMessage = String.format("%s :While handling " +
"this error: %s", listenerException.getMessage(),
if (StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
errorMessage = String.format("%s :While handling " + "this error: %s",
listenerException.getMessage(),
listenerTaskExecution.getErrorMessage());
}
else {
@@ -359,14 +383,14 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
return listenerTaskExecution;
}
private TaskExecution getTaskExecutionCopy(TaskExecution taskExecution){
private TaskExecution getTaskExecutionCopy(TaskExecution taskExecution) {
Date startTime = new Date(taskExecution.getStartTime().getTime());
Date endTime = (taskExecution.getEndTime() == null) ?
null : new Date(taskExecution.getEndTime().getTime());
Date endTime = (taskExecution.getEndTime() == null) ? null
: new Date(taskExecution.getEndTime().getTime());
return new TaskExecution(taskExecution.getExecutionId(),
taskExecution.getExitCode(), taskExecution.getTaskName(), startTime,
endTime,taskExecution.getExitMessage(),
endTime, taskExecution.getExitMessage(),
Collections.unmodifiableList(taskExecution.getArguments()),
taskExecution.getErrorMessage(), taskExecution.getExternalExecutionId());
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.listener;
@@ -47,12 +47,13 @@ import org.springframework.core.annotation.AnnotationUtils;
* @author Glenn Renfro
* @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 final Set<Class<?>> nonAnnotatedClasses =
Collections.newSetFromMap(new ConcurrentHashMap<>());
private final Set<Class<?>> nonAnnotatedClasses = Collections
.newSetFromMap(new ConcurrentHashMap<>());
private ConfigurableApplicationContext context;
@@ -62,7 +63,7 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
private Map<Method, Object> failedTaskInstances;
public TaskListenerExecutorObjectFactory(ConfigurableApplicationContext context){
public TaskListenerExecutorObjectFactory(ConfigurableApplicationContext context) {
this.context = context;
}
@@ -72,12 +73,13 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
this.afterTaskInstances = new HashMap<>();
this.failedTaskInstances = new HashMap<>();
initializeExecutor();
return new TaskListenerExecutor(beforeTaskInstances, afterTaskInstances, failedTaskInstances);
return new TaskListenerExecutor(this.beforeTaskInstances, this.afterTaskInstances,
this.failedTaskInstances);
}
private void initializeExecutor( ) {
ConfigurableListableBeanFactory factory = context.getBeanFactory();
for( String beanName : context.getBeanDefinitionNames()) {
private void initializeExecutor() {
ConfigurableListableBeanFactory factory = this.context.getBeanFactory();
for (String beanName : this.context.getBeanDefinitionNames()) {
if (!ScopedProxyUtils.isScopedTarget(beanName)) {
Class<?> type = null;
@@ -85,9 +87,11 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
type = AutoProxyUtils.determineTargetClass(factory, beanName);
}
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()) {
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) {
@@ -99,7 +103,10 @@ public class TaskListenerExecutorObjectFactory implements ObjectFactory<TaskExec
catch (RuntimeException ex) {
// An invalid scoped proxy arrangement - let's ignore it.
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);
}
catch (RuntimeException ex) {
throw new BeanInitializationException("Failed to process @BeforeTask " +
"annotation on bean with name '" + beanName + "'", ex);
throw new BeanInitializationException(
"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)) {
Map<Method, BeforeTask> beforeTaskMethods =
(new MethodGetter<BeforeTask>()).getMethods(type, BeforeTask.class);
Map<Method, AfterTask> afterTaskMethods =
(new MethodGetter<AfterTask>()).getMethods(type, AfterTask.class);
Map<Method, FailedTask> failedTaskMethods =
(new MethodGetter<FailedTask>()).getMethods(type, FailedTask.class);
Map<Method, BeforeTask> beforeTaskMethods = (new MethodGetter<BeforeTask>())
.getMethods(type, BeforeTask.class);
Map<Method, AfterTask> afterTaskMethods = (new MethodGetter<AfterTask>())
.getMethods(type, AfterTask.class);
Map<Method, FailedTask> failedTaskMethods = (new MethodGetter<FailedTask>())
.getMethods(type, FailedTask.class);
if (beforeTaskMethods.isEmpty() && afterTaskMethods.isEmpty()) {
this.nonAnnotatedClasses.add(type);
return;
}
if(!beforeTaskMethods.isEmpty()) {
for(Method beforeTaskMethod : beforeTaskMethods.keySet()) {
this.beforeTaskInstances.put(beforeTaskMethod, context.getBean(beanName));
if (!beforeTaskMethods.isEmpty()) {
for (Method beforeTaskMethod : beforeTaskMethods.keySet()) {
this.beforeTaskInstances.put(beforeTaskMethod,
this.context.getBean(beanName));
}
}
if(!afterTaskMethods.isEmpty()){
for(Method afterTaskMethod : afterTaskMethods.keySet()) {
this.afterTaskInstances.put(afterTaskMethod, context.getBean(beanName));
if (!afterTaskMethods.isEmpty()) {
for (Method afterTaskMethod : afterTaskMethods.keySet()) {
this.afterTaskInstances.put(afterTaskMethod,
this.context.getBean(beanName));
}
}
if(!failedTaskMethods.isEmpty()){
for(Method failedTaskMethod : failedTaskMethods.keySet()) {
this.failedTaskInstances.put(failedTaskMethod, context.getBean(beanName));
if (!failedTaskMethods.isEmpty()) {
for (Method failedTaskMethod : failedTaskMethods.keySet()) {
this.failedTaskInstances.put(failedTaskMethod,
this.context.getBean(beanName));
}
}
}
}
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,
(MethodIntrospector.MetadataLookup<T>) method -> AnnotationUtils.findAnnotation(method, annotationClass));
(MethodIntrospector.MetadataLookup<T>) method -> AnnotationUtils
.findAnnotation(method, annotationClass));
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,22 +27,22 @@ import org.springframework.cloud.task.repository.TaskExecution;
/**
* <p>
* {@link TaskExecutionListener#onTaskEnd(TaskExecution)}
* {@link TaskExecutionListener#onTaskEnd(TaskExecution)}.
* </p>
*
* <pre class="code">
* public class MyListener {
* &#064;AfterTask
* public void doSomething(TaskExecution taskExecution) {
* }
* }
* }
* </pre>
*
* @author Glenn Renfro
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AfterTask {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,22 +27,22 @@ import org.springframework.cloud.task.repository.TaskExecution;
/**
* <p>
* {@link TaskExecutionListener#onTaskStartup(TaskExecution)}
* {@link TaskExecutionListener#onTaskStartup(TaskExecution)}.
* </p>
*
* <pre class="code">
* public class MyListener {
* &#064;BeforeTask
* public void doSomething(TaskExecution taskExecution) {
* }
* }
* }
* </pre>
*
* @author Glenn Renfro
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BeforeTask {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -27,22 +27,22 @@ import org.springframework.cloud.task.repository.TaskExecution;
/**
* <p>
* {@link TaskExecutionListener#onTaskFailed(TaskExecution, Throwable)}
* {@link TaskExecutionListener#onTaskFailed(TaskExecution, Throwable)}.
* </p>
*
* <pre class="code">
* public class MyListener {
* &#064;FailedTask
* public void doSomething(TaskExecution taskExecution, Throwable throwable) {
* }
* }
* }
* </pre>
*
* @author Glenn Renfro
*/
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FailedTask {
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ import org.springframework.cloud.task.repository.TaskExecution;
*
* @author Glenn Renfro
*/
public class TaskListenerExecutor implements TaskExecutionListener{
public class TaskListenerExecutor implements TaskExecutionListener {
private Map<Method, Object> beforeTaskInstances;
@@ -42,7 +42,7 @@ public class TaskListenerExecutor implements TaskExecutionListener{
public TaskListenerExecutor(Map<Method, Object> beforeTaskInstances,
Map<Method, Object> afterTaskInstances,
Map<Method, Object> failedTaskInstances){
Map<Method, Object> failedTaskInstances) {
this.beforeTaskInstances = beforeTaskInstances;
this.afterTaskInstances = afterTaskInstances;
@@ -50,66 +50,77 @@ public class TaskListenerExecutor implements TaskExecutionListener{
}
/**
* Executes all the methods that have been annotated with &#064;BeforeTask.
* Executes all the methods that have been annotated with &#064;BeforeTask.
* @param taskExecution associated with the event.
*/
@Override
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 &#064;AfterTask.
* Executes all the methods that have been annotated with &#064;AfterTask.
* @param taskExecution associated with the event.
*/
@Override
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 &#064;FailedTask.
* Executes all the methods that have been annotated with &#064;FailedTask.
* @param throwable that was not caught for the task execution.
* @param taskExecution associated with the event.
*/
@Override
public void onTaskFailed(TaskExecution taskExecution, Throwable 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) {
try {
method.invoke(instances.get(method),taskExecution);
method.invoke(instances.get(method), taskExecution);
}
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) {
throw new TaskExecutionException(String.format("Failed to process @BeforeTask or @AfterTask" +
" annotation because: %s", e.getTargetException().getMessage()), e);
throw new TaskExecutionException(String.format(
"Failed to process @BeforeTask or @AfterTask"
+ " annotation because: %s",
e.getTargetException().getMessage()), e);
}
catch (IllegalArgumentException e){
throw new TaskExecutionException("taskExecution parameter is required for @BeforeTask and @AfterTask annotated methods", e);
catch (IllegalArgumentException e) {
throw new TaskExecutionException("taskExecution parameter "
+ "is required for @BeforeTask and @AfterTask annotated methods",
e);
}
}
}
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) {
try {
method.invoke(instances.get(method),taskExecution, throwable);
method.invoke(instances.get(method), taskExecution, throwable);
}
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) {
throw new TaskExecutionException(String.format("Failed to process @FailedTask " +
"annotation because: %s", e.getTargetException().getMessage()), e);
throw new TaskExecutionException(String.format(
"Failed to process @FailedTask " + "annotation because: %s",
e.getTargetException().getMessage()), e);
}
catch (IllegalArgumentException e){
catch (IllegalArgumentException e) {
throw new TaskExecutionException("taskExecution and throwable parameters "
+ "are required for @FailedTask annotated methods", e);
}

View File

@@ -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.
*/

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -33,7 +33,7 @@ import org.springframework.util.Assert;
public class TaskExecution {
/**
* The unique id associated with the task execution.
* The unique id associated with the task execution.
*/
private long executionId;
@@ -75,7 +75,7 @@ public class TaskExecution {
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
*/
@@ -87,14 +87,12 @@ public class TaskExecution {
private List<String> arguments;
public TaskExecution() {
arguments = new ArrayList<>();
this.arguments = new ArrayList<>();
}
public TaskExecution(long executionId, Integer exitCode, String taskName,
Date startTime, Date endTime,
String exitMessage, List<String> arguments,
String errorMessage, String externalExecutionId,
Long parentExecutionId) {
Date startTime, Date endTime, String exitMessage, List<String> arguments,
String errorMessage, String externalExecutionId, Long parentExecutionId) {
Assert.notNull(arguments, "arguments must not be null");
this.executionId = executionId;
@@ -102,24 +100,23 @@ public class TaskExecution {
this.taskName = taskName;
this.exitMessage = exitMessage;
this.arguments = new ArrayList<>(arguments);
this.startTime = (startTime != null) ? (Date)startTime.clone() : null;
this.endTime = (endTime != null) ? (Date)endTime.clone() : null;
this.startTime = (startTime != null) ? (Date) startTime.clone() : null;
this.endTime = (endTime != null) ? (Date) endTime.clone() : null;
this.errorMessage = errorMessage;
this.externalExecutionId = externalExecutionId;
this.parentExecutionId = parentExecutionId;
}
public TaskExecution(long executionId, Integer exitCode, String taskName,
Date startTime, Date endTime,
String exitMessage, List<String> arguments,
Date startTime, Date endTime, String exitMessage, List<String> arguments,
String errorMessage, String externalExecutionId) {
this(executionId, exitCode, taskName, startTime, endTime, exitMessage,
arguments, errorMessage,externalExecutionId, null);
this(executionId, exitCode, taskName, startTime, endTime, exitMessage, arguments,
errorMessage, externalExecutionId, null);
}
public long getExecutionId() {
return executionId;
return this.executionId;
}
public Integer getExitCode() {
@@ -131,7 +128,7 @@ public class TaskExecution {
}
public String getTaskName() {
return taskName;
return this.taskName;
}
public void setTaskName(String taskName) {
@@ -139,23 +136,23 @@ public class TaskExecution {
}
public Date getStartTime() {
return (startTime != null) ? (Date)startTime.clone() : null;
return (this.startTime != null) ? (Date) this.startTime.clone() : null;
}
public void setStartTime(Date startTime) {
this.startTime = (startTime != null) ? (Date)startTime.clone() : null;
this.startTime = (startTime != null) ? (Date) startTime.clone() : null;
}
public Date getEndTime() {
return (endTime != null) ? (Date)endTime.clone() : null;
return (this.endTime != null) ? (Date) this.endTime.clone() : null;
}
public void setEndTime(Date endTime) {
this.endTime = (endTime != null) ? (Date)endTime.clone() : null;
this.endTime = (endTime != null) ? (Date) endTime.clone() : null;
}
public String getExitMessage() {
return exitMessage;
return this.exitMessage;
}
public void setExitMessage(String exitMessage) {
@@ -163,15 +160,15 @@ public class TaskExecution {
}
public List<String> getArguments() {
return arguments;
return this.arguments;
}
public void setArguments(List<String> arguments) {
this.arguments = new ArrayList<> (arguments);
this.arguments = new ArrayList<>(arguments);
}
public String getErrorMessage() {
return errorMessage;
return this.errorMessage;
}
public void setErrorMessage(String errorMessage) {
@@ -179,7 +176,7 @@ public class TaskExecution {
}
public String getExternalExecutionId() {
return externalExecutionId;
return this.externalExecutionId;
}
public void setExternalExecutionId(String externalExecutionId) {
@@ -187,7 +184,7 @@ public class TaskExecution {
}
public Long getParentExecutionId() {
return parentExecutionId;
return this.parentExecutionId;
}
public void setParentExecutionId(Long parentExecutionId) {
@@ -196,17 +193,13 @@ public class TaskExecution {
@Override
public String toString() {
return "TaskExecution{" +
"executionId=" + executionId +
", parentExecutionId=" + parentExecutionId +
", exitCode=" + exitCode +
", taskName='" + taskName + '\'' +
", startTime=" + startTime +
", endTime=" + endTime +
", exitMessage='" + exitMessage + '\'' +
", externalExecutionId='" + externalExecutionId + '\'' +
", errorMessage='" + errorMessage + '\'' +
", arguments=" + arguments +
'}';
return "TaskExecution{" + "executionId=" + this.executionId
+ ", parentExecutionId=" + this.parentExecutionId + ", exitCode="
+ this.exitCode + ", taskName='" + this.taskName + '\'' + ", startTime="
+ this.startTime + ", endTime=" + this.endTime + ", exitMessage='"
+ this.exitMessage + '\'' + ", externalExecutionId='"
+ this.externalExecutionId + '\'' + ", errorMessage='" + this.errorMessage
+ '\'' + ", arguments=" + this.arguments + '}';
}
}

View File

@@ -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");
* 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.
*
* @param executionId the task execution id
* @return the {@link TaskExecution} with this id, or null if not found
*/
TaskExecution getTaskExecution(long executionId);
/**
* Retrieve a collection of taskExecutions that have the task name provided.
*
* @param taskName the name of the task
* @param pageable the constraints for the search
* @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.
*
* @return the set of task names that have been executed
*/
List<String> getTaskNames();
/**
* Get number of executions for a taskName.
*
* @param taskName the name of the task to be searched
* @return the number of running tasks that have the taskname specified
*/
@@ -66,21 +61,18 @@ public interface TaskExplorer {
/**
* Retrieves current number of task executions.
*
* @return current number of task executions.
*/
long getTaskExecutionCount();
/**
* Retrieves current number of running task executions.
*
* @return current number of running task executions.
*/
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 pageable the constraints for the search
* @return list of task executions
@@ -88,9 +80,8 @@ public interface TaskExplorer {
Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable);
/**
* Retrieves all the task executions within the pageable constraints sorted by
* start date descending, taskExecution id descending.
*
* Retrieves all the task executions within the pageable constraints sorted by start
* date descending, taskExecution id descending.
* @param pageable the constraints for 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
* 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
* @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
* of the requested task.
*
* @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);
/**
* 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
* (The results may including pending {@link TaskExecution}s).
* Latest is defined by the most recent start time. A {@link TaskExecution} does not
* 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
* {@link TaskExecution} for the exact same start time. In that case 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.
* It is theoretically possible that a {@link TaskExecution} with the same name to
* have more than 1 {@link TaskExecution} for the exact same start time. In that case
* 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.
* @param taskNames At least 1 task name must be provided
* @return List of TaskExecutions. May be empty but never null.
*/
List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames);
/**
* Returns the latest task execution for a given task name. Will ultimately apply the same algorithm underneath
* as {@link #getLatestTaskExecutionsByTaskNames(String...)} but will only return a single result.
*
* Returns the latest task execution for a given task name. Will ultimately apply the
* same algorithm underneath as {@link #getLatestTaskExecutionsByTaskNames(String...)}
* but will only return a single result.
* @param taskName Must not be null or empty
* @return The latest Task Execution or null
* @see #getLatestTaskExecutionsByTaskNames(String...)
*/
TaskExecution getLatestTaskExecutionForTaskName(String taskName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository;
/**
@@ -26,4 +27,5 @@ public interface TaskNameResolver {
* @return the name of the task being executed within this context.
*/
String getTaskName();
}

View File

@@ -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");
* 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.
*
* @param executionId to the task execution to be updated.
* @param exitCode to be stored for this task.
* @param endTime designated when the task completed.
@@ -40,11 +39,10 @@ public interface TaskRepository {
*/
@Transactional
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
String exitMessage);
String exitMessage);
/**
* Notifies the repository that a taskExecution has completed.
*
* @param executionId to the task execution to be updated.
* @param exitCode to be stored for this task execution.
* @param endTime designated when the task completed.
@@ -55,30 +53,26 @@ public interface TaskRepository {
*/
@Transactional
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.
*
* @param taskExecution a TaskExecution instance containing the startTime,
* arguments and externalExecutionId that will be stored in the repository.
* Only the values enumerated above will be stored for this
* @param taskExecution a TaskExecution instance containing the startTime, arguments
* and externalExecutionId that will be stored in the repository. Only the values
* enumerated above will be stored for this 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.
* @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
TaskExecution createTaskExecution(TaskExecution taskExecution);
/**
* Creates an empty TaskExecution with just an id and name provided. This is intended to be
* 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
* launching, etc).
*
* Creates an empty TaskExecution with just an id and name provided. This is intended
* to be 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 launching, etc).
* @param name task name to be associated with the task execution.
*
* @return the initial {@link TaskExecution}
*/
@Transactional
@@ -89,7 +83,6 @@ public interface TaskRepository {
* 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
* launching, etc).
*
* @return the initial {@link TaskExecution}
*/
@Transactional
@@ -97,43 +90,38 @@ public interface TaskRepository {
/**
* Notifies the repository that a taskExecution has has started.
*
* @param executionid to the task execution to be updated.
* @param taskName the name that associated with the task execution.
* @param startTime the time task began.
* @param arguments list of key/value pairs that configure the task.
* @param executionid to the task execution to be updated.
* @param taskName the name that associated with the task execution.
* @param startTime the time task began.
* @param arguments list of key/value pairs that configure the task.
* @param externalExecutionId id assigned to the task by the platform.
* @return TaskExecution created based on the parameters.
*/
@Transactional
TaskExecution startTaskExecution(long executionid, String taskName,
Date startTime,List<String> arguments, String externalExecutionId);
TaskExecution startTaskExecution(long executionid, String taskName, Date startTime,
List<String> arguments, String 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.
*/
@Transactional
void updateExternalExecutionId(long executionid,
String externalExecutionId);
void updateExternalExecutionId(long executionid, String externalExecutionId);
/**
* 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 startTime the time task began.
* @param arguments list of key/value pairs that configure the task.
* @param externalExecutionId id assigned to the task by the platform.
* @param parentExecutionId the parent task execution id.
* @return A TaskExecution that contains the information available at the
* beginning of a TaskExecution.
* @return A TaskExecution that contains the information available at the beginning of
* a TaskExecution.
*/
@Transactional
TaskExecution startTaskExecution(long executionid, String taskName,
Date startTime,List<String> arguments, String externalExecutionId,
Long parentExecutionId);
TaskExecution startTaskExecution(long executionid, String taskName, Date startTime,
List<String> arguments, String externalExecutionId, Long parentExecutionId);
}

View File

@@ -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");
* 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 {
/**
* SELECT clause for task execution.
*/
public static final String SELECT_CLAUSE = "TASK_EXECUTION_ID, "
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, "
+ "EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID ";
/**
* FROM clause for task 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 ";
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)"
+ "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 "
+ "%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";
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 "
+ "%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 "
+ "EXTERNAL_EXECUTION_ID = :externalExecutionId where TASK_EXECUTION_ID = :taskExecutionId";
private static final String GET_EXECUTION_BY_ID = "SELECT TASK_EXECUTION_ID, " +
"START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
private static final String GET_EXECUTION_BY_ID = "SELECT TASK_EXECUTION_ID, "
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, "
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, "
+ "PARENT_EXECUTION_ID "
+ "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, "
+ "TASK_PARAM from %PREFIX%EXECUTION_PARAMS where TASK_EXECUTION_ID = :taskExecutionId";
private static final String TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM " +
"%PREFIX%EXECUTION ";
private static final String TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM "
+ "%PREFIX%EXECUTION ";
private static final String TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM " +
"%PREFIX%EXECUTION where TASK_NAME = :taskName";
private static final String TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM "
+ "%PREFIX%EXECUTION where TASK_NAME = :taskName";
private static final String RUNNING_TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM " +
"%PREFIX%EXECUTION where TASK_NAME = :taskName AND END_TIME IS NULL ";
private static final String RUNNING_TASK_EXECUTION_COUNT_BY_NAME = "SELECT COUNT(*) FROM "
+ "%PREFIX%EXECUTION where TASK_NAME = :taskName AND END_TIME IS NULL ";
private static final String RUNNING_TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM " +
"%PREFIX%EXECUTION where END_TIME IS NULL ";
private static final String RUNNING_TASK_EXECUTION_COUNT = "SELECT COUNT(*) FROM "
+ "%PREFIX%EXECUTION where END_TIME IS NULL ";
private static final String LAST_TASK_EXECUTIONS_BY_TASK_NAMES =
"select TE2.* 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" +
" FROM %PREFIX%EXECUTION where TASK_NAME in (:taskNames)" +
" GROUP BY TASK_NAME" +
") TE_MAX " +
"inner join %PREFIX%EXECUTION TE ON TE.TASK_NAME = TE_MAX.TASK_NAME AND TE.START_TIME = TE_MAX.START_TIME " +
"group by TE.TASK_NAME, TE.START_TIME" +
") 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 LAST_TASK_EXECUTIONS_BY_TASK_NAMES = "select TE2.* 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"
+ " FROM %PREFIX%EXECUTION where TASK_NAME in (:taskNames)"
+ " GROUP BY TASK_NAME" + ") TE_MAX "
+ "inner join %PREFIX%EXECUTION TE ON TE.TASK_NAME = TE_MAX.TASK_NAME AND TE.START_TIME = TE_MAX.START_TIME "
+ "group by TE.TASK_NAME, TE.START_TIME" + ") 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_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 String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
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 final NamedParameterJdbcTemplate jdbcTemplate;
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
private DataSource dataSource;
private LinkedHashMap<String, Order> orderMap;
@@ -169,120 +181,119 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
Assert.notNull(dataSource, "The dataSource must not be null.");
this.jdbcTemplate = new NamedParameterJdbcTemplate(dataSource);
this.dataSource = dataSource;
orderMap = new LinkedHashMap<>();
orderMap.put("START_TIME", Order.DESCENDING);
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);
this.orderMap = new LinkedHashMap<>();
this.orderMap.put("START_TIME", Order.DESCENDING);
this.orderMap.put("TASK_EXECUTION_ID", Order.DESCENDING);
}
@Override
public TaskExecution createTaskExecution(String taskName, Date startTime,
List<String> arguments, String externalExecutionId,
Long parentExecutionId) {
List<String> arguments, String externalExecutionId) {
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();
TaskExecution taskExecution = new TaskExecution(nextExecutionId, null, taskName,
startTime, null, null, arguments, null, externalExecutionId);
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("taskExecutionId", nextExecutionId, Types.BIGINT)
.addValue("exitCode", null, Types.INTEGER)
.addValue("startTime", startTime, Types.TIMESTAMP)
.addValue("taskName", taskName, Types.VARCHAR)
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT);
.addValue("taskExecutionId", nextExecutionId, Types.BIGINT)
.addValue("exitCode", null, Types.INTEGER)
.addValue("startTime", startTime, Types.TIMESTAMP)
.addValue("taskName", taskName, Types.VARCHAR)
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT);
jdbcTemplate.update(
getQuery(SAVE_TASK_EXECUTION),
queryParameters);
this.jdbcTemplate.update(getQuery(SAVE_TASK_EXECUTION), queryParameters);
insertTaskArguments(nextExecutionId, arguments);
return taskExecution;
}
@Override
public TaskExecution startTaskExecution(long executionId, String taskName,
Date startTime, List<String> arguments,
String externalExecutionId) {
Date startTime, List<String> arguments, String externalExecutionId) {
return startTaskExecution(executionId, taskName, startTime, arguments,
externalExecutionId, null);
}
@Override
public TaskExecution startTaskExecution(long executionId, String taskName,
Date startTime, List<String> arguments,
String externalExecutionId, Long parentExecutionId) {
Date startTime, List<String> arguments, String externalExecutionId,
Long parentExecutionId) {
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()
.addValue("startTime", startTime, Types.TIMESTAMP)
.addValue("exitCode", null, Types.INTEGER)
.addValue("taskName", taskName, Types.VARCHAR)
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT)
.addValue("taskExecutionId", executionId, Types.BIGINT);
.addValue("startTime", startTime, Types.TIMESTAMP)
.addValue("exitCode", null, Types.INTEGER)
.addValue("taskName", taskName, Types.VARCHAR)
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
.addValue("parentExecutionId", parentExecutionId, Types.BIGINT)
.addValue("taskExecutionId", executionId, Types.BIGINT);
String updateString = START_TASK_EXECUTION_PREFIX;
if(externalExecutionId == null) {
if (externalExecutionId == null) {
updateString += START_TASK_EXECUTION_SUFFIX;
}
else {
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);
return taskExecution;
}
@Override
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime,
String exitMessage, String errorMessage) {
public void completeTaskExecution(long taskExecutionId, Integer exitCode,
Date endTime, String exitMessage, String errorMessage) {
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
// it is invalid and an exception should be thrown.
if (jdbcTemplate.queryForObject(getQuery(CHECK_TASK_EXECUTION_EXISTS), queryParameters, Integer.class) != 1) {
throw new IllegalStateException("Invalid TaskExecution, ID " + taskExecutionId + " not found.");
if (this.jdbcTemplate.queryForObject(getQuery(CHECK_TASK_EXECUTION_EXISTS),
queryParameters, Integer.class) != 1) {
throw new IllegalStateException(
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
}
final MapSqlParameterSource parameters = new MapSqlParameterSource()
.addValue("endTime", endTime, Types.TIMESTAMP)
.addValue("exitCode", exitCode, Types.INTEGER)
.addValue("exitMessage", exitMessage, Types.VARCHAR)
.addValue("errorMessage", errorMessage, Types.VARCHAR)
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
.addValue("endTime", endTime, Types.TIMESTAMP)
.addValue("exitCode", exitCode, Types.INTEGER)
.addValue("exitMessage", exitMessage, Types.VARCHAR)
.addValue("errorMessage", errorMessage, Types.VARCHAR)
.addValue("lastUpdated", new Date(), Types.TIMESTAMP)
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
jdbcTemplate.update(
getQuery(UPDATE_TASK_EXECUTION),
parameters);
this.jdbcTemplate.update(getQuery(UPDATE_TASK_EXECUTION), parameters);
}
@Override
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime,
String exitMessage) {
public void completeTaskExecution(long taskExecutionId, Integer exitCode,
Date endTime, String exitMessage) {
completeTaskExecution(taskExecutionId, exitCode, endTime, exitMessage, null);
}
@Override
public TaskExecution getTaskExecution(long executionId) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("taskExecutionId", executionId, Types.BIGINT);
.addValue("taskExecutionId", executionId, Types.BIGINT);
try {
TaskExecution taskExecution = jdbcTemplate.queryForObject(getQuery(GET_EXECUTION_BY_ID),
queryParameters, new TaskExecutionRowMapper());
TaskExecution taskExecution = this.jdbcTemplate.queryForObject(
getQuery(GET_EXECUTION_BY_ID), queryParameters,
new TaskExecutionRowMapper());
taskExecution.setArguments(getTaskArguments(executionId));
return taskExecution;
}
@@ -295,11 +306,11 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
public long getTaskExecutionCountByTaskName(String taskName) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("taskName", taskName, Types.VARCHAR);
.addValue("taskName", taskName, Types.VARCHAR);
try {
return jdbcTemplate.queryForObject(
getQuery(TASK_EXECUTION_COUNT_BY_NAME), queryParameters, Long.class);
return this.jdbcTemplate.queryForObject(
getQuery(TASK_EXECUTION_COUNT_BY_NAME), queryParameters, Long.class);
}
catch (EmptyResultDataAccessException e) {
return 0;
@@ -309,11 +320,12 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
@Override
public long getRunningTaskExecutionCountByTaskName(String taskName) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("taskName", taskName, Types.VARCHAR);
.addValue("taskName", taskName, Types.VARCHAR);
try {
return jdbcTemplate.queryForObject(
getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), queryParameters, Long.class);
return this.jdbcTemplate.queryForObject(
getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), queryParameters,
Long.class);
}
catch (EmptyResultDataAccessException e) {
return 0;
@@ -325,8 +337,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
try {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource();
return jdbcTemplate.queryForObject(
getQuery(RUNNING_TASK_EXECUTION_COUNT), queryParameters, Long.class);
return this.jdbcTemplate.queryForObject(
getQuery(RUNNING_TASK_EXECUTION_COUNT), queryParameters, Long.class);
}
catch (EmptyResultDataAccessException e) {
return 0;
@@ -345,14 +357,15 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
}
}
Assert.isTrue(taskNamesAsList.size() == taskNames.length,
String.format("Task names must not contain any empty elements but %s of %s were empty or null.",
taskNames.length - taskNamesAsList.size(), taskNames.length));
Assert.isTrue(taskNamesAsList.size() == taskNames.length, String.format(
"Task names must not contain any empty elements but %s of %s were empty or null.",
taskNames.length - taskNamesAsList.size(), taskNames.length));
try {
final Map<String, List<String>> paramMap = Collections.singletonMap("taskNames", taskNamesAsList);
return this.jdbcTemplate.query(
getQuery(LAST_TASK_EXECUTIONS_BY_TASK_NAMES), paramMap, new TaskExecutionRowMapper());
final Map<String, List<String>> paramMap = Collections
.singletonMap("taskNames", taskNamesAsList);
return this.jdbcTemplate.query(getQuery(LAST_TASK_EXECUTIONS_BY_TASK_NAMES),
paramMap, new TaskExecutionRowMapper());
}
catch (EmptyResultDataAccessException e) {
return Collections.emptyList();
@@ -362,7 +375,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
@Override
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
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()) {
return null;
}
@@ -370,7 +384,9 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
return taskExecutions.get(0);
}
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() {
try {
return jdbcTemplate.queryForObject(
getQuery(TASK_EXECUTION_COUNT), new MapSqlParameterSource(), Long.class);
return this.jdbcTemplate.queryForObject(getQuery(TASK_EXECUTION_COUNT),
new MapSqlParameterSource(), Long.class);
}
catch (EmptyResultDataAccessException e) {
return 0;
@@ -387,14 +403,17 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
}
@Override
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
Pageable pageable) {
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));
}
@Override
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
Pageable pageable) {
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE,
TASK_NAME_WHERE_CLAUSE, new MapSqlParameterSource("taskName", taskName),
getTaskExecutionCountByTaskName(taskName));
@@ -402,7 +421,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
@Override
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
@@ -415,19 +435,18 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
this.taskIncrementer = taskIncrementer;
}
public long getNextExecutionId(){
return taskIncrementer.nextLongValue();
public long getNextExecutionId() {
return this.taskIncrementer.nextLongValue();
}
@Override
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("jobExecutionId", jobExecutionId, Types.BIGINT);
.addValue("jobExecutionId", jobExecutionId, Types.BIGINT);
try {
return jdbcTemplate.queryForObject(
getQuery(FIND_TASK_EXECUTION_BY_JOB_EXECUTION_ID),
queryParameters,
return this.jdbcTemplate.queryForObject(
getQuery(FIND_TASK_EXECUTION_BY_JOB_EXECUTION_ID), queryParameters,
Long.class);
}
catch (EmptyResultDataAccessException e) {
@@ -438,19 +457,20 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
@Override
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
try {
return jdbcTemplate.query(
getQuery(FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID),
queryParameters,
return this.jdbcTemplate.query(
getQuery(FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID), queryParameters,
new ResultSetExtractor<Set<Long>>() {
@Override
public Set<Long> extractData(ResultSet resultSet) throws SQLException, DataAccessException {
public Set<Long> extractData(ResultSet resultSet)
throws SQLException, DataAccessException {
Set<Long> jobExecutionIds = new TreeSet<>();
while(resultSet.next()) {
jobExecutionIds.add(resultSet.getLong("JOB_EXECUTION_ID"));
while (resultSet.next()) {
jobExecutionIds
.add(resultSet.getLong("JOB_EXECUTION_ID"));
}
return jobExecutionIds;
@@ -463,29 +483,27 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
}
@Override
public void updateExternalExecutionId(long taskExecutionId, String externalExecutionId) {
public void updateExternalExecutionId(long taskExecutionId,
String externalExecutionId) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR)
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
if (jdbcTemplate.update(
if (this.jdbcTemplate.update(
getQuery(UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID),
queryParameters) != 1) {
throw new IllegalStateException("Invalid TaskExecution, ID "
+ taskExecutionId + " not found.");
throw new IllegalStateException(
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
}
}
private Page<TaskExecution> queryForPageableResults(Pageable pageable,
String selectClause,
String fromClause,
String whereClause,
MapSqlParameterSource queryParameters,
long totalCount){
String selectClause, String fromClause, String whereClause,
MapSqlParameterSource queryParameters, long totalCount) {
SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean();
factoryBean.setSelectClause(selectClause);
factoryBean.setFromClause(fromClause);
if(StringUtils.hasText(whereClause)){
if (StringUtils.hasText(whereClause)) {
factoryBean.setWhereClause(whereClause);
}
final Sort sort = pageable.getSort();
@@ -493,7 +511,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
if (sort != null) {
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;
try {
pagingQueryProvider = factoryBean.getObject();
pagingQueryProvider.init(dataSource);
pagingQueryProvider.init(this.dataSource);
}
catch (Exception e) {
throw new IllegalStateException(e);
}
String query = pagingQueryProvider.getPageQuery(pageable);
List<TaskExecution> resultList = jdbcTemplate.query(
getQuery(query),
queryParameters,
new TaskExecutionRowMapper());
List<TaskExecution> resultList = this.jdbcTemplate.query(getQuery(query),
queryParameters, new TaskExecutionRowMapper());
return new PageImpl<>(resultList, pageable, totalCount);
}
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
* task arguments.
*
* @param executionId The executionId to which the arguments are associated.
* @param taskArguments The arguments to be stored.
* Convenience method that inserts all arguments from the provided task arguments.
* @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) {
for (String args : taskArguments) {
@@ -541,26 +556,29 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
/**
* Convenience method that inserts an individual records into the
* TASK_EXECUTION_PARAMS table.
* @param taskExecutionId id of a task execution
* @param taskParam task parameters
*/
private void insertArgument(long taskExecutionId, String taskParam) {
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT)
.addValue("taskParam", taskParam, Types.VARCHAR);
jdbcTemplate.update(getQuery(CREATE_TASK_ARGUMENT), queryParameters);
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT)
.addValue("taskParam", taskParam, Types.VARCHAR);
this.jdbcTemplate.update(getQuery(CREATE_TASK_ARGUMENT), queryParameters);
}
private List<String> getTaskArguments(long taskExecutionId){
final List<String> params= new ArrayList<>();
private List<String> getTaskArguments(long taskExecutionId) {
final List<String> params = new ArrayList<>();
RowCallbackHandler handler = new RowCallbackHandler() {
@Override
public void processRow(ResultSet rs) throws SQLException {
params.add(rs.getString(2));
}
};
jdbcTemplate.query(getQuery(FIND_ARGUMENT_FROM_ID), new MapSqlParameterSource("taskExecutionId", taskExecutionId),
handler);
this.jdbcTemplate.query(getQuery(FIND_ARGUMENT_FROM_ID),
new MapSqlParameterSource("taskExecutionId", taskExecutionId), handler);
return params;
}
/**
* Re-usable mapper for {@link TaskExecution} instances.
*
@@ -572,26 +590,23 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
@Override
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");
if(rs.wasNull()) {
if (rs.wasNull()) {
parentExecutionId = null;
}
return new TaskExecution(id,
getNullableExitCode(rs),
rs.getString("TASK_NAME"),
rs.getTimestamp("START_TIME"),
rs.getTimestamp("END_TIME"),
rs.getString("EXIT_MESSAGE"),
getTaskArguments(id),
rs.getString("ERROR_MESSAGE"),
rs.getString("EXTERNAL_EXECUTION_ID"),
parentExecutionId);
return new TaskExecution(id, getNullableExitCode(rs),
rs.getString("TASK_NAME"), rs.getTimestamp("START_TIME"),
rs.getTimestamp("END_TIME"), rs.getString("EXIT_MESSAGE"),
getTaskArguments(id), rs.getString("ERROR_MESSAGE"),
rs.getString("EXTERNAL_EXECUTION_ID"), parentExecutionId);
}
private Integer getNullableExitCode(ResultSet rs) throws SQLException {
int exitCode = rs.getInt("EXIT_CODE");
return !rs.wasNull() ? exitCode : null;
}
}
}

View File

@@ -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");
* 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 {
private final AtomicLong currentId = new AtomicLong(0L);
private ConcurrentMap<Long, TaskExecution> taskExecutions;
private ConcurrentMap<Long, Set<Long>> batchJobAssociations;
private final AtomicLong currentId = new AtomicLong(0L);
public MapTaskExecutionDao() {
taskExecutions = new ConcurrentHashMap<>();
batchJobAssociations = new ConcurrentHashMap<>();
this.taskExecutions = new ConcurrentHashMap<>();
this.batchJobAssociations = new ConcurrentHashMap<>();
}
@Override
public TaskExecution createTaskExecution(String taskName,
Date startTime, List<String> arguments, String externalExecutionId) {
return createTaskExecution(taskName, startTime, arguments,
externalExecutionId, null);
public TaskExecution createTaskExecution(String taskName, Date startTime,
List<String> arguments, String externalExecutionId) {
return createTaskExecution(taskName, startTime, arguments, externalExecutionId,
null);
}
@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();
TaskExecution taskExecution = new TaskExecution(taskExecutionId, null, taskName,
startTime, null, null, arguments, null, externalExecutionId, parentExecutionId);
taskExecutions.put(taskExecutionId, taskExecution);
startTime, null, null, arguments, null, externalExecutionId,
parentExecutionId);
this.taskExecutions.put(taskExecutionId, taskExecution);
return taskExecution;
}
@Override
public TaskExecution startTaskExecution(long executionId, String taskName, Date startTime, List<String> arguments,
String externalExecutionid) {
public TaskExecution startTaskExecution(long executionId, String taskName,
Date startTime, List<String> arguments, String externalExecutionid) {
return startTaskExecution(executionId, taskName, startTime, arguments,
externalExecutionid, null);
}
@@ -84,24 +86,26 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
public TaskExecution startTaskExecution(long executionId, String taskName,
Date startTime, List<String> arguments, String externalExecutionid,
Long parentExecutionId) {
TaskExecution taskExecution= taskExecutions.get(executionId);
TaskExecution taskExecution = this.taskExecutions.get(executionId);
taskExecution.setTaskName(taskName);
taskExecution.setStartTime(startTime);
taskExecution.setArguments(arguments);
taskExecution.setParentExecutionId(parentExecutionId);
if(externalExecutionid != null) {
if (externalExecutionid != null) {
taskExecution.setExternalExecutionId(externalExecutionid);
}
return taskExecution;
}
@Override
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage, String errorMessage) {
if(!this.taskExecutions.containsKey(executionId)) {
throw new IllegalStateException("Invalid TaskExecution, ID " + executionId + " not found.");
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime,
String exitMessage, String errorMessage) {
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.setExitCode(exitCode);
taskExecution.setExitMessage(exitMessage);
@@ -109,19 +113,20 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
}
@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);
}
@Override
public TaskExecution getTaskExecution(long executionId) {
return taskExecutions.get(executionId);
return this.taskExecutions.get(executionId);
}
@Override
public long getTaskExecutionCountByTaskName(String taskName) {
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)) {
count++;
}
@@ -132,9 +137,9 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public long getRunningTaskExecutionCountByTaskName(String taskName) {
int count = 0;
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
if (entry.getValue().getTaskName().equals(taskName) &&
entry.getValue().getEndTime() == null) {
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
if (entry.getValue().getTaskName().equals(taskName)
&& entry.getValue().getEndTime() == null) {
count++;
}
}
@@ -144,8 +149,8 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public long getRunningTaskExecutionCount() {
long count = 0;
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
if ( entry.getValue().getEndTime() == null) {
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
if (entry.getValue().getEndTime() == null) {
count++;
}
}
@@ -154,15 +159,16 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public long getTaskExecutionCount() {
return taskExecutions.size();
return this.taskExecutions.size();
}
@Override
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
Pageable pageable) {
Set<TaskExecution> result = getTaskExecutionTreeSet();
for (Map.Entry<Long, TaskExecution> entry : taskExecutions.entrySet()) {
if (entry.getValue().getTaskName().equals(taskName) &&
entry.getValue().getEndTime() == null) {
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
if (entry.getValue().getTaskName().equals(taskName)
&& entry.getValue().getEndTime() == null) {
result.add(entry.getValue());
}
}
@@ -171,9 +177,10 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
}
@Override
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
Pageable pageable) {
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)) {
filteredSet.add(entry.getValue());
}
@@ -185,7 +192,7 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public List<String> getTaskNames() {
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());
}
return new ArrayList<>(result);
@@ -194,17 +201,17 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public Page<TaskExecution> findAll(Pageable pageable) {
TreeSet<TaskExecution> sortedSet = getTaskExecutionTreeSet();
sortedSet.addAll(taskExecutions.values());
sortedSet.addAll(this.taskExecutions.values());
List<TaskExecution> result = new ArrayList<>(sortedSet.descendingSet());
return getPageFromList(result, pageable, getTaskExecutionCount());
}
public Map<Long, TaskExecution> getTaskExecutions() {
return Collections.unmodifiableMap(taskExecutions);
return Collections.unmodifiableMap(this.taskExecutions);
}
public long getNextExecutionId(){
return currentId.getAndIncrement();
public long getNextExecutionId() {
return this.currentId.getAndIncrement();
}
@Override
@@ -213,9 +220,10 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
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()) {
if(curJobExecutionId.equals(jobExecutionId)) {
if (curJobExecutionId.equals(jobExecutionId)) {
taskId = association.getKey();
break found;
}
@@ -227,8 +235,9 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
if(batchJobAssociations.containsKey(taskExecutionId)) {
return Collections.unmodifiableSet(batchJobAssociations.get(taskExecutionId));
if (this.batchJobAssociations.containsKey(taskExecutionId)) {
return Collections
.unmodifiableSet(this.batchJobAssociations.get(taskExecutionId));
}
else {
return new TreeSet<>();
@@ -236,15 +245,16 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
}
@Override
public void updateExternalExecutionId(long taskExecutionId, String externalExecutionId) {
TaskExecution taskExecution = taskExecutions.get(taskExecutionId);
Assert.notNull(taskExecution, "Invalid TaskExecution, ID "
+ taskExecutionId + " not found.");
public void updateExternalExecutionId(long taskExecutionId,
String externalExecutionId) {
TaskExecution taskExecution = this.taskExecutions.get(taskExecutionId);
Assert.notNull(taskExecution,
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
taskExecution.setExternalExecutionId(externalExecutionId);
}
public ConcurrentMap<Long, Set<Long>> getBatchJobAssociations() {
return batchJobAssociations;
return this.batchJobAssociations;
}
private TreeSet<TaskExecution> getTaskExecutionTreeSet() {
@@ -252,19 +262,22 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public int compare(TaskExecution e1, TaskExecution e2) {
int result = e1.getStartTime().compareTo(e2.getStartTime());
if (result == 0){
result = Long.valueOf(e1.getExecutionId()).compareTo(e2.getExecutionId());
if (result == 0) {
result = Long.valueOf(e1.getExecutionId())
.compareTo(e2.getExecutionId());
}
return result;
}
});
}
private Page getPageFromList(List<TaskExecution> executionList, Pageable pageable, long maxSize){
long toIndex = (pageable.getOffset() + pageable.getPageSize() > executionList.size()) ?
executionList.size() : pageable.getOffset() + pageable.getPageSize();
private Page getPageFromList(List<TaskExecution> executionList, Pageable pageable,
long maxSize) {
long toIndex = (pageable.getOffset() + pageable.getPageSize() > executionList
.size()) ? executionList.size()
: pageable.getOffset() + pageable.getPageSize();
return new PageImpl<>(
executionList.subList((int)pageable.getOffset(), (int)toIndex),
executionList.subList((int) pageable.getOffset(), (int) toIndex),
pageable, maxSize);
}
@@ -281,29 +294,34 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
}
}
Assert.isTrue(taskNamesAsList.size() == taskNames.length,
String.format("Task names must not contain any empty elements but %s of %s were empty or null.",
taskNames.length - taskNamesAsList.size(), taskNames.length));
Assert.isTrue(taskNamesAsList.size() == taskNames.length, String.format(
"Task names must not contain any empty elements but %s of %s were empty or null.",
taskNames.length - taskNamesAsList.size(), taskNames.length));
final Map<String, TaskExecution> tempTaskExecutions = new HashMap<>();
for (Map.Entry<Long, TaskExecution> taskExecutionMapEntry : this.taskExecutions.entrySet()) {
if (!taskNamesAsList.contains(taskExecutionMapEntry.getValue().getTaskName())) {
for (Map.Entry<Long, TaskExecution> taskExecutionMapEntry : this.taskExecutions
.entrySet()) {
if (!taskNamesAsList
.contains(taskExecutionMapEntry.getValue().getTaskName())) {
continue;
}
final TaskExecution tempTaskExecution = tempTaskExecutions.get(taskExecutionMapEntry.getValue().getTaskName());
final TaskExecution tempTaskExecution = tempTaskExecutions
.get(taskExecutionMapEntry.getValue().getTaskName());
if (tempTaskExecution == null
|| tempTaskExecution.getStartTime().before(taskExecutionMapEntry.getValue().getStartTime())
|| (
tempTaskExecution.getStartTime().equals(taskExecutionMapEntry.getValue().getStartTime())
&& tempTaskExecution.getExecutionId() < taskExecutionMapEntry.getValue().getExecutionId()
)
) {
tempTaskExecutions.put(taskExecutionMapEntry.getValue().getTaskName(), taskExecutionMapEntry.getValue());
|| tempTaskExecution.getStartTime()
.before(taskExecutionMapEntry.getValue().getStartTime())
|| (tempTaskExecution.getStartTime()
.equals(taskExecutionMapEntry.getValue().getStartTime())
&& tempTaskExecution.getExecutionId() < taskExecutionMapEntry
.getValue().getExecutionId())) {
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());
return latestTaskExecutions;
}
@@ -311,7 +329,8 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
@Override
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
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()) {
return null;
}
@@ -319,20 +338,29 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
return taskExecutions.get(0);
}
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
public int compare(TaskExecution firstTaskExecution, TaskExecution secondTaskExecution) {
if (firstTaskExecution.getStartTime().equals(secondTaskExecution.getStartTime())) {
return Long.compare(firstTaskExecution.getExecutionId(), secondTaskExecution.getExecutionId());
public int compare(TaskExecution firstTaskExecution,
TaskExecution secondTaskExecution) {
if (firstTaskExecution.getStartTime()
.equals(secondTaskExecution.getStartTime())) {
return Long.compare(firstTaskExecution.getExecutionId(),
secondTaskExecution.getExecutionId());
}
else {
return secondTaskExecution.getStartTime().compareTo(firstTaskExecution.getStartTime());
return secondTaskExecution.getStartTime()
.compareTo(firstTaskExecution.getStartTime());
}
}
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -36,19 +36,17 @@ public interface TaskExecutionDao {
/**
* Save a new {@link TaskExecution}.
*
* @param taskName the name that associated with the task execution.
* @param startTime the time task began.
* @param arguments list of key/value pairs that configure the task.
* @param externalExecutionId id assigned to the task by the platform
* @return A fully qualified {@link TaskExecution} instance.
*/
TaskExecution createTaskExecution( String taskName,
Date startTime, List<String> arguments, String externalExecutionId);
TaskExecution createTaskExecution(String taskName, Date startTime,
List<String> arguments, String externalExecutionId);
/**
* Save a new {@link TaskExecution}.
*
* @param taskName the name that associated with the task execution.
* @param startTime the time task began.
* @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.
* @since 1.2.0
*/
TaskExecution createTaskExecution( String taskName,
Date startTime, List<String> arguments, String externalExecutionId,
Long parentExecutionId);
TaskExecution createTaskExecution(String taskName, Date startTime,
List<String> arguments, String externalExecutionId, Long parentExecutionId);
/**
* 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 startTime the time task began.
* @param arguments list of key/value pairs that configure the task.
* @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
*/
TaskExecution startTaskExecution(long executionId, String taskName,
Date startTime, List<String> arguments, String externalExecutionId);
TaskExecution startTaskExecution(long executionId, String taskName, Date startTime,
List<String> arguments, String externalExecutionId);
/**
* 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 startTime the time task began.
* @param arguments list of key/value pairs that configure the task.
* @param externalExecutionId id assigned to the task by the platform
* @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
*/
TaskExecution startTaskExecution(long executionId, String taskName,
Date startTime, List<String> arguments, String externalExecutionId,
Long parentExecutionId);
TaskExecution startTaskExecution(long executionId, String taskName, Date startTime,
List<String> arguments, String externalExecutionId, Long parentExecutionId);
/**
* 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 endTime the time the task completed.
* @param exitMessage the message assigned to the task upon completion.
* @param errorMessage error information available upon failure of a task.
* @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}.
*
* @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 endTime the time the task completed.
* @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.
*
* @param executionId the id associated with the task execution.
* @return a fully qualified TaskExecution instance.
*/
@@ -123,16 +118,14 @@ public interface TaskExecutionDao {
/**
* Retrieves current number of task executions for a taskName.
*
* @param taskName the name of the task to search for in the repository.
* @return current number of task executions for the 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.
* @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.
*
* @return current number of task executions.
*/
long getRunningTaskExecutionCount();
/**
* Retrieves current number of task executions.
*
* @return current number of task executions.
*/
long getTaskExecutionCount();
@@ -159,7 +149,7 @@ public interface TaskExecutionDao {
* @param pageable the constraints for the search.
* @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.
@@ -172,7 +162,6 @@ public interface TaskExecutionDao {
/**
* Retrieves a sorted list of distinct task names for the task executions.
*
* @return a list of distinct task names from the task repository..
*/
List<String> getTaskNames();
@@ -193,8 +182,7 @@ public interface TaskExecutionDao {
/**
* 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
* @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.
* @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);
@@ -212,35 +201,35 @@ public interface TaskExecutionDao {
* @param taskExecutionId the execution id for the task to be updated.
* @param externalExecutionId the new externalExecutionId.
*/
void updateExternalExecutionId(long taskExecutionId,
String externalExecutionId);
void updateExternalExecutionId(long taskExecutionId, 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
* (The results may including pending {@link TaskExecution}s).
* Latest is defined by the most recent start time. A {@link TaskExecution} does not
* 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
* {@link TaskExecution} for the exact same start time. In that case 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.
* It is theoretically possible that a {@link TaskExecution} with the same name to
* have more than 1 {@link TaskExecution} for the exact same start time. In that case
* 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.
* @param taskNames At least 1 task name must be provided
* @return List of TaskExecutions. May be empty but never null.
*/
List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames);
/**
* Returns the latest task execution for a given task name. Will ultimately apply the same algorithm underneath
* as {@link #getLatestTaskExecutionsByTaskNames(String...)} but will only return a single result.
*
* Returns the latest task execution for a given task name. Will ultimately apply the
* same algorithm underneath as {@link #getLatestTaskExecutionsByTaskNames(String...)}
* but will only return a single result.
* @param taskName Must not be null or empty
* @return The latest Task Execution or null
* @see #getLatestTaskExecutionsByTaskNames(String...)
*/
TaskExecution getLatestTaskExecutionForTaskName(String taskName);
}

View File

@@ -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
* from a repository.

View File

@@ -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");
* 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.
*
* @author Glenn Renfro
*/
public interface PagingQueryProvider {
/**
* Initialize the query provider using the provided {@link DataSource} if necessary.
*
* @param dataSource DataSource to use for any initialization
* @throws Exception throws {@link Exception} if query provider initialize fails.
*/
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
*/
int getParameterCount();
/**
* Indicate whether the generated queries use named parameter syntax.
*
* @return true if named parameter syntax is used
*/
boolean isUsingNamedParameters();
/**
* The sort keys. A Map of the columns that make up the key and a Boolean indicating ascending or descending
* (ascending = true).
*
* The sort keys. A Map of the columns that make up the key and a Boolean indicating
* ascending or descending (ascending = true).
* @return the sort keys used to order the query
*/
Map<String, Order> getSortKeys();
@@ -61,9 +59,9 @@ public interface PagingQueryProvider {
/**
*
* Generate the query that will provide the jump to item query.
*
* @param pageable the coordinates to pull the next page from the datasource
* @return the generated query
*/
String getPageQuery(Pageable pageable);
}

View File

@@ -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");
* 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;
/**
* Abstract SQL Paging Query Provider to serve as a base class for all provided
* SQL paging query providers.
* Abstract SQL Paging Query Provider to serve as a base class for all provided SQL paging
* query providers.
*
* Any implementation must provide a way to specify the select clause, from
* clause and optionally a where clause. It is recommended that there should be an index for
* the sort key to provide better performance.
* Any implementation must provide a way to specify the select clause, from clause and
* optionally a where clause. It is recommended that there should be an index for the sort
* key to provide better performance.
*
* Provides properties and preparation for the mandatory "selectClause" and
* "fromClause" as well as for the optional "whereClause".
* Provides properties and preparation for the mandatory "selectClause" and "fromClause"
* as well as for the optional "whereClause".
*
* @author Glenn Renfro
*/
@@ -51,12 +51,19 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
private String whereClause;
private Map<String, Order> sortKeys = new LinkedHashMap<String, Order>();
private Map<String, Order> sortKeys = new LinkedHashMap<>();
private int parameterCount;
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
*/
@@ -65,11 +72,10 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
}
/**
*
* @return SQL SELECT clause part of SQL query string
* @return SQL FROM clause part of SQL query string
*/
protected String getSelectClause() {
return selectClause;
protected String getFromClause() {
return this.fromClause;
}
/**
@@ -80,11 +86,10 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
}
/**
*
* @return SQL FROM clause part of SQL query string
* @return SQL WHERE clause part of SQL query string
*/
protected String getFromClause() {
return fromClause;
protected String getWhereClause() {
return this.whereClause;
}
/**
@@ -100,11 +105,13 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
}
/**
*
* @return SQL WHERE clause part of SQL query string
* A Map&lt;String, Order&gt; of sort columns as the key and {@link Order} for
* ascending/descending.
* @return sortKey key to use to sort and limit page content
*/
protected String getWhereClause() {
return whereClause;
@Override
public Map<String, Order> getSortKeys() {
return this.sortKeys;
}
/**
@@ -114,56 +121,51 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
this.sortKeys = sortKeys;
}
/**
* A Map&lt;String, Order&gt; 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
public int getParameterCount() {
return parameterCount;
return this.parameterCount;
}
@Override
public boolean isUsingNamedParameters() {
return usingNamedParameters;
return this.usingNamedParameters;
}
@Override
public void init(DataSource dataSource) throws Exception {
Assert.notNull(dataSource, "DataSource must not be null");
Assert.hasLength(selectClause, "selectClause must be specified");
Assert.hasLength(fromClause, "fromClause must be specified");
Assert.notEmpty(sortKeys, "sortKey must be specified");
Assert.hasLength(this.selectClause, "selectClause must be specified");
Assert.hasLength(this.fromClause, "fromClause must be specified");
Assert.notEmpty(this.sortKeys, "sortKey must be specified");
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(selectClause);
sql.append(" FROM ").append(fromClause);
if (whereClause != null) {
sql.append(" WHERE ").append(whereClause);
sql.append("SELECT ").append(this.selectClause);
sql.append(" FROM ").append(this.fromClause);
if (this.whereClause != null) {
sql.append(" WHERE ").append(this.whereClause);
}
List<String> namedParameters = new ArrayList<String>();
parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql.toString(), namedParameters);
List<String> namedParameters = new ArrayList<>();
this.parameterCount = JdbcParameterUtils
.countParameterPlaceholders(sql.toString(), namedParameters);
if (namedParameters.size() > 0) {
if (parameterCount != namedParameters.size()) {
if (this.parameterCount != namedParameters.size()) {
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) {
String temp = clause.trim();
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());
}
else {
return temp;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,9 +19,10 @@ package org.springframework.cloud.task.repository.database.support;
import org.springframework.data.domain.Pageable;
/**
* IBM DB2 implementation of a {@link org.springframework.cloud.task.repository.database.PagingQueryProvider} using database
* specific features.
*
* IBM DB2 implementation of a
* {@link org.springframework.cloud.task.repository.database.PagingQueryProvider} using
* database specific features.
*
* @author Thomas Schuettel
*/
public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
@@ -30,15 +31,18 @@ public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
public String getPageQuery(Pageable pageable) {
long offset = pageable.getOffset() + 1;
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,
String rowNumClause) {
private String generateRowNumSqlQueryWithNesting(String selectClause,
boolean remainingPageQuery, String rowNumClause) {
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");
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);
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
sql.append(")) WHERE ").append(rowNumClause);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -29,8 +29,8 @@ public class H2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String getPageQuery(Pageable pageable) {
String topClause = new StringBuilder().append("LIMIT ")
.append(pageable.getOffset()).append(" ")
.append(pageable.getPageSize()).toString();
.append(pageable.getOffset()).append(" ").append(pageable.getPageSize())
.toString();
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
}

View File

@@ -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");
* 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;
/**
* HSQLDB implementation of a {@link PagingQueryProvider} using database specific features.
* HSQLDB implementation of a {@link PagingQueryProvider} using database specific
* features.
*
* @author Glenn Renfro
*/
@@ -29,8 +30,8 @@ public class HsqlPagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String getPageQuery(Pageable pageable) {
String topClause = new StringBuilder().append("LIMIT ")
.append(pageable.getOffset()).append(" ")
.append(pageable.getPageSize()).toString();
.append(pageable.getOffset()).append(" ").append(pageable.getPageSize())
.toString();
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
}

View File

@@ -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");
* 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
*/
public class MySqlPagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String getPageQuery(Pageable pageable) {
String topClause = new StringBuilder().append("LIMIT ")
.append(pageable.getOffset()).append(", ")
.append(pageable.getPageSize()).toString();
.append(pageable.getOffset()).append(", ").append(pageable.getPageSize())
.toString();
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, topClause);
}

View File

@@ -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");
* 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;
/**
* Oracle implementation of a {@link PagingQueryProvider} using database specific features.
* Oracle implementation of a {@link PagingQueryProvider} using database specific
* features.
*
* @author Glenn Renfro
*/
@@ -28,22 +29,24 @@ public class OraclePagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String getPageQuery(Pageable pageable) {
long offset = pageable.getOffset()+1;
return generateRowNumSqlQueryWithNesting(getSelectClause(), false, "TMP_ROW_NUM >= "
+ offset + " AND TMP_ROW_NUM < " + (offset+pageable.getPageSize()));
long offset = pageable.getOffset() + 1;
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < "
+ (offset + pageable.getPageSize()));
}
private String generateRowNumSqlQueryWithNesting(String selectClause,
boolean remainingPageQuery,
String rowNumClause) {
boolean remainingPageQuery, String rowNumClause) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause)
.append(", ").append("ROWNUM as TMP_ROW_NUM");
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ").append(this.getFromClause());
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ")
.append(selectClause).append(", ").append("ROWNUM as TMP_ROW_NUM");
sql.append(" FROM (SELECT ").append(selectClause).append(" FROM ")
.append(this.getFromClause());
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
sql.append(")) WHERE ").append(rowNumClause);
return sql.toString();
}
}

View File

@@ -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");
* 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;
/**
* Postgres implementation of a {@link PagingQueryProvider} using database specific features.
* Postgres implementation of a {@link PagingQueryProvider} using database specific
* features.
*
* @author Glenn Renfro
*/
@@ -28,9 +29,10 @@ public class PostgresPagingQueryProvider extends AbstractSqlPagingQueryProvider
@Override
public String getPageQuery(Pageable pageable) {
String limitClause = new StringBuilder().append("LIMIT ").
append(pageable.getPageSize()).append(" OFFSET ").
append(pageable.getOffset()).toString();
String limitClause = new StringBuilder().append("LIMIT ")
.append(pageable.getPageSize()).append(" OFFSET ")
.append(pageable.getOffset()).toString();
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, limitClause);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -16,17 +16,6 @@
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.Map;
@@ -40,14 +29,26 @@ import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.util.Assert;
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
* will be determined from the data source if not provided explicitly. Valid
* types are given by the {@link DatabaseType} enum.
* Factory bean for {@link PagingQueryProvider} interface. The database type will be
* determined from the data source if not provided explicitly. Valid types are given by
* the {@link DatabaseType} enum.
*
* @author Glenn Renfro
*/
public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQueryProvider> {
public class SqlPagingQueryProviderFactoryBean
implements FactoryBean<PagingQueryProvider> {
private DataSource dataSource;
@@ -61,20 +62,19 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
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());
providers.put(H2, new H2PagingQueryProvider());
providers.put(MYSQL, new MySqlPagingQueryProvider());
providers.put(POSTGRES, new PostgresPagingQueryProvider());
providers.put(ORACLE, new OraclePagingQueryProvider());
providers.put(SQLSERVER, new SqlServerPagingQueryProvider());
providers.put(DB2, new Db2PagingQueryProvider());
providers.put(DB2VSE, new Db2PagingQueryProvider());
providers.put(DB2ZOS, new Db2PagingQueryProvider());
providers.put(DB2AS400, new Db2PagingQueryProvider());
this.providers.put(HSQL, new HsqlPagingQueryProvider());
this.providers.put(H2, new H2PagingQueryProvider());
this.providers.put(MYSQL, new MySqlPagingQueryProvider());
this.providers.put(POSTGRES, new PostgresPagingQueryProvider());
this.providers.put(ORACLE, new OraclePagingQueryProvider());
this.providers.put(SQLSERVER, new SqlServerPagingQueryProvider());
this.providers.put(DB2, new Db2PagingQueryProvider());
this.providers.put(DB2VSE, new Db2PagingQueryProvider());
this.providers.put(DB2ZOS, 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
* and appropriate for the given database type.
* Get a {@link PagingQueryProvider} instance using the provided properties and
* appropriate for the given database type.
*
* @see FactoryBean#getObject()
*/
@@ -134,24 +134,28 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
DatabaseType type;
try {
type = databaseType != null ? DatabaseType.valueOf(databaseType.toUpperCase()) : DatabaseType
.fromMetaData(dataSource);
type = this.databaseType != null
? DatabaseType.valueOf(this.databaseType.toUpperCase())
: DatabaseType.fromMetaData(this.dataSource);
}
catch (MetaDataAccessException e) {
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);
Assert.state(provider != null, "Should not happen: missing PagingQueryProvider for DatabaseType=" + type);
AbstractSqlPagingQueryProvider provider = this.providers.get(type);
Assert.state(provider != null,
"Should not happen: missing PagingQueryProvider for DatabaseType="
+ type);
provider.setFromClause(fromClause);
provider.setWhereClause(whereClause);
provider.setSortKeys(sortKeys);
if (StringUtils.hasText(selectClause)) {
provider.setSelectClause(selectClause);
provider.setFromClause(this.fromClause);
provider.setWhereClause(this.whereClause);
provider.setSortKeys(this.sortKeys);
if (StringUtils.hasText(this.selectClause)) {
provider.setSelectClause(this.selectClause);
}
provider.init(dataSource);
provider.init(this.dataSource);
return provider;
@@ -176,4 +180,5 @@ public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQuer
public boolean isSingleton() {
return true;
}
}

View File

@@ -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");
* 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;
/**
* Utility class that generates the actual SQL statements used by query
* providers.
* Utility class that generates the actual SQL statements used by query providers.
*
* @author Glenn Renfro
*/
public class SqlPagingQueryUtils {
public final class SqlPagingQueryUtils {
private SqlPagingQueryUtils(){}
private SqlPagingQueryUtils() {
}
/**
* Generate SQL query string using a LIMIT clause
*
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
* implementation specifics
* Generate SQL query string using a LIMIT clause.
* @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation
* specifics
* @param limitClause the implementation specific top clause to be used
* @return the generated query
*/
public static String generateLimitJumpToQuery(AbstractSqlPagingQueryProvider provider, String limitClause) {
public static String generateLimitJumpToQuery(AbstractSqlPagingQueryProvider provider,
String limitClause) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(provider.getSelectClause());
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(" ").append(limitClause);
@@ -50,18 +51,20 @@ public class SqlPagingQueryUtils {
}
/**
* Generate SQL query string using a TOP clause
*
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
* implementation specifics
* Generate SQL query string using a TOP clause.
* @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation
* specifics
* @param topClause the implementation specific top clause to be used
* @return the generated query
*/
public static String generateTopJumpToQuery(AbstractSqlPagingQueryProvider provider, String topClause) {
public static String generateTopJumpToQuery(AbstractSqlPagingQueryProvider provider,
String topClause) {
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(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
sql.append(provider.getWhereClause() == null ? ""
: " WHERE " + provider.getWhereClause());
sql.append(" ORDER BY ").append(buildSortClause(provider));
return sql.toString();
@@ -69,13 +72,12 @@ public class SqlPagingQueryUtils {
/**
* Generates WHERE clause for queries that require sub selects.
*
* @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 sql the sql statement to be appended.
*/
public static void buildWhereClause( AbstractSqlPagingQueryProvider provider,
boolean remainingPageQuery, StringBuilder sql) {
public static void buildWhereClause(AbstractSqlPagingQueryProvider provider,
boolean remainingPageQuery, StringBuilder sql) {
if (remainingPageQuery) {
sql.append(" WHERE ");
if (provider.getWhereClause() != null) {
@@ -85,15 +87,15 @@ public class SqlPagingQueryUtils {
}
}
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.
*
* @param provider {@link AbstractSqlPagingQueryProvider} providing the
* implementation specifics
* @param provider {@link AbstractSqlPagingQueryProvider} providing the implementation
* specifics
* @return a String that can be appended to an ORDER BY clause.
*/
public static String buildSortClause(AbstractSqlPagingQueryProvider provider) {
@@ -102,7 +104,6 @@ public class SqlPagingQueryUtils {
/**
* Generates ORDER BY attributes based on the sort keys.
*
* @param sortKeys generates order by clause from map
* @return a String that can be appended to an ORDER BY clause.
*/
@@ -117,7 +118,7 @@ public class SqlPagingQueryUtils {
builder.append(sortKey.getKey());
if(sortKey.getValue() != null && sortKey.getValue() == Order.DESCENDING) {
if (sortKey.getValue() != null && sortKey.getValue() == Order.DESCENDING) {
builder.append(" DESC");
}
else {
@@ -127,4 +128,5 @@ public class SqlPagingQueryUtils {
return builder.toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,31 +20,33 @@ import org.springframework.cloud.task.repository.database.PagingQueryProvider;
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
*/
public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider{
public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider {
@Override
public String getPageQuery(Pageable pageable) {
long offset = pageable.getOffset()+1;
return generateRowNumSqlQueryWithNesting(getSelectClause(), false, "TMP_ROW_NUM >= "
+ offset + " AND TMP_ROW_NUM < " + (offset+pageable.getPageSize()));
long offset = pageable.getOffset() + 1;
return generateRowNumSqlQueryWithNesting(getSelectClause(), false,
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < "
+ (offset + pageable.getPageSize()));
}
private String generateRowNumSqlQueryWithNesting(String selectClause,
boolean remainingPageQuery,
String rowNumClause) {
boolean remainingPageQuery, String rowNumClause) {
StringBuilder sql = new StringBuilder();
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ").append(selectClause)
.append(", ").append("ROW_NUMBER() OVER (ORDER BY ")
sql.append("SELECT ").append(selectClause).append(" FROM (SELECT ")
.append(selectClause).append(", ").append("ROW_NUMBER() OVER (ORDER BY ")
.append(SqlPagingQueryUtils.buildSortClause(this))
.append(") AS TMP_ROW_NUM ")
.append(" FROM ").append(getFromClause());
.append(") AS TMP_ROW_NUM ").append(" FROM ").append(getFromClause());
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
sql.append(") TASK_EXECUTION_PAGE ");
sql.append(" WHERE ").append(rowNumClause);
sql.append(" ORDER BY ").append(SqlPagingQueryUtils.buildSortClause(this));
return sql.toString();
}
}

View File

@@ -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");
* 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.util.StringUtils;
/**
* Enum representing a database type, such as DB2 or oracle. The type also
* contains a product name, which is expected to be the same as the product name
* provided by the database driver's metadata.
* Enum representing a database type, such as DB2 or oracle. The type also contains a
* product name, which is expected to be the same as the product name provided by the
* database driver's metadata.
*
* @author Glenn Renfro
*/
public enum DatabaseType {
/**
* HSQL DB.
*/
HSQL("HSQL Database Engine"),
/**
* H2 DB.
*/
H2("H2"),
/**
* Oracle DB.
*/
ORACLE("Oracle"),
/**
* MySQL DB.
*/
MYSQL("MySQL"),
/**
* PostgreSQL DB.
*/
POSTGRES("PostgreSQL"),
/**
* Microsoft SQL Server DB.
*/
SQLSERVER("Microsoft SQL Server"),
/**
* DB2 DB.
*/
DB2("DB2"),
/**
* DB2VSE DB.
*/
DB2VSE("DB2VSE"),
/**
* DB2ZOS DB.
*/
DB2ZOS("DB2ZOS"),
/**
* DB2AS400 DB.
*/
DB2AS400("DB2AS400");
private static final Map<String, DatabaseType> dbNameMap;
static {
dbNameMap = new HashMap<>();
for (DatabaseType type : values()) {
dbNameMap.put(type.getProductName(), type);
}
}
private final String productName;
DatabaseType(String 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.
* @return DatabaseType The database type associated with the datasource.
* @throws MetaDataAccessException thrown if failure occurs on metadata lookup.
*/
public static DatabaseType fromMetaData(DataSource dataSource) throws MetaDataAccessException {
String databaseProductName =
JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductName").toString();
if (StringUtils.hasText(databaseProductName) && !databaseProductName.equals("DB2/Linux") && databaseProductName.startsWith("DB2")) {
String databaseProductVersion =
JdbcUtils.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion").toString();
public static DatabaseType fromMetaData(DataSource dataSource)
throws MetaDataAccessException {
String databaseProductName = JdbcUtils
.extractDatabaseMetaData(dataSource, "getDatabaseProductName").toString();
if (StringUtils.hasText(databaseProductName)
&& !databaseProductName.equals("DB2/Linux")
&& databaseProductName.startsWith("DB2")) {
String databaseProductVersion = JdbcUtils
.extractDatabaseMetaData(dataSource, "getDatabaseProductVersion")
.toString();
if (databaseProductVersion.startsWith("ARI")) {
databaseProductName = "DB2VSE";
}
else if (databaseProductVersion.startsWith("DSN")) {
databaseProductName = "DB2ZOS";
}
else if (databaseProductName.indexOf("AS") != -1 && (databaseProductVersion.startsWith("QSQ") ||
databaseProductVersion.substring(databaseProductVersion.indexOf('V')).matches("V\\dR\\d[mM]\\d"))) {
else if (databaseProductName.indexOf("AS") != -1
&& (databaseProductVersion.startsWith("QSQ") || databaseProductVersion
.substring(databaseProductVersion.indexOf('V'))
.matches("V\\dR\\d[mM]\\d"))) {
databaseProductName = "DB2AS400";
}
else {
@@ -96,23 +140,22 @@ public enum DatabaseType {
/**
* Static method to obtain a DatabaseType from the provided product name.
*
* @param productName the name of the database.
* @return DatabaseType for given product name.
* @throws IllegalArgumentException if none is found.
*/
public static DatabaseType fromProductName(String productName){
if(!dbNameMap.containsKey(productName)){
throw new IllegalArgumentException("DatabaseType not found for product name: [" +
productName + "]");
public static DatabaseType fromProductName(String productName) {
if (!dbNameMap.containsKey(productName)) {
throw new IllegalArgumentException(
"DatabaseType not found for product name: [" + productName + "]");
}
else{
else {
return dbNameMap.get(productName);
}
}
private String getProductName() {
return productName;
return this.productName;
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -39,7 +39,8 @@ public class SimpleTaskExplorer implements TaskExplorer {
private TaskExecutionDao taskExecutionDao;
public SimpleTaskExplorer(TaskExecutionDaoFactoryBean taskExecutionDaoFactoryBean) {
Assert.notNull(taskExecutionDaoFactoryBean, "taskExecutionDaoFactoryBean must not be null");
Assert.notNull(taskExecutionDaoFactoryBean,
"taskExecutionDaoFactoryBean must not be null");
try {
this.taskExecutionDao = taskExecutionDaoFactoryBean.getObject();
@@ -51,62 +52,64 @@ public class SimpleTaskExplorer implements TaskExplorer {
@Override
public TaskExecution getTaskExecution(long executionId) {
return taskExecutionDao.getTaskExecution(executionId);
return this.taskExecutionDao.getTaskExecution(executionId);
}
@Override
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
return taskExecutionDao.findRunningTaskExecutions(taskName, pageable);
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
Pageable pageable) {
return this.taskExecutionDao.findRunningTaskExecutions(taskName, pageable);
}
@Override
public List<String> getTaskNames() {
return taskExecutionDao.getTaskNames();
return this.taskExecutionDao.getTaskNames();
}
@Override
public long getTaskExecutionCountByTaskName(String taskName) {
return taskExecutionDao.getTaskExecutionCountByTaskName(taskName);
return this.taskExecutionDao.getTaskExecutionCountByTaskName(taskName);
}
@Override
public long getTaskExecutionCount() {
return taskExecutionDao.getTaskExecutionCount();
return this.taskExecutionDao.getTaskExecutionCount();
}
@Override
public long getRunningTaskExecutionCount() {
return taskExecutionDao.getRunningTaskExecutionCount();
return this.taskExecutionDao.getRunningTaskExecutionCount();
}
@Override
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
return taskExecutionDao.findTaskExecutionsByName(taskName, pageable);
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
Pageable pageable) {
return this.taskExecutionDao.findTaskExecutionsByName(taskName, pageable);
}
@Override
public Page<TaskExecution> findAll(Pageable pageable) {
return taskExecutionDao.findAll(pageable);
return this.taskExecutionDao.findAll(pageable);
}
@Override
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
return taskExecutionDao.getTaskExecutionIdByJobExecutionId(jobExecutionId);
return this.taskExecutionDao.getTaskExecutionIdByJobExecutionId(jobExecutionId);
}
@Override
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
return taskExecutionDao.getJobExecutionIdsByTaskExecutionId(taskExecutionId);
return this.taskExecutionDao.getJobExecutionIdsByTaskExecutionId(taskExecutionId);
}
@Override
public List<TaskExecution> getLatestTaskExecutionsByTaskNames(String... taskNames) {
return taskExecutionDao.getLatestTaskExecutionsByTaskNames(taskNames);
return this.taskExecutionDao.getLatestTaskExecutionsByTaskNames(taskNames);
}
@Override
public TaskExecution getLatestTaskExecutionForTaskName(String taskName) {
return taskExecutionDao.getLatestTaskExecutionForTaskName(taskName);
return this.taskExecutionDao.getLatestTaskExecutionForTaskName(taskName);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository.support;
import org.springframework.beans.BeansException;
@@ -23,11 +24,11 @@ import org.springframework.context.ApplicationContextAware;
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:
* <ol>
* <li>A configured property <code>spring.cloud.task.name</code></li>
* <li>The {@link ApplicationContext}'s id.</li>
* <li>A configured property <code>spring.cloud.task.name</code></li>
* <li>The {@link ApplicationContext}'s id.</li>
* </ol>
*
* @author Michael Minella
@@ -45,17 +46,19 @@ public class SimpleTaskNameResolver implements TaskNameResolver, ApplicationCont
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.context = applicationContext;
}
@Override
public String getTaskName() {
if(StringUtils.hasText(configuredName)) {
return configuredName;
if (StringUtils.hasText(this.configuredName)) {
return this.configuredName;
}
else {
return context.getId().replace(":", "_");
return this.context.getId().replace(":", "_");
}
}
}

View File

@@ -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");
* 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.
*
* @author Glenn Renfro
*/
public class SimpleTaskRepository implements TaskRepository {
/**
* Max exit message size.
*/
public static final int MAX_EXIT_MESSAGE_SIZE = 2500;
/**
* Max task name size.
*/
public static final int MAX_TASK_NAME_SIZE = 100;
/**
* Max error message size.
*/
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;
@@ -53,63 +65,63 @@ public class SimpleTaskRepository implements TaskRepository {
private int maxErrorMessageSize = MAX_ERROR_MESSAGE_SIZE;
public SimpleTaskRepository(FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean){
Assert.notNull(taskExecutionDaoFactoryBean, "A FactoryBean that provides a TaskExecutionDao is required");
public SimpleTaskRepository(
FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean) {
Assert.notNull(taskExecutionDaoFactoryBean,
"A FactoryBean that provides a TaskExecutionDao is required");
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
}
public SimpleTaskRepository(FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean, Integer maxExitMessageSize,
Integer maxTaskNameSize, Integer maxErrorMessageSize){
Assert.notNull(taskExecutionDaoFactoryBean, "A FactoryBean that provides a TaskExecutionDao is required");
if(maxTaskNameSize != null) {
public SimpleTaskRepository(FactoryBean<TaskExecutionDao> taskExecutionDaoFactoryBean,
Integer maxExitMessageSize, Integer maxTaskNameSize,
Integer maxErrorMessageSize) {
Assert.notNull(taskExecutionDaoFactoryBean,
"A FactoryBean that provides a TaskExecutionDao is required");
if (maxTaskNameSize != null) {
this.maxTaskNameSize = maxTaskNameSize;
}
if(maxExitMessageSize != null) {
if (maxExitMessageSize != null) {
this.maxExitMessageSize = maxExitMessageSize;
}
if(maxErrorMessageSize != null) {
if (maxErrorMessageSize != null) {
this.maxErrorMessageSize = maxErrorMessageSize;
}
this.taskExecutionDaoFactoryBean = taskExecutionDaoFactoryBean;
}
@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);
}
@Override
public TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
String exitMessage, String errorMessage) {
public TaskExecution completeTaskExecution(long executionId, Integer exitCode,
Date endTime, String exitMessage, String errorMessage) {
initialize();
validateCompletedTaskExitInformation(executionId, exitCode, endTime);
exitMessage = trimMessage(exitMessage, this.maxExitMessageSize);
errorMessage = trimMessage(errorMessage, this.maxErrorMessageSize);
taskExecutionDao.completeTaskExecution(executionId, exitCode, endTime, exitMessage, errorMessage);
logger.debug("Updating: TaskExecution with executionId="+executionId
+ " with the following {"
+ "exitCode=" + exitCode
+ ", endTime=" + endTime
+ ", exitMessage='" + exitMessage + '\''
+ ", errorMessage='" + errorMessage + '\''
+ '}');
this.taskExecutionDao.completeTaskExecution(executionId, exitCode, endTime,
exitMessage, errorMessage);
logger.debug("Updating: TaskExecution with executionId=" + executionId
+ " with the following {" + "exitCode=" + exitCode + ", endTime="
+ endTime + ", exitMessage='" + exitMessage + '\'' + ", errorMessage='"
+ errorMessage + '\'' + '}');
return taskExecutionDao.getTaskExecution(executionId);
return this.taskExecutionDao.getTaskExecution(executionId);
}
@Override
public TaskExecution createTaskExecution(TaskExecution taskExecution) {
initialize();
validateCreateInformation(taskExecution);
TaskExecution daoTaskExecution =
taskExecutionDao.createTaskExecution(
taskExecution.getTaskName(),
taskExecution.getStartTime(),
taskExecution.getArguments(),
taskExecution.getExternalExecutionId(),
taskExecution.getParentExecutionId());
TaskExecution daoTaskExecution = this.taskExecutionDao.createTaskExecution(
taskExecution.getTaskName(), taskExecution.getStartTime(),
taskExecution.getArguments(), taskExecution.getExternalExecutionId(),
taskExecution.getParentExecutionId());
logger.debug("Creating: " + taskExecution.toString());
return daoTaskExecution;
}
@@ -117,21 +129,20 @@ public class SimpleTaskRepository implements TaskRepository {
@Override
public TaskExecution createTaskExecution(String name) {
initialize();
TaskExecution taskExecution =
taskExecutionDao.createTaskExecution(name, null,
Collections.<String>emptyList(), null);
TaskExecution taskExecution = this.taskExecutionDao.createTaskExecution(name,
null, Collections.<String>emptyList(), null);
logger.debug("Creating: " + taskExecution.toString());
return taskExecution;
}
@Override
public TaskExecution createTaskExecution() {
return createTaskExecution((String)null);
return createTaskExecution((String) null);
}
@Override
public TaskExecution startTaskExecution(long executionid, String taskName, Date startTime, List<String> arguments,
String externalExecutionId) {
public TaskExecution startTaskExecution(long executionid, String taskName,
Date startTime, List<String> arguments, String externalExecutionId) {
return startTaskExecution(executionid, taskName, startTime, arguments,
externalExecutionId, null);
}
@@ -139,7 +150,7 @@ public class SimpleTaskRepository implements TaskRepository {
@Override
public void updateExternalExecutionId(long executionid, String externalExecutionId) {
initialize();
taskExecutionDao.updateExternalExecutionId(executionid, externalExecutionId);
this.taskExecutionDao.updateExternalExecutionId(executionid, externalExecutionId);
}
@Override
@@ -147,10 +158,9 @@ public class SimpleTaskRepository implements TaskRepository {
Date startTime, List<String> arguments, String externalExecutionId,
Long parentExecutionId) {
initialize();
TaskExecution taskExecution =
taskExecutionDao.startTaskExecution(executionid, taskName,
startTime, arguments, externalExecutionId,
parentExecutionId);
TaskExecution taskExecution = this.taskExecutionDao.startTaskExecution(
executionid, taskName, startTime, arguments, externalExecutionId,
parentExecutionId);
logger.debug("Starting: " + taskExecution.toString());
return taskExecution;
}
@@ -161,44 +171,47 @@ public class SimpleTaskRepository implements TaskRepository {
*/
public TaskExecutionDao getTaskExecutionDao() {
initialize();
return taskExecutionDao;
return this.taskExecutionDao;
}
private void initialize() {
if(!initialized) {
if (!this.initialized) {
try {
this.taskExecutionDao = this.taskExecutionDaoFactoryBean.getObject();
this.initialized = true;
}
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.
* @param taskExecution task execution to validate
*/
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 &&
taskExecution.getTaskName().length() > this.maxTaskNameSize) {
throw new IllegalArgumentException("TaskName length exceeds "
+ this.maxTaskNameSize + " characters");
if (taskExecution.getTaskName() != null
&& taskExecution.getTaskName().length() > this.maxTaskNameSize) {
throw new IllegalArgumentException(
"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.isTrue(exitCode >= 0, "exit code must be greater than or equal to zero");
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;
if(exitMessage != null &&
exitMessage.length() > maxSize) {
if (exitMessage != null && exitMessage.length() > maxSize) {
result = exitMessage.substring(0, maxSize);
}
return result;
@@ -215,4 +228,5 @@ public class SimpleTaskRepository implements TaskRepository {
public void setMaxErrorMessageSize(int maxErrorMessageSize) {
this.maxErrorMessageSize = maxErrorMessageSize;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository.support;
import javax.sql.DataSource;
@@ -43,7 +44,7 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
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>
*/
public TaskExecutionDaoFactoryBean() {
@@ -51,7 +52,6 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
/**
* {@link DataSource} to be used.
*
* @param dataSource {@link DataSource} to be used.
* @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.
*
* @param dataSource {@link DataSource} to be used.
*/
public TaskExecutionDaoFactoryBean(DataSource dataSource) {
@@ -74,7 +73,7 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
@Override
public TaskExecutionDao getObject() throws Exception {
if(this.dao == null) {
if (this.dao == null) {
if (this.dataSource != null) {
buildTaskExecutionDao(this.dataSource);
}
@@ -97,15 +96,19 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
}
private void buildTaskExecutionDao(DataSource dataSource) {
DataFieldMaxValueIncrementerFactory incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(dataSource);
DataFieldMaxValueIncrementerFactory incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(
dataSource);
this.dao = new JdbcTaskExecutionDao(dataSource, this.tablePrefix);
String databaseType;
try {
databaseType = org.springframework.batch.support.DatabaseType.fromMetaData(dataSource).name();
databaseType = org.springframework.batch.support.DatabaseType
.fromMetaData(dataSource).name();
}
catch (MetaDataAccessException 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"));
}
}

View File

@@ -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");
* 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;
/**
* 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
* (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
* (if desired).
* (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 (if
* desired).
*
* By default, initialization of the database can be disabled by configuring the property
* <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}}")
private String tablePrefix;
public TaskRepositoryInitializer(){
public TaskRepositoryInitializer() {
}
public void setDataSource(DataSource dataSource) {
@@ -81,7 +81,9 @@ public final class TaskRepositoryInitializer implements InitializingBean {
private String getDatabaseType(DataSource dataSource) {
try {
return JdbcUtils.commonDatabaseName(DatabaseType.fromMetaData(dataSource).toString()).toLowerCase();
return JdbcUtils
.commonDatabaseName(DatabaseType.fromMetaData(dataSource).toString())
.toLowerCase();
}
catch (MetaDataAccessException ex) {
throw new IllegalStateException("Unable to detect database type", ex);
@@ -90,10 +92,9 @@ public final class TaskRepositoryInitializer implements InitializingBean {
@Override
public void afterPropertiesSet() throws Exception {
if (dataSource != null &&
taskInitializationEnable &&
!StringUtils.hasText(this.tablePrefix)) {
String platform = getDatabaseType(dataSource);
if (this.dataSource != null && this.taskInitializationEnable
&& !StringUtils.hasText(this.tablePrefix)) {
String platform = getDatabaseType(this.dataSource);
if ("hsql".equals(platform)) {
platform = "hsqldb";
}
@@ -106,17 +107,18 @@ public final class TaskRepositoryInitializer implements InitializingBean {
if ("mysql".equals(platform)) {
platform = "mysql";
}
if ("sqlserver".equals(platform)){
if ("sqlserver".equals(platform)) {
platform = "sqlserver";
}
ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
String schemaLocation = schema;
schemaLocation = schemaLocation.replace("@@platform@@", platform);
populator.addScript(resourceLoader.getResource(schemaLocation));
populator.addScript(this.resourceLoader.getResource(schemaLocation));
populator.setContinueOnError(true);
logger.debug(String.format("Initializing task schema for %s database",
platform));
DatabasePopulatorUtils.execute(populator, dataSource);
logger.debug(
String.format("Initializing task schema for %s database", platform));
DatabasePopulatorUtils.execute(populator, this.dataSource);
}
}
}

View File

@@ -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.
*/

View File

@@ -1,10 +1,10 @@
{
"properties": [
{
"defaultValue": false,
"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.",
"type": "java.lang.Boolean"
}
]
"properties": [
{
"defaultValue": false,
"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.",
"type": "java.lang.Boolean"
}
]
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task;
@@ -25,8 +25,7 @@ import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Verifies that the beans created by the SimpleSingleTaskAutoConfigurationConfiguration
@@ -43,15 +42,18 @@ public class SimpleSingleTaskAutoConfigurationTests {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
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());
});
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task;
@@ -26,8 +26,7 @@ import org.springframework.cloud.task.configuration.SimpleTaskAutoConfiguration;
import org.springframework.cloud.task.configuration.SingleInstanceTaskListener;
import org.springframework.cloud.task.configuration.SingleTaskConfiguration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Verifies that the beans created by the SimpleSingleTaskAutoConfigurationConfiguration
@@ -44,16 +43,19 @@ public class SimpleSingleTaskAutoConfigurationWithDataSourceTests {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class,
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class,
EmbeddedDataSourceConfiguration.class))
.withPropertyValues("spring.cloud.task.singleInstanceEnabled=true");
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());
});
}
}

View File

@@ -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");
* 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 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;
/**
@@ -71,10 +71,10 @@ public class SimpleTaskAutoConfigurationTests {
@Test
public void testRepository() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class));
.withConfiguration(
AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class));
applicationContextRunner.run((context) -> {
TaskRepository taskRepository = context.getBean(TaskRepository.class);
@@ -89,50 +89,50 @@ public class SimpleTaskAutoConfigurationTests {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withPropertyValues("spring.cloud.task.autoconfiguration.enabled=false");
Executable executable = () -> {
applicationContextRunner.run((context) -> {
context.getBean(TaskRepository.class);
});
};
verifyExceptionThrown(NoSuchBeanDefinitionException.class, "No qualifying " +
"bean of type 'org.springframework.cloud.task.repository.TaskRepository' " +
"available", executable);
verifyExceptionThrown(NoSuchBeanDefinitionException.class, "No qualifying "
+ "bean of type 'org.springframework.cloud.task.repository.TaskRepository' "
+ "available", executable);
}
@Test
public void testRepositoryInitialized() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
.withConfiguration(AutoConfigurations.of(
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withUserConfiguration(TaskLifecycleListenerConfiguration.class);
applicationContextRunner.run((context) -> {
TaskExplorer taskExplorer = context.getBean(TaskExplorer.class);
assertThat(taskExplorer.getTaskExecutionCount()).isEqualTo(1l);
assertThat(taskExplorer.getTaskExecutionCount()).isEqualTo(1L);
});
}
@Test
public void testRepositoryNotInitialized() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EmbeddedDataSourceConfiguration.class,
.withConfiguration(AutoConfigurations.of(
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withUserConfiguration(TaskLifecycleListenerConfiguration.class)
.withPropertyValues("spring.cloud.task.tablePrefix=foobarless");
verifyExceptionThrownDefaultExecutable(ApplicationContextException.class, "Failed to start " +
"bean 'taskLifecycleListener'; nested exception is " +
"org.springframework.dao.DataAccessResourceFailureException: " +
"Could not obtain sequence value; nested exception is org.h2.jdbc.JdbcSQLException: " +
"Syntax error in SQL statement \"SELECT FOOBARLESSSEQ.NEXTVAL FROM[*] DUAL \"; " +
"expected \"identifier\"; SQL statement:\n" +
"select foobarlessSEQ.nextval from dual [42001-197]", applicationContextRunner);
verifyExceptionThrownDefaultExecutable(ApplicationContextException.class,
"Failed to start " + "bean 'taskLifecycleListener'; nested exception is "
+ "org.springframework.dao.DataAccessResourceFailureException: "
+ "Could not obtain sequence value; nested exception is org.h2.jdbc.JdbcSQLException: "
+ "Syntax error in SQL statement \"SELECT FOOBARLESSSEQ.NEXTVAL FROM[*] DUAL \"; "
+ "expected \"identifier\"; SQL statement:\n"
+ "select foobarlessSEQ.nextval from dual [42001-197]",
applicationContextRunner);
}
@Test
@@ -140,29 +140,32 @@ public class SimpleTaskAutoConfigurationTests {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withUserConfiguration(MultipleConfigurers.class);
verifyExceptionThrownDefaultExecutable(BeanCreationException.class, "Error creating bean " +
"with name 'simpleTaskAutoConfiguration': Invocation of init " +
"method failed; nested exception is java.lang.IllegalStateException:" +
" Expected one TaskConfigurer but found 2", applicationContextRunner);
verifyExceptionThrownDefaultExecutable(BeanCreationException.class,
"Error creating bean "
+ "with name 'simpleTaskAutoConfiguration': Invocation of init "
+ "method failed; nested exception is java.lang.IllegalStateException:"
+ " Expected one TaskConfigurer but found 2",
applicationContextRunner);
}
@Test
public void testMultipleDataSources() {
ApplicationContextRunner applicationContextRunner = new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
.withConfiguration(AutoConfigurations.of(
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withUserConfiguration(MultipleDataSources.class);
verifyExceptionThrownDefaultExecutable(BeanCreationException.class, "Error creating bean " +
"with name 'simpleTaskAutoConfiguration': Invocation of init method " +
"failed; nested exception is java.lang.IllegalStateException: To use " +
"the default TaskConfigurer the context must contain no more than " +
"one DataSource, found 2", applicationContextRunner);
verifyExceptionThrownDefaultExecutable(BeanCreationException.class,
"Error creating bean "
+ "with name 'simpleTaskAutoConfiguration': Invocation of init method "
+ "failed; nested exception is java.lang.IllegalStateException: To use "
+ "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);
}
public void verifyExceptionThrown(Class classToCheck, String message, Executable executable) {
Throwable exception = assertThrows(classToCheck, executable);
assertThat(exception.getMessage()).isEqualTo(message);
public void verifyExceptionThrown(Class classToCheck, String message,
Executable executable) {
assertThatExceptionOfType(classToCheck).isThrownBy(executable::execute)
.withMessage(message);
}
/**
* Verify that the verifyEnvironment method skips DataSource Proxy Beans when determining
* the number of available dataSources.
* Verify that the verifyEnvironment method skips DataSource Proxy Beans when
* determining the number of available dataSources.
*/
@Test
public void testWithDataSourceProxy() {
@@ -193,12 +197,12 @@ public class SimpleTaskAutoConfigurationTests {
.withConfiguration(AutoConfigurations.of(
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class))
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class))
.withUserConfiguration(DataSourceProxyConfiguration.class);
applicationContextRunner.run((context) -> {
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.taskExplorer()).isNotNull();
});
@@ -216,6 +220,7 @@ public class SimpleTaskAutoConfigurationTests {
public TaskConfigurer taskConfigurer2() {
return new DefaultTaskConfigurer((DataSource) null);
}
}
@Configuration
@@ -243,9 +248,10 @@ public class SimpleTaskAutoConfigurationTests {
public BeanDefinitionHolder proxyDataSource() {
GenericBeanDefinition proxyBeanDefinition = new GenericBeanDefinition();
proxyBeanDefinition.setBeanClassName("javax.sql.DataSource");
BeanDefinitionHolder myDataSource = new BeanDefinitionHolder(proxyBeanDefinition, "dataSource2");
ScopedProxyUtils.createScopedProxy(myDataSource, (BeanDefinitionRegistry) this.context.getBeanFactory(),
true);
BeanDefinitionHolder myDataSource = new BeanDefinitionHolder(
proxyBeanDefinition, "dataSource2");
ScopedProxyUtils.createScopedProxy(myDataSource,
(BeanDefinitionRegistry) this.context.getBeanFactory(), true);
return myDataSource;
}

View File

@@ -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");
* 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.annotation.Bean;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Verifies core behavior for Tasks.
@@ -41,42 +41,49 @@ import static org.junit.Assert.assertTrue;
public class TaskCoreTests {
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
public OutputCapture outputCapture = new OutputCapture();
private ConfigurableApplicationContext applicationContext;
@After
public void teardown() {
if (applicationContext != null && applicationContext.isActive()) {
applicationContext.close();
if (this.applicationContext != null && this.applicationContext.isActive()) {
this.applicationContext.close();
}
}
@Test
public void successfulTaskTest() {
this.applicationContext = SpringApplication.run( TaskConfiguration.class,
this.applicationContext = SpringApplication.run(TaskConfiguration.class,
"--spring.cloud.task.closecontext.enable=false",
"--spring.cloud.task.name=" + TASK_NAME,
"--spring.main.web-environment=false");
String output = this.outputCapture.toString();
assertTrue("Test results do not show create task message: " + output,
output.contains(CREATE_TASK_MESSAGE));
assertTrue("Test results do not show success message: " + output,
output.contains(UPDATE_TASK_MESSAGE));
assertTrue("Test results have incorrect exit code: " + output,
output.contains(SUCCESS_EXIT_CODE_MESSAGE));
assertThat(output.contains(CREATE_TASK_MESSAGE))
.as("Test results do not show create task message: " + output).isTrue();
assertThat(output.contains(UPDATE_TASK_MESSAGE))
.as("Test results do not show success message: " + output).isTrue();
assertThat(output.contains(SUCCESS_EXIT_CODE_MESSAGE))
.as("Test results have incorrect exit code: " + output).isTrue();
}
/**
@@ -84,25 +91,27 @@ public class TaskCoreTests {
*/
@Test
public void successfulTaskTestWithAnnotation() {
this.applicationContext = SpringApplication.run( TaskConfigurationWithAnotation.class,
this.applicationContext = SpringApplication.run(
TaskConfigurationWithAnotation.class,
"--spring.cloud.task.closecontext.enable=false",
"--spring.cloud.task.name=" + TASK_NAME,
"--spring.main.web-environment=false");
String output = this.outputCapture.toString();
assertTrue("Test results do not show create task message: " + output,
output.contains(CREATE_TASK_MESSAGE));
assertTrue("Test results do not show success message: " + output,
output.contains(UPDATE_TASK_MESSAGE));
assertTrue("Test results have incorrect exit code: " + output,
output.contains(SUCCESS_EXIT_CODE_MESSAGE));
assertThat(output.contains(CREATE_TASK_MESSAGE))
.as("Test results do not show create task message: " + output).isTrue();
assertThat(output.contains(UPDATE_TASK_MESSAGE))
.as("Test results do not show success message: " + output).isTrue();
assertThat(output.contains(SUCCESS_EXIT_CODE_MESSAGE))
.as("Test results have incorrect exit code: " + output).isTrue();
}
@Test
public void exceptionTaskTest() {
boolean exceptionFired = false;
try {
this.applicationContext = SpringApplication.run( TaskExceptionConfiguration.class,
this.applicationContext = SpringApplication.run(
TaskExceptionConfiguration.class,
"--spring.cloud.task.closecontext.enable=false",
"--spring.cloud.task.name=" + TASK_NAME,
"--spring.main.web-environment=false");
@@ -110,19 +119,20 @@ public class TaskCoreTests {
catch (IllegalStateException exception) {
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();
assertTrue("Test results do not show create task message: " + output,
output.contains(CREATE_TASK_MESSAGE));
assertTrue("Test results do not show success message: " + output,
output.contains(UPDATE_TASK_MESSAGE));
assertTrue("Test results have incorrect exit code: " + output,
output.contains(EXCEPTION_EXIT_CODE_MESSAGE));
assertTrue("Test results have incorrect exit message: " + output,
output.contains(ERROR_MESSAGE));
assertTrue("Test results have exception message: " + output,
output.contains(EXCEPTION_MESSAGE));
assertThat(output.contains(CREATE_TASK_MESSAGE))
.as("Test results do not show create task message: " + output).isTrue();
assertThat(output.contains(UPDATE_TASK_MESSAGE))
.as("Test results do not show success message: " + output).isTrue();
assertThat(output.contains(EXCEPTION_EXIT_CODE_MESSAGE))
.as("Test results have incorrect exit code: " + output).isTrue();
assertThat(output.contains(ERROR_MESSAGE))
.as("Test results have incorrect exit message: " + output).isTrue();
assertThat(output.contains(EXCEPTION_MESSAGE))
.as("Test results have exception message: " + output).isTrue();
}
@Test
@@ -130,7 +140,8 @@ public class TaskCoreTests {
boolean exceptionFired = false;
try {
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.main.web-environment=false",
"--spring.cloud.task.executionid=55");
@@ -138,15 +149,18 @@ public class TaskCoreTests {
catch (ApplicationContextException exception) {
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();
assertTrue("Test results do not show the correct exception message: " + output,
output.contains(EXCEPTION_INVALID_TASK_EXECUTION_ID));
assertThat(output.contains(EXCEPTION_INVALID_TASK_EXECUTION_ID))
.as("Test results do not show the correct exception message: " + output)
.isTrue();
}
@EnableTask
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
@ImportAutoConfiguration({ SimpleTaskAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class })
public static class TaskConfiguration {
@Bean
@@ -157,10 +171,12 @@ public class TaskCoreTests {
}
};
}
}
@EnableTask
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
@ImportAutoConfiguration({ SimpleTaskAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class })
public static class TaskConfigurationWithAnotation {
@Bean
@@ -171,10 +187,12 @@ public class TaskCoreTests {
}
};
}
}
@EnableTask
@ImportAutoConfiguration({SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class})
@ImportAutoConfiguration({ SimpleTaskAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class })
public static class TaskExceptionConfiguration {
@Bean
@@ -186,5 +204,7 @@ public class TaskCoreTests {
}
};
}
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task;
@@ -36,15 +36,15 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
/**
* Verifies that TaskRepositoryInitializer creates tables if a {@link TaskConfigurer}
* has a {@link DataSource}.
* Verifies that TaskRepositoryInitializer creates tables if a {@link TaskConfigurer} has
* a {@link DataSource}.
*
* @author Glenn Renfro
* @since 2.0.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SimpleTaskAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class})
@ContextConfiguration(classes = { SimpleTaskAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class })
@DirtiesContext
public class TaskRepositoryInitializerDefaultTaskConfigurerTests {
@@ -53,8 +53,9 @@ public class TaskRepositoryInitializerDefaultTaskConfigurerTests {
@Test
public void testTablesCreated() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<Map<String, Object>> rows= jdbcTemplate.queryForList("SHOW TABLES");
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SHOW TABLES");
assertThat(rows.size()).isEqualTo(4);
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task;
@@ -37,16 +37,16 @@ import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
/**
* Verifies that TaskRepositoryInitializer does not create tables if a {@link TaskConfigurer}
* has no {@link DataSource}.
* Verifies that TaskRepositoryInitializer does not create tables if a
* {@link TaskConfigurer} has no {@link DataSource}.
*
* @author Glenn Renfro
* @since 2.0.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class,
EmbeddedDataSourceConfiguration.class,
DefaultTaskConfigurer.class})
@ContextConfiguration(classes = { SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class, EmbeddedDataSourceConfiguration.class,
DefaultTaskConfigurer.class })
public class TaskRepositoryInitializerNoDataSourceTaskConfigurerTests {
@Autowired
@@ -54,8 +54,9 @@ public class TaskRepositoryInitializerNoDataSourceTaskConfigurerTests {
@Test
public void testNoTablesCreated() {
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<Map<String, Object>> rows= jdbcTemplate.queryForList("SHOW TABLES");
JdbcTemplate jdbcTemplate = new JdbcTemplate(this.dataSource);
List<Map<String, Object>> rows = jdbcTemplate.queryForList("SHOW TABLES");
assertThat(rows.size()).isEqualTo(0);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.configuration;
@@ -31,11 +31,7 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.hamcrest.CoreMatchers.equalTo;
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.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
@@ -54,64 +50,80 @@ public class DefaultTaskConfigurerTests {
@Test
public void resourcelessTransactionManagerTest() {
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer();
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
is("org.springframework.batch.support.transaction.ResourcelessTransactionManager"));
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
.isEqualTo(
"org.springframework.batch.support.transaction.ResourcelessTransactionManager");
defaultTaskConfigurer = new DefaultTaskConfigurer("foo");
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
is("org.springframework.batch.support.transaction.ResourcelessTransactionManager"));
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
.isEqualTo(
"org.springframework.batch.support.transaction.ResourcelessTransactionManager");
}
@Test
public void testDefaultContext() throws Exception {
AnnotationConfigApplicationContext localContext = new AnnotationConfigApplicationContext();
localContext.register(EmbeddedDataSourceConfiguration.class,EntityManagerConfiguration.class);
localContext.register(EmbeddedDataSourceConfiguration.class,
EntityManagerConfiguration.class);
localContext.refresh();
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, localContext);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(), is(equalTo("org.springframework.orm.jpa.JpaTransactionManager")));
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
this.dataSource, TaskProperties.DEFAULT_TABLE_PREFIX, localContext);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
.isEqualTo("org.springframework.orm.jpa.JpaTransactionManager");
}
@Test
public void dataSourceTransactionManagerTest() {
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
is("org.springframework.jdbc.datasource.DataSourceTransactionManager"));
defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource, "FOO", null);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
is("org.springframework.jdbc.datasource.DataSourceTransactionManager"));
defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource, "FOO", context);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName(),
is("org.springframework.jdbc.datasource.DataSourceTransactionManager"));
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
this.dataSource);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
.isEqualTo(
"org.springframework.jdbc.datasource.DataSourceTransactionManager");
defaultTaskConfigurer = new DefaultTaskConfigurer(this.dataSource, "FOO", null);
assertThat(defaultTaskConfigurer.getTransactionManager().getClass().getName())
.isEqualTo(
"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
public void taskExplorerTest() {
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
assertThat(defaultTaskConfigurer.getTaskExplorer(), is(notNullValue()));
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
this.dataSource);
assertThat(defaultTaskConfigurer.getTaskExplorer()).isNotNull();
defaultTaskConfigurer = new DefaultTaskConfigurer();
assertThat(defaultTaskConfigurer.getTaskExplorer(), is(notNullValue()));
assertThat(defaultTaskConfigurer.getTaskExplorer()).isNotNull();
}
@Test
public void taskRepositoryTest() {
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
assertThat(defaultTaskConfigurer.getTaskRepository(), is(notNullValue()));
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
this.dataSource);
assertThat(defaultTaskConfigurer.getTaskRepository()).isNotNull();
defaultTaskConfigurer = new DefaultTaskConfigurer();
assertThat(defaultTaskConfigurer.getTaskRepository(), is(notNullValue()));
assertThat(defaultTaskConfigurer.getTaskRepository()).isNotNull();
}
@Test
public void taskDataSource() {
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(dataSource);
assertThat(defaultTaskConfigurer.getTaskDataSource(), is(notNullValue()));
DefaultTaskConfigurer defaultTaskConfigurer = new DefaultTaskConfigurer(
this.dataSource);
assertThat(defaultTaskConfigurer.getTaskDataSource()).isNotNull();
defaultTaskConfigurer = new DefaultTaskConfigurer();
assertThat(defaultTaskConfigurer.getTaskDataSource(), is(nullValue()));
assertThat(defaultTaskConfigurer.getTaskDataSource()).isNull();
}
@Configuration
public static class EntityManagerConfiguration {
@Bean
public EntityManager entityManager() {
return mock(EntityManager.class);
}
}
}

View File

@@ -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");
* 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.context.junit4.SpringRunner;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(Suite.class)
@SuiteClasses({
TaskPropertiesTests.CloseContextEnabledTest.class
@SuiteClasses({ TaskPropertiesTests.CloseContextEnabledTest.class
})
@DirtiesContext
public class TaskPropertiesTests {
@Autowired
TaskProperties taskProperties;
@Test
public void test() {
assertThat(taskProperties.getClosecontextEnabled(), is(false));
assertThat(this.taskProperties.getClosecontextEnabled()).isFalse();
}
@RunWith(SpringRunner.class)
@SpringBootTest(classes={TaskPropertiesTests.Config.class,
SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class},
properties = { "spring.cloud.task.closecontextEnabled=false" })
@SpringBootTest(classes = { TaskPropertiesTests.Config.class,
SimpleTaskAutoConfiguration.class,
SingleTaskConfiguration.class }, properties = {
"spring.cloud.task.closecontextEnabled=false" })
@DirtiesContext
public static class CloseContextEnabledTest extends TaskPropertiesTests {}
public static class CloseContextEnabledTest extends TaskPropertiesTests {
}
@Configuration
public static class Config {
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.configuration;
import javax.sql.DataSource;
@@ -63,27 +64,29 @@ public class TestConfiguration implements InitializingBean {
}
@Bean
public TaskRepository taskRepository(){
public TaskRepository taskRepository() {
return new SimpleTaskRepository(this.taskExecutionDaoFactoryBean);
}
@Bean
public PlatformTransactionManager transactionManager() {
if(dataSource == null) {
if (this.dataSource == null) {
return new ResourcelessTransactionManager();
}
else {
return new DataSourceTransactionManager(dataSource);
return new DataSourceTransactionManager(this.dataSource);
}
}
@Override
public void afterPropertiesSet() throws Exception {
if(this.dataSource != null) {
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(this.dataSource);
if (this.dataSource != null) {
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(
this.dataSource);
}
else {
this.taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
}
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.listener;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Glenn Renfro
@@ -31,24 +30,25 @@ public class TaskExceptionTests {
@Test
public void testTaskException() {
TaskException taskException = new TaskException(ERROR_MESSAGE);
assertEquals(ERROR_MESSAGE, taskException.getMessage());
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
taskException = new TaskException(ERROR_MESSAGE,
new IllegalStateException(ERROR_MESSAGE));
assertEquals(ERROR_MESSAGE, taskException.getMessage());
assertNotNull(taskException.getCause());
assertEquals(ERROR_MESSAGE, taskException.getCause().getMessage());
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
assertThat(taskException.getCause()).isNotNull();
assertThat(taskException.getCause().getMessage()).isEqualTo(ERROR_MESSAGE);
}
@Test
public void testTaskExecutionException() {
TaskExecutionException taskException = new TaskExecutionException(ERROR_MESSAGE);
assertEquals(ERROR_MESSAGE, taskException.getMessage());
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
taskException = new TaskExecutionException(ERROR_MESSAGE,
new IllegalStateException(ERROR_MESSAGE));
assertEquals(ERROR_MESSAGE, taskException.getMessage());
assertNotNull(taskException.getCause());
assertEquals(ERROR_MESSAGE, taskException.getCause().getMessage());
assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
assertThat(taskException.getCause()).isNotNull();
assertThat(taskException.getCause().getMessage()).isEqualTo(ERROR_MESSAGE);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,10 +37,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Verifies that the TaskExecutionListener invocations occur at the appropriate task
@@ -49,14 +46,17 @@ import static org.junit.Assert.assertTrue;
* @author Glenn Renfro
*/
public class TaskExecutionListenerTests {
private AnnotationConfigApplicationContext context;
private static final String EXCEPTION_MESSAGE = "This was expected";
private static boolean beforeTaskDidFireOnError = false;
private static boolean endTaskDidFireOnError = false;
private static boolean failedTaskDidFireOnError = false;
private AnnotationConfigApplicationContext context;
@BeforeTask
public void setup() {
beforeTaskDidFireOnError = false;
@@ -66,27 +66,29 @@ public class TaskExecutionListenerTests {
@After
public void tearDown() {
if(context != null && context.isActive()) {
context.close();
if (this.context != null && this.context.isActive()) {
this.context.close();
}
}
/**
* Verify that if a TaskExecutionListener Bean is present that the onTaskStartup method
* is called.
* Verify that if a TaskExecutionListener Bean is present that the onTaskStartup
* method is called.
*/
@Test
public void testTaskCreate() {
setupContextForTaskExecutionListener();
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
TaskExecution taskExecution = new TaskExecution(0, null, "wombat",
new Date(), new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(false, false, taskExecution,taskExecutionListener);
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener = this.context
.getBean(
DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
TaskExecution taskExecution = new TaskExecution(0, null, "wombat", new Date(),
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
public void testBeforeTaskErrorCreate() {
@@ -97,14 +99,18 @@ public class TaskExecutionListenerTests {
catch (Exception exception) {
exceptionFired = true;
}
assertTrue("Exception should have fired", exceptionFired);
assertTrue("BeforeTask Listener should have executed", beforeTaskDidFireOnError);
assertTrue("EndTask Listener should have executed", endTaskDidFireOnError);
assertTrue("FailedTask Listener should have executed", failedTaskDidFireOnError);
assertThat(exceptionFired).as("Exception should have fired").isTrue();
assertThat(beforeTaskDidFireOnError)
.as("BeforeTask Listener should have executed").isTrue();
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
public void testFailedTaskErrorCreate() {
@@ -115,42 +121,52 @@ public class TaskExecutionListenerTests {
catch (Exception exception) {
exceptionFired = true;
}
assertTrue("Exception should have fired", exceptionFired);
assertTrue("EndTask Listener should have executed", endTaskDidFireOnError);
assertTrue("FailedTask Listener should not have executed", failedTaskDidFireOnError);
assertThat(exceptionFired).as("Exception should have fired").isTrue();
assertThat(endTaskDidFireOnError).as("EndTask Listener should have executed")
.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
public void testAfterTaskErrorCreate() {
setupContextForAfterTaskErrorAnnotatedListener();
AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener taskExecutionListener =
context.getBean(AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener.class);
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener taskExecutionListener = this.context
.getBean(
AfterTaskErrorAnnotationConfiguration.AnnotatedTaskListener.class);
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
new String[0], this.context));
assertTrue(taskExecutionListener.isTaskStartup());
assertTrue(taskExecutionListener.isTaskEnd());
assertEquals(TestListener.END_MESSAGE, taskExecutionListener.getTaskExecution().getExitMessage());
assertTrue(taskExecutionListener.getTaskExecution().getErrorMessage().contains("Failed to process @BeforeTask or @AfterTask annotation because: AfterTaskFailure"));
assertNull(taskExecutionListener.getThrowable());
assertThat(taskExecutionListener.isTaskStartup()).isTrue();
assertThat(taskExecutionListener.isTaskEnd()).isTrue();
assertThat(taskExecutionListener.getTaskExecution().getExitMessage())
.isEqualTo(TestListener.END_MESSAGE);
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
* is called.
* Verify that if a TaskExecutionListener Bean is present that the onTaskEnd method is
* called.
*/
@Test
public void testTaskUpdate() {
setupContextForTaskExecutionListener();
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener = this.context
.getBean(
DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
new String[0], this.context));
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat",
new Date(), new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(true, false, taskExecution,taskExecutionListener);
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat", new Date(),
new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(true, false, taskExecution, taskExecutionListener);
}
/**
@@ -162,14 +178,17 @@ public class TaskExecutionListenerTests {
RuntimeException exception = new RuntimeException(EXCEPTION_MESSAGE);
setupContextForTaskExecutionListener();
SpringApplication application = new SpringApplication();
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener =
context.getBean(DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
DefaultTaskListenerConfiguration.TestTaskExecutionListener taskExecutionListener = this.context
.getBean(
DefaultTaskListenerConfiguration.TestTaskExecutionListener.class);
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(),
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
public void testAnnotationCreate() {
setupContextForAnnotatedListener();
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
TaskExecution taskExecution = new TaskExecution(0, null, "wombat",
new Date(), new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(false, false, taskExecution,annotatedListener);
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener = this.context
.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
TaskExecution taskExecution = new TaskExecution(0, null, "wombat", new Date(),
new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(false, false, taskExecution, annotatedListener);
}
/**
@@ -193,13 +212,14 @@ public class TaskExecutionListenerTests {
@Test
public void testAnnotationUpdate() {
setupContextForAnnotatedListener();
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
context.publishEvent(new ApplicationReadyEvent(new SpringApplication(), new String[0], context));
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener = this.context
.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
this.context.publishEvent(new ApplicationReadyEvent(new SpringApplication(),
new String[0], this.context));
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat",
new Date(), new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(true, false, taskExecution,annotatedListener);
TaskExecution taskExecution = new TaskExecution(0, 0, "wombat", new Date(),
new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(true, false, taskExecution, annotatedListener);
}
/**
@@ -211,73 +231,91 @@ public class TaskExecutionListenerTests {
RuntimeException exception = new RuntimeException(EXCEPTION_MESSAGE);
setupContextForAnnotatedListener();
SpringApplication application = new SpringApplication();
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener =
context.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
DefaultAnnotationConfiguration.AnnotatedTaskListener annotatedListener = this.context
.getBean(DefaultAnnotationConfiguration.AnnotatedTaskListener.class);
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(),
new Date(), null, new ArrayList<>(), null, null);
verifyListenerResults(true, true, taskExecution,annotatedListener);
verifyListenerResults(true, true, taskExecution, annotatedListener);
}
private void verifyListenerResults(boolean isTaskEnd,
boolean isTaskFailed, TaskExecution taskExecution,
TestListener actualListener){
assertTrue(actualListener.isTaskStartup());
assertEquals(isTaskEnd,actualListener.isTaskEnd());
assertEquals(isTaskFailed,actualListener.isTaskFailed());
if(isTaskFailed){
assertEquals(TestListener.END_MESSAGE, actualListener.getTaskExecution().getExitMessage());
assertNotNull(actualListener.getThrowable());
assertTrue(actualListener.getThrowable() instanceof RuntimeException);
assertTrue(actualListener.getTaskExecution().getErrorMessage().startsWith("java.lang.RuntimeException: This was expected"));
private void verifyListenerResults(boolean isTaskEnd, boolean isTaskFailed,
TaskExecution taskExecution, TestListener actualListener) {
assertThat(actualListener.isTaskStartup()).isTrue();
assertThat(actualListener.isTaskEnd()).isEqualTo(isTaskEnd);
assertThat(actualListener.isTaskFailed()).isEqualTo(isTaskFailed);
if (isTaskFailed) {
assertThat(actualListener.getTaskExecution().getExitMessage())
.isEqualTo(TestListener.END_MESSAGE);
assertThat(actualListener.getThrowable()).isNotNull();
assertThat(actualListener.getThrowable() instanceof RuntimeException)
.isTrue();
assertThat(actualListener.getTaskExecution().getErrorMessage()
.startsWith("java.lang.RuntimeException: This was expected"))
.isTrue();
}
else if(isTaskEnd){
assertEquals(TestListener.END_MESSAGE, actualListener.getTaskExecution().getExitMessage());
assertEquals(taskExecution.getErrorMessage(), actualListener.getTaskExecution().getErrorMessage());
assertNull(actualListener.getThrowable());
else if (isTaskEnd) {
assertThat(actualListener.getTaskExecution().getExitMessage())
.isEqualTo(TestListener.END_MESSAGE);
assertThat(actualListener.getTaskExecution().getErrorMessage())
.isEqualTo(taskExecution.getErrorMessage());
assertThat(actualListener.getThrowable()).isNull();
}
else {
assertEquals(TestListener.START_MESSAGE, actualListener.getTaskExecution().getExitMessage());
assertNull(actualListener.getTaskExecution().getErrorMessage());
assertNull(actualListener.getThrowable());
assertThat(actualListener.getTaskExecution().getExitMessage())
.isEqualTo(TestListener.START_MESSAGE);
assertThat(actualListener.getTaskExecution().getErrorMessage()).isNull();
assertThat(actualListener.getThrowable()).isNull();
}
assertEquals(taskExecution.getExecutionId(), actualListener.getTaskExecution().getExecutionId());
assertEquals(taskExecution.getExitCode(), actualListener.getTaskExecution().getExitCode());
assertEquals(taskExecution.getExternalExecutionId(), actualListener.getTaskExecution().getExternalExecutionId());
assertThat(actualListener.getTaskExecution().getExecutionId())
.isEqualTo(taskExecution.getExecutionId());
assertThat(actualListener.getTaskExecution().getExitCode())
.isEqualTo(taskExecution.getExitCode());
assertThat(actualListener.getTaskExecution().getExternalExecutionId())
.isEqualTo(taskExecution.getExternalExecutionId());
}
private void setupContextForTaskExecutionListener(){
context = new AnnotationConfigApplicationContext(DefaultTaskListenerConfiguration.class,
private void setupContextForTaskExecutionListener() {
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,
BeforeTaskErrorAnnotationConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
context.setId("testTask");
this.context.setId("beforeTaskAnnotatedTask");
}
private void setupContextForAnnotatedListener(){
context = new AnnotationConfigApplicationContext(TestDefaultConfiguration.class, DefaultAnnotationConfiguration.class,
private void setupContextForFailedTaskErrorAnnotatedListener() {
this.context = new AnnotationConfigApplicationContext(
TestDefaultConfiguration.class,
FailedTaskErrorAnnotationConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
context.setId("annotatedTask");
this.context.setId("failedTaskAnnotatedTask");
}
private void setupContextForBeforeTaskErrorAnnotatedListener(){
context = new AnnotationConfigApplicationContext(TestDefaultConfiguration.class, BeforeTaskErrorAnnotationConfiguration.class,
private void setupContextForAfterTaskErrorAnnotatedListener() {
this.context = new AnnotationConfigApplicationContext(
TestDefaultConfiguration.class,
AfterTaskErrorAnnotationConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
context.setId("beforeTaskAnnotatedTask");
}
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");
this.context.setId("afterTaskAnnotatedTask");
}
@Configuration
@@ -292,14 +330,14 @@ public class TaskExecutionListenerTests {
@BeforeTask
public void methodA(TaskExecution taskExecution) {
isTaskStartup = true;
this.isTaskStartup = true;
this.taskExecution = taskExecution;
this.taskExecution.setExitMessage(START_MESSAGE);
}
@AfterTask
public void methodB(TaskExecution taskExecution) {
isTaskEnd = true;
this.isTaskEnd = true;
this.taskExecution = taskExecution;
this.taskExecution.setExitMessage(END_MESSAGE);
@@ -307,12 +345,14 @@ public class TaskExecutionListenerTests {
@FailedTask
public void methodC(TaskExecution taskExecution, Throwable throwable) {
isTaskFailed = true;
this.isTaskFailed = true;
this.taskExecution = taskExecution;
this.throwable = throwable;
this.taskExecution.setExitMessage(ERROR_MESSAGE);
}
}
}
@Configuration
@@ -345,7 +385,9 @@ public class TaskExecutionListenerTests {
public void methodC(TaskExecution taskExecution, Throwable throwable) {
failedTaskDidFireOnError = true;
}
}
}
@Configuration
@@ -356,7 +398,6 @@ public class TaskExecutionListenerTests {
return new AnnotatedTaskListener();
}
public static class AnnotatedTaskListener {
@BeforeTask
@@ -375,7 +416,9 @@ public class TaskExecutionListenerTests {
failedTaskDidFireOnError = true;
throw new TaskExecutionException("FailedTaskFailure");
}
}
}
@Configuration
@@ -386,21 +429,23 @@ public class TaskExecutionListenerTests {
return new AnnotatedTaskListener();
}
public static class AnnotatedTaskListener extends TestListener{
public static class AnnotatedTaskListener extends TestListener {
@BeforeTask
public void methodA(TaskExecution taskExecution) {
isTaskStartup = true;
this.isTaskStartup = true;
}
@AfterTask
public void methodB(TaskExecution taskExecution) {
isTaskEnd = true;
this.isTaskEnd = true;
this.taskExecution = taskExecution;
this.taskExecution.setExitMessage(END_MESSAGE);
throw new TaskExecutionException("AfterTaskFailure");
}
}
}
@Configuration
@@ -411,31 +456,33 @@ public class TaskExecutionListenerTests {
return new TestTaskExecutionListener();
}
public static class TestTaskExecutionListener extends TestListener implements TaskExecutionListener {
public static class TestTaskExecutionListener extends TestListener
implements TaskExecutionListener {
@Override
public void onTaskStartup(TaskExecution taskExecution) {
isTaskStartup = true;
this.isTaskStartup = true;
this.taskExecution = taskExecution;
this.taskExecution.setExitMessage(START_MESSAGE);
}
@Override
public void onTaskEnd(TaskExecution taskExecution) {
isTaskEnd = true;
this.isTaskEnd = true;
this.taskExecution = taskExecution;
this.taskExecution.setExitMessage(END_MESSAGE);
}
@Override
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
isTaskFailed = true;
this.isTaskFailed = true;
this.taskExecution = taskExecution;
this.throwable = throwable;
this.taskExecution.setExitMessage(ERROR_MESSAGE);
}
}
}
}

View File

@@ -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");
* 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.Sort;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Verifies that the TaskLifecycleListener Methods record the appropriate log header entries and
* result codes.
* Verifies that the TaskLifecycleListener Methods record the appropriate log header
* entries and result codes.
*
* @author Glenn Renfro
* @author Michael Minella
*/
public class TaskLifecycleListenerTests {
@Rule
public OutputCapture outputCapture = new OutputCapture();
private AnnotationConfigApplicationContext context;
private TaskExplorer taskExplorer;
@Rule
public OutputCapture outputCapture = new OutputCapture();
@Before
public void setUp() {
context = new AnnotationConfigApplicationContext();
context.setId("testTask");
context.register(TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class);
this.context = new AnnotationConfigApplicationContext();
this.context.setId("testTask");
this.context.register(TestDefaultConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
TestListener.getStartupOrderList().clear();
TestListener.getFailOrderList().clear();
TestListener.getEndOrderList().clear();
@@ -85,44 +83,47 @@ public class TaskLifecycleListenerTests {
@After
public void tearDown() {
if(context != null && context.isActive()) {
context.close();
if (this.context != null && this.context.isActive()) {
this.context.close();
}
}
@Test
public void testTaskCreate() {
context.refresh();
this.taskExplorer = context.getBean(TaskExplorer.class);
this.context.refresh();
this.taskExplorer = this.context.getBean(TaskExplorer.class);
verifyTaskExecution(0, false);
}
@Test
public void testTaskCreateWithArgs() {
context.register(ArgsConfiguration.class);
context.refresh();
this.taskExplorer = context.getBean(TaskExplorer.class);
this.context.register(ArgsConfiguration.class);
this.context.refresh();
this.taskExplorer = this.context.getBean(TaskExplorer.class);
verifyTaskExecution(2, false);
}
@Test
public void testTaskUpdate() {
context.refresh();
this.taskExplorer = context.getBean(TaskExplorer.class);
this.context.refresh();
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);
}
@Test
public void testTaskFailedUpdate() {
context.refresh();
this.context.refresh();
RuntimeException exception = new RuntimeException("This was expected");
SpringApplication application = new SpringApplication();
this.taskExplorer = context.getBean(TaskExplorer.class);
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
this.taskExplorer = this.context.getBean(TaskExplorer.class);
this.context.publishEvent(new ApplicationFailedEvent(application, new String[0],
this.context, exception));
this.context.publishEvent(
new ApplicationReadyEvent(application, new String[0], this.context));
verifyTaskExecution(0, true, 1, exception, null);
}
@@ -130,38 +131,44 @@ public class TaskLifecycleListenerTests {
@Test
public void testTaskFailedWithExitCodeEvent() {
final int exitCode = 10;
context.register(TestListener.class);
context.register(TestListener2.class);
this.context.register(TestListener.class);
this.context.register(TestListener2.class);
context.refresh();
this.context.refresh();
RuntimeException exception = new RuntimeException("This was expected");
SpringApplication application = new SpringApplication();
this.taskExplorer = context.getBean(TaskExplorer.class);
context.publishEvent(new ExitCodeEvent(context, exitCode));
context.publishEvent(new ApplicationFailedEvent(application, new String[0], context, exception));
context.publishEvent(new ApplicationReadyEvent(application, new String[0], context));
this.taskExplorer = this.context.getBean(TaskExplorer.class);
this.context.publishEvent(new ExitCodeEvent(this.context, exitCode));
this.context.publishEvent(new ApplicationFailedEvent(application, new String[0],
this.context, exception));
this.context.publishEvent(
new ApplicationReadyEvent(application, new String[0], this.context));
verifyTaskExecution(0, true, exitCode, exception, null);
assertEquals(2, TestListener.getStartupOrderList().size());
assertEquals(Integer.valueOf(2), TestListener.getStartupOrderList().get(0));
assertEquals(Integer.valueOf(1), TestListener.getStartupOrderList().get(1));
assertThat(TestListener.getStartupOrderList().size()).isEqualTo(2);
assertThat(TestListener.getStartupOrderList().get(0))
.isEqualTo(Integer.valueOf(2));
assertThat(TestListener.getStartupOrderList().get(1))
.isEqualTo(Integer.valueOf(1));
assertEquals(2, TestListener.getEndOrderList().size());
assertEquals(Integer.valueOf(1), TestListener.getEndOrderList().get(0));
assertEquals(Integer.valueOf(2), TestListener.getEndOrderList().get(1));
assertThat(TestListener.getEndOrderList().size()).isEqualTo(2);
assertThat(TestListener.getEndOrderList().get(0)).isEqualTo(Integer.valueOf(1));
assertThat(TestListener.getEndOrderList().get(1)).isEqualTo(Integer.valueOf(2));
assertEquals(2, TestListener.getFailOrderList().size());
assertEquals(Integer.valueOf(1), TestListener.getFailOrderList().get(0));
assertEquals(Integer.valueOf(2), TestListener.getFailOrderList().get(1));
assertThat(TestListener.getFailOrderList().size()).isEqualTo(2);
assertThat(TestListener.getFailOrderList().get(0)).isEqualTo(Integer.valueOf(1));
assertThat(TestListener.getFailOrderList().get(1)).isEqualTo(Integer.valueOf(2));
}
@Test
public void testNoClosingOfContext() {
try (ConfigurableApplicationContext applicationContext = SpringApplication.run(new Class[] {TestDefaultConfiguration.class, PropertyPlaceholderAutoConfiguration.class},
new String[] {"--spring.cloud.task.closecontext_enabled=false"})) {
assertTrue(applicationContext.isActive());
try (ConfigurableApplicationContext applicationContext = SpringApplication.run(
new Class[] { TestDefaultConfiguration.class,
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();
Map<String, Object> myMap = new HashMap<>();
myMap.put("spring.cloud.task.executionid", "55");
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
context.setEnvironment(environment);
context.refresh();
propertySources
.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
this.context.setEnvironment(environment);
this.context.refresh();
}
@Test
public void testRestartExistingTask() {
context.refresh();
TaskLifecycleListener taskLifecycleListener =
context.getBean(TaskLifecycleListener.class);
this.context.refresh();
TaskLifecycleListener taskLifecycleListener = this.context
.getBean(TaskLifecycleListener.class);
taskLifecycleListener.start();
String output = this.outputCapture.toString();
assertTrue("Test results do not show error message: " + output,
output.contains("Multiple start events have been received"));
assertThat(output.contains("Multiple start events have been received"))
.as("Test results do not show error message: " + output).isTrue();
}
@Test
@@ -193,10 +201,11 @@ public class TaskLifecycleListenerTests {
MutablePropertySources propertySources = environment.getPropertySources();
Map<String, Object> myMap = new HashMap<>();
myMap.put("spring.cloud.task.external-execution-id", "myid");
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
context.setEnvironment(environment);
context.refresh();
this.taskExplorer = context.getBean(TaskExplorer.class);
propertySources
.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
this.context.setEnvironment(environment);
this.context.refresh();
this.taskExplorer = this.context.getBean(TaskExplorer.class);
verifyTaskExecution(0, false, null, null, "myid");
}
@@ -207,15 +216,17 @@ public class TaskLifecycleListenerTests {
MutablePropertySources propertySources = environment.getPropertySources();
Map<String, Object> myMap = new HashMap<>();
myMap.put("spring.cloud.task.parentExecutionId", 789);
propertySources.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
context.setEnvironment(environment);
context.refresh();
this.taskExplorer = context.getBean(TaskExplorer.class);
propertySources
.addFirst(new MapPropertySource("EnvrionmentTestPropsource", myMap));
this.context.setEnvironment(environment);
this.context.refresh();
this.taskExplorer = this.context.getBean(TaskExplorer.class);
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);
}
@@ -223,47 +234,48 @@ public class TaskLifecycleListenerTests {
verifyTaskExecution(numberOfParams, update, null, null, null);
}
private void verifyTaskExecution(int numberOfParams, boolean update,
Integer exitCode, Throwable exception, String externalExecutionId) {
private void verifyTaskExecution(int numberOfParams, boolean update, Integer exitCode,
Throwable exception, String externalExecutionId) {
verifyTaskExecution(numberOfParams, update, exitCode, exception,
externalExecutionId, null);
}
private void verifyTaskExecution(int numberOfParams, boolean update,
Integer exitCode, Throwable exception, String externalExecutionId,
Long parentExecutionId) {
private void verifyTaskExecution(int numberOfParams, boolean update, Integer exitCode,
Throwable exception, String externalExecutionId, Long parentExecutionId) {
Sort sort = Sort.by("id");
PageRequest request = PageRequest.of(0, Integer.MAX_VALUE, sort);
Page<TaskExecution> taskExecutionsByName = this.taskExplorer.findTaskExecutionsByName("testTask",
request);
assertTrue(taskExecutionsByName.iterator().hasNext());
Page<TaskExecution> taskExecutionsByName = this.taskExplorer
.findTaskExecutionsByName("testTask", request);
assertThat(taskExecutionsByName.iterator().hasNext()).isTrue();
TaskExecution taskExecution = taskExecutionsByName.iterator().next();
assertEquals(numberOfParams, taskExecution.getArguments().size());
assertEquals(exitCode, taskExecution.getExitCode());
assertEquals(externalExecutionId, taskExecution.getExternalExecutionId());
assertEquals(parentExecutionId, taskExecution.getParentExecutionId());
assertThat(taskExecution.getArguments().size()).isEqualTo(numberOfParams);
assertThat(taskExecution.getExitCode()).isEqualTo(exitCode);
assertThat(taskExecution.getExternalExecutionId()).isEqualTo(externalExecutionId);
assertThat(taskExecution.getParentExecutionId()).isEqualTo(parentExecutionId);
if(exception != null) {
assertTrue(taskExecution.getErrorMessage().length() > exception.getStackTrace().length);
if (exception != null) {
assertThat(taskExecution.getErrorMessage()
.length() > exception.getStackTrace().length).isTrue();
}
else {
assertNull(taskExecution.getExitMessage());
assertThat(taskExecution.getExitMessage()).isNull();
}
if(update) {
assertTrue(taskExecution.getEndTime().getTime() >= taskExecution.getStartTime().getTime());
assertNotNull(taskExecution.getExitCode());
if (update) {
assertThat(taskExecution.getEndTime().getTime() >= taskExecution
.getStartTime().getTime()).isTrue();
assertThat(taskExecution.getExitCode()).isNotNull();
}
else {
assertNull(taskExecution.getEndTime());
assertTrue(taskExecution.getExitCode() == null);
assertThat(taskExecution.getEndTime()).isNull();
assertThat(taskExecution.getExitCode() == null).isTrue();
}
assertEquals("testTask", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("testTask");
}
@Configuration
@@ -278,23 +290,25 @@ public class TaskLifecycleListenerTests {
return new SimpleApplicationArgs(args);
}
}
private static class SimpleApplicationArgs implements ApplicationArguments {
private Map<String, String> args;
public SimpleApplicationArgs(Map<String, String> args) {
SimpleApplicationArgs(Map<String, String> args) {
this.args = args;
}
@Override
public String[] getSourceArgs() {
String [] sourceArgs = new String[this.args.size()];
String[] sourceArgs = new String[this.args.size()];
int i = 0;
for (Map.Entry<String, String> stringStringEntry : args.entrySet()) {
sourceArgs[i] = "--" + stringStringEntry.getKey() + "=" + stringStringEntry.getValue();
for (Map.Entry<String, String> stringStringEntry : this.args.entrySet()) {
sourceArgs[i] = "--" + stringStringEntry.getKey() + "="
+ stringStringEntry.getValue();
i++;
}
@@ -320,6 +334,7 @@ public class TaskLifecycleListenerTests {
public List<String> getNonOptionArgs() {
throw new UnsupportedOperationException("Not supported at this time.");
}
}
private static class TestListener2 extends TestListener {
@@ -328,34 +343,17 @@ public class TaskLifecycleListenerTests {
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 int id = 0;
static List<Integer> startupOrderList = new ArrayList<>();
static List<Integer> endOrderList = new ArrayList<>();
static List<Integer> failOrderList = new ArrayList<>();
public TestListener() {
TestListener() {
currentCount++;
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);
this.id = currentCount;
}
public static List<Integer> getStartupOrderList() {
@@ -369,5 +367,22 @@ public class TaskLifecycleListenerTests {
public static List<Integer> getFailOrderList() {
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);
}
}
}

View File

@@ -1,17 +1,17 @@
/*
* Copyright 2018 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.listener;
@@ -46,7 +46,8 @@ import static org.assertj.core.api.Assertions.assertThat;
* @since 2.1.0
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { TaskListenerExecutorObjectFactoryTests.TaskExecutionListenerConfiguration.class })
@ContextConfiguration(classes = {
TaskListenerExecutorObjectFactoryTests.TaskExecutionListenerConfiguration.class })
@DirtiesContext
public class TaskListenerExecutorObjectFactoryTests {
@@ -68,13 +69,15 @@ public class TaskListenerExecutorObjectFactoryTests {
@Before
public void setup() {
taskExecutionListenerResults.clear();
this.taskListenerExecutorObjectFactory = new TaskListenerExecutorObjectFactory(this.context);
this.taskListenerExecutorObjectFactory = new TaskListenerExecutorObjectFactory(
this.context);
this.taskListenerExecutor = this.taskListenerExecutorObjectFactory.getObject();
}
@Test
public void verifyTaskStartupListener() {
this.taskListenerExecutor.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
this.taskListenerExecutor
.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
validateSingleEntry(BEFORE_LISTENER);
}
@@ -93,14 +96,18 @@ public class TaskListenerExecutorObjectFactoryTests {
@Test
public void verifyAllListener() {
this.taskListenerExecutor.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
this.taskListenerExecutor
.onTaskStartup(createSampleTaskExecution(BEFORE_LISTENER));
this.taskListenerExecutor.onTaskFailed(createSampleTaskExecution(FAIL_LISTENER),
new IllegalStateException("oops"));
this.taskListenerExecutor.onTaskEnd(createSampleTaskExecution(AFTER_LISTENER));
assertThat(taskExecutionListenerResults.size()).isEqualTo(3);
assertThat(taskExecutionListenerResults.get(0).getTaskName()).isEqualTo(BEFORE_LISTENER);
assertThat(taskExecutionListenerResults.get(1).getTaskName()).isEqualTo(FAIL_LISTENER);
assertThat(taskExecutionListenerResults.get(2).getTaskName()).isEqualTo(AFTER_LISTENER);
assertThat(taskExecutionListenerResults.get(0).getTaskName())
.isEqualTo(BEFORE_LISTENER);
assertThat(taskExecutionListenerResults.get(1).getTaskName())
.isEqualTo(FAIL_LISTENER);
assertThat(taskExecutionListenerResults.get(2).getTaskName())
.isEqualTo(AFTER_LISTENER);
}
private TaskExecution createSampleTaskExecution(String taskName) {
@@ -121,23 +128,29 @@ public class TaskListenerExecutorObjectFactoryTests {
public TaskRunComponent taskRunComponent() {
return new TaskRunComponent();
}
}
public static class TaskRunComponent {
@BeforeTask
public void initBeforeListener(TaskExecution taskExecution) {
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults
.add(taskExecution);
}
@AfterTask
public void initAfterListener(TaskExecution taskExecution) {
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults
.add(taskExecution);
}
@FailedTask
public void initFailedListener(TaskExecution taskExecution, Throwable exception) {
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults.add(taskExecution);
TaskListenerExecutorObjectFactoryTests.taskExecutionListenerResults
.add(taskExecution);
}
}
}

View File

@@ -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");
* 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.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;
import org.junit.Test;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.test.annotation.DirtiesContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.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
*/
@@ -43,12 +41,13 @@ public class BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void getLatestTaskExecutionsByTaskNamesWithNullParameter() {
public void getLatestTaskExecutionsByTaskNamesWithNullParameter() {
try {
dao.getLatestTaskExecutionsByTaskNames(null);
this.dao.getLatestTaskExecutionsByTaskNames(null);
}
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;
}
fail("Expected an IllegalArgumentException to be thrown.");
@@ -56,12 +55,13 @@ public class BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void getLatestTaskExecutionsByTaskNamesWithEmptyArrayParameter() {
public void getLatestTaskExecutionsByTaskNamesWithEmptyArrayParameter() {
try {
dao.getLatestTaskExecutionsByTaskNames(new String[0]);
this.dao.getLatestTaskExecutionsByTaskNames(new String[0]);
}
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;
}
fail("Expected an IllegalArgumentException to be thrown.");
@@ -69,12 +69,13 @@ public class BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void getLatestTaskExecutionsByTaskNamesWithArrayParametersContainingNullAndEmptyValues() {
public void getLatestTaskExecutionsByTaskNamesWithArrayParametersContainingNullAndEmptyValues() {
try {
dao.getLatestTaskExecutionsByTaskNames("foo", null, "bar", " ");
this.dao.getLatestTaskExecutionsByTaskNames("foo", null, "bar", " ");
}
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;
}
fail("Expected an IllegalArgumentException to be thrown.");
@@ -82,95 +83,105 @@ public class BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void getLatestTaskExecutionsByTaskNamesWithSingleTaskName() {
public void getLatestTaskExecutionsByTaskNamesWithSingleTaskName() {
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
final List<TaskExecution> latestTaskExecutions = dao.getLatestTaskExecutionsByTaskNames("FOO1");
assertTrue("Expected only 1 taskExecution but got " + latestTaskExecutions.size(), latestTaskExecutions.size() == 1);
final List<TaskExecution> latestTaskExecutions = this.dao
.getLatestTaskExecutionsByTaskNames("FOO1");
assertThat(latestTaskExecutions.size() == 1).as(
"Expected only 1 taskExecution but got " + latestTaskExecutions.size())
.isTrue();
final TaskExecution lastTaskExecution = latestTaskExecutions.get(0);
assertEquals("FOO1", lastTaskExecution.getTaskName());
assertThat(lastTaskExecution.getTaskName()).isEqualTo("FOO1");
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
dateTime.setTime(lastTaskExecution.getStartTime());
assertEquals(2015, dateTime.get(Calendar.YEAR));
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
assertEquals(59, dateTime.get(Calendar.MINUTE));
assertEquals(0, dateTime.get(Calendar.SECOND));
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
}
@Test
@DirtiesContext
public void getLatestTaskExecutionsByTaskNamesWithMultipleTaskNames() {
public void getLatestTaskExecutionsByTaskNamesWithMultipleTaskNames() {
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
final List<TaskExecution> latestTaskExecutions = dao.getLatestTaskExecutionsByTaskNames("FOO1", "FOO3", "FOO4");
assertTrue("Expected 3 taskExecutions but got " + latestTaskExecutions.size(), latestTaskExecutions.size() == 3);
final List<TaskExecution> latestTaskExecutions = this.dao
.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"));
dateTimeFoo3.setTime(latestTaskExecutions.get(0).getStartTime());
assertEquals(2016, dateTimeFoo3.get(Calendar.YEAR));
assertEquals(8, dateTimeFoo3.get(Calendar.MONTH) + 1);
assertEquals(20, dateTimeFoo3.get(Calendar.DAY_OF_MONTH));
assertEquals(14, dateTimeFoo3.get(Calendar.HOUR_OF_DAY));
assertEquals(45, dateTimeFoo3.get(Calendar.MINUTE));
assertEquals(0, dateTimeFoo3.get(Calendar.SECOND));
assertThat(dateTimeFoo3.get(Calendar.YEAR)).isEqualTo(2016);
assertThat(dateTimeFoo3.get(Calendar.MONTH) + 1).isEqualTo(8);
assertThat(dateTimeFoo3.get(Calendar.DAY_OF_MONTH)).isEqualTo(20);
assertThat(dateTimeFoo3.get(Calendar.HOUR_OF_DAY)).isEqualTo(14);
assertThat(dateTimeFoo3.get(Calendar.MINUTE)).isEqualTo(45);
assertThat(dateTimeFoo3.get(Calendar.SECOND)).isEqualTo(0);
final Calendar dateTimeFoo1 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
dateTimeFoo1.setTime(latestTaskExecutions.get(1).getStartTime());
assertEquals(2015, dateTimeFoo1.get(Calendar.YEAR));
assertEquals(2, dateTimeFoo1.get(Calendar.MONTH) + 1);
assertEquals(22, dateTimeFoo1.get(Calendar.DAY_OF_MONTH));
assertEquals(23, dateTimeFoo1.get(Calendar.HOUR_OF_DAY));
assertEquals(59, dateTimeFoo1.get(Calendar.MINUTE));
assertEquals(0, dateTimeFoo1.get(Calendar.SECOND));
assertThat(dateTimeFoo1.get(Calendar.YEAR)).isEqualTo(2015);
assertThat(dateTimeFoo1.get(Calendar.MONTH) + 1).isEqualTo(2);
assertThat(dateTimeFoo1.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
assertThat(dateTimeFoo1.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
assertThat(dateTimeFoo1.get(Calendar.MINUTE)).isEqualTo(59);
assertThat(dateTimeFoo1.get(Calendar.SECOND)).isEqualTo(0);
final Calendar dateTimeFoo4 = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
dateTimeFoo4.setTime(latestTaskExecutions.get(2).getStartTime());
assertEquals(2015, dateTimeFoo4.get(Calendar.YEAR));
assertEquals(2, dateTimeFoo4.get(Calendar.MONTH) + 1);
assertEquals(20, dateTimeFoo4.get(Calendar.DAY_OF_MONTH));
assertEquals(14, dateTimeFoo4.get(Calendar.HOUR_OF_DAY));
assertEquals(45, dateTimeFoo4.get(Calendar.MINUTE));
assertEquals(0, dateTimeFoo4.get(Calendar.SECOND));
assertThat(dateTimeFoo4.get(Calendar.YEAR)).isEqualTo(2015);
assertThat(dateTimeFoo4.get(Calendar.MONTH) + 1).isEqualTo(2);
assertThat(dateTimeFoo4.get(Calendar.DAY_OF_MONTH)).isEqualTo(20);
assertThat(dateTimeFoo4.get(Calendar.HOUR_OF_DAY)).isEqualTo(14);
assertThat(dateTimeFoo4.get(Calendar.MINUTE)).isEqualTo(45);
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
* executed with the exact same start time multiple times. In that case we should still only get 1 returned
* {@link TaskExecution}.
* This test is a special use-case. While not common, it is theoretically possible,
* that a task may have executed with the exact same start time multiple times. In
* that case we should still only get 1 returned {@link TaskExecution}.
*/
@Test
@DirtiesContext
public void getLatestTaskExecutionsByTaskNamesWithIdenticalTaskExecutions() {
public void getLatestTaskExecutionsByTaskNamesWithIdenticalTaskExecutions() {
long executionIdOffset = initializeRepositoryNotInOrderWithMultipleTaskExecutions();
final List<TaskExecution> latestTaskExecutions = dao.getLatestTaskExecutionsByTaskNames("FOO5");
assertTrue("Expected only 1 taskExecution but got " + latestTaskExecutions.size(), latestTaskExecutions.size() == 1);
final List<TaskExecution> latestTaskExecutions = this.dao
.getLatestTaskExecutionsByTaskNames("FOO5");
assertThat(latestTaskExecutions.size() == 1).as(
"Expected only 1 taskExecution but got " + latestTaskExecutions.size())
.isTrue();
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
dateTime.setTime(latestTaskExecutions.get(0).getStartTime());
assertEquals(2015, dateTime.get(Calendar.YEAR));
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
assertEquals(59, dateTime.get(Calendar.MINUTE));
assertEquals(0, dateTime.get(Calendar.SECOND));
assertEquals(9 + executionIdOffset, latestTaskExecutions.get(0).getExecutionId());
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
assertThat(latestTaskExecutions.get(0).getExecutionId())
.isEqualTo(9 + executionIdOffset);
}
@Test
@DirtiesContext
public void getLatestTaskExecutionForTaskNameWithNullParameter() {
public void getLatestTaskExecutionForTaskNameWithNullParameter() {
try {
dao.getLatestTaskExecutionForTaskName(null);
this.dao.getLatestTaskExecutionForTaskName(null);
}
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;
}
fail("Expected an IllegalArgumentException to be thrown.");
@@ -178,12 +189,12 @@ public class BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void getLatestTaskExecutionForTaskNameWithEmptyStringParameter() {
public void getLatestTaskExecutionForTaskNameWithEmptyStringParameter() {
try {
dao.getLatestTaskExecutionForTaskName("");
this.dao.getLatestTaskExecutionForTaskName("");
}
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;
}
fail("Expected an IllegalArgumentException to be thrown.");
@@ -191,61 +202,71 @@ public class BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void getLatestTaskExecutionForNonExistingTaskName() {
public void getLatestTaskExecutionForNonExistingTaskName() {
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
final TaskExecution latestTaskExecution = dao.getLatestTaskExecutionForTaskName("Bar5");
assertNull("Expected the latestTaskExecution to be null but got" + latestTaskExecution, latestTaskExecution);
final TaskExecution latestTaskExecution = this.dao
.getLatestTaskExecutionForTaskName("Bar5");
assertThat(latestTaskExecution)
.as("Expected the latestTaskExecution to be null but got"
+ latestTaskExecution)
.isNull();
}
@Test
@DirtiesContext
public void getLatestTaskExecutionForExistingTaskName() {
public void getLatestTaskExecutionForExistingTaskName() {
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
final TaskExecution latestTaskExecution = dao.getLatestTaskExecutionForTaskName("FOO1");
assertNotNull("Expected the latestTaskExecution not to be null", latestTaskExecution);
final TaskExecution latestTaskExecution = this.dao
.getLatestTaskExecutionForTaskName("FOO1");
assertThat(latestTaskExecution)
.as("Expected the latestTaskExecution not to be null").isNotNull();
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
dateTime.setTime(latestTaskExecution.getStartTime());
assertEquals(2015, dateTime.get(Calendar.YEAR));
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
assertEquals(59, dateTime.get(Calendar.MINUTE));
assertEquals(0, dateTime.get(Calendar.SECOND));
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
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
* executed with the exact same start time multiple times. In that case we should still only get 1 returned
* {@link TaskExecution}.
* This test is a special use-case. While not common, it is theoretically possible,
* that a task may have executed with the exact same start time multiple times. In
* that case we should still only get 1 returned {@link TaskExecution}.
*/
@Test
@DirtiesContext
public void getLatestTaskExecutionForTaskNameWithIdenticalTaskExecutions() {
public void getLatestTaskExecutionForTaskNameWithIdenticalTaskExecutions() {
long executionIdOffset = initializeRepositoryNotInOrderWithMultipleTaskExecutions();
final TaskExecution latestTaskExecution = dao.getLatestTaskExecutionForTaskName("FOO5");
assertNotNull("Expected the latestTaskExecution not to be null", latestTaskExecution);
final TaskExecution latestTaskExecution = this.dao
.getLatestTaskExecutionForTaskName("FOO5");
assertThat(latestTaskExecution)
.as("Expected the latestTaskExecution not to be null").isNotNull();
final Calendar dateTime = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
dateTime.setTime(latestTaskExecution.getStartTime());
assertEquals(2015, dateTime.get(Calendar.YEAR));
assertEquals(2, dateTime.get(Calendar.MONTH) + 1);
assertEquals(22, dateTime.get(Calendar.DAY_OF_MONTH));
assertEquals(23, dateTime.get(Calendar.HOUR_OF_DAY));
assertEquals(59, dateTime.get(Calendar.MINUTE));
assertEquals(0, dateTime.get(Calendar.SECOND));
assertEquals(9 + executionIdOffset, latestTaskExecution.getExecutionId());
assertThat(dateTime.get(Calendar.YEAR)).isEqualTo(2015);
assertThat(dateTime.get(Calendar.MONTH) + 1).isEqualTo(2);
assertThat(dateTime.get(Calendar.DAY_OF_MONTH)).isEqualTo(22);
assertThat(dateTime.get(Calendar.HOUR_OF_DAY)).isEqualTo(23);
assertThat(dateTime.get(Calendar.MINUTE)).isEqualTo(59);
assertThat(dateTime.get(Calendar.SECOND)).isEqualTo(0);
assertThat(latestTaskExecution.getExecutionId()).isEqualTo(9 + executionIdOffset);
}
@Test
@DirtiesContext
public void getRunningTaskExecutions() {
initializeRepositoryNotInOrderWithMultipleTaskExecutions();
assertEquals(dao.getTaskExecutionCount(), dao.getRunningTaskExecutionCount());
dao.completeTaskExecution(1, 0, new Date(), "c'est fini!" );
assertEquals(dao.getTaskExecutionCount() - 1, dao.getRunningTaskExecutionCount());
assertThat(this.dao.getRunningTaskExecutionCount())
.isEqualTo(this.dao.getTaskExecutionCount());
this.dao.completeTaskExecution(1, 0, new Date(), "c'est fini!");
assertThat(this.dao.getRunningTaskExecutionCount())
.isEqualTo(this.dao.getTaskExecutionCount() - 1);
}
protected long initializeRepositoryNotInOrderWithMultipleTaskExecutions() {
@@ -304,7 +325,8 @@ public class BaseTaskExecutionDaoTestCases {
}
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,
@@ -315,4 +337,5 @@ public class BaseTaskExecutionDaoTestCases {
taskExecution.setStartTime(new Date());
return taskExecution;
}
}

View File

@@ -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");
* 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.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Executes unit tests on JdbcTaskExecutionDao.
@@ -53,83 +53,95 @@ import static org.junit.Assert.assertEquals;
* @author Gunnar Hillert
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {TestConfiguration.class,
@ContextConfiguration(classes = { TestConfiguration.class,
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class})
PropertyPlaceholderAutoConfiguration.class })
public class JdbcTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases {
@Autowired
private DataSource dataSource;
@Autowired
TaskRepository repository;
@Autowired
private DataSource dataSource;
@Before
public void setup(){
final JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(dataSource);
dao.setTaskIncrementer(TestDBUtils.getIncrementer(dataSource));
public void setup() {
final JdbcTaskExecutionDao dao = new JdbcTaskExecutionDao(this.dataSource);
dao.setTaskIncrementer(TestDBUtils.getIncrementer(this.dataSource));
super.dao = dao;
}
@Test
@DirtiesContext
public void testStartTaskExecution() {
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
new ArrayList<String>(0), null);
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, 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.setTaskName(UUID.randomUUID().toString());
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void createTaskExecution() {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), expectedTaskExecution.getExternalExecutionId());
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
expectedTaskExecution = this.dao.createTaskExecution(
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void createEmptyTaskExecution() {
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
new ArrayList<String>(0), null);
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, null,
new ArrayList<>(0), null);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void completeTaskExecution() {
TaskExecution expectedTaskExecution = TestVerifierUtils.endSampleTaskExecutionNoArg();
expectedTaskExecution = dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
TaskExecution expectedTaskExecution = TestVerifierUtils
.endSampleTaskExecutionNoArg();
expectedTaskExecution = this.dao.createTaskExecution(
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test(expected = IllegalStateException.class)
@DirtiesContext
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(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
@@ -137,89 +149,90 @@ public class JdbcTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases {
@Test
@DirtiesContext
public void testFindAllPageableSort() {
public void testFindAllPageableSort() {
initializeRepositoryNotInOrder();
Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC,
"EXTERNAL_EXECUTION_ID"));
Sort sort = Sort.by(new Sort.Order(Sort.Direction.ASC, "EXTERNAL_EXECUTION_ID"));
Iterator<TaskExecution> iter = getPageIterator(0, 2, sort);
TaskExecution taskExecution = iter.next();
assertEquals("FOO2", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("FOO2");
taskExecution = iter.next();
assertEquals("FOO3", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("FOO3");
iter = getPageIterator(1, 2, sort);
taskExecution = iter.next();
assertEquals("FOO1", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("FOO1");
}
@Test
@DirtiesContext
public void testFindAllDefaultSort() {
public void testFindAllDefaultSort() {
initializeRepository();
Iterator<TaskExecution> iter = getPageIterator(0, 2, null);
TaskExecution taskExecution = iter.next();
assertEquals("FOO1", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("FOO1");
taskExecution = iter.next();
assertEquals("FOO2", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("FOO2");
iter = getPageIterator(1, 2, null);
taskExecution = iter.next();
assertEquals("FOO3", taskExecution.getTaskName());
assertThat(taskExecution.getTaskName()).isEqualTo("FOO3");
}
@Test
@DirtiesContext
public void testStartExecutionWithNullExternalExecutionIdExisting() {
TaskExecution expectedTaskExecution =
initializeTaskExecutionWithExternalExecutionId();
TaskExecution expectedTaskExecution = initializeTaskExecutionWithExternalExecutionId();
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
null);
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), null);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test
@DirtiesContext
public void testStartExecutionWithNullExternalExecutionIdNonExisting() {
TaskExecution expectedTaskExecution =
initializeTaskExecutionWithExternalExecutionId();
TaskExecution expectedTaskExecution = initializeTaskExecutionWithExternalExecutionId();
dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
"BAR");
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), "BAR");
expectedTaskExecution.setExternalExecutionId("BAR");
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource, expectedTaskExecution.getExecutionId()));
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
private TaskExecution initializeTaskExecutionWithExternalExecutionId() {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
return this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
"FOO1");
expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), "FOO1");
}
private Iterator<TaskExecution> getPageIterator(int pageNum, int pageSize, Sort sort) {
Pageable pageable = (sort == null) ?
PageRequest.of(pageNum, pageSize) :
PageRequest.of(pageNum, pageSize, sort);
Page<TaskExecution> page = dao.findAll(pageable);
assertEquals(3, page.getTotalElements());
assertEquals(2, page.getTotalPages());
private Iterator<TaskExecution> getPageIterator(int pageNum, int pageSize,
Sort sort) {
Pageable pageable = (sort == null) ? PageRequest.of(pageNum, pageSize)
: PageRequest.of(pageNum, pageSize, sort);
Page<TaskExecution> page = this.dao.findAll(pageable);
assertThat(page.getTotalElements()).isEqualTo(3);
assertThat(page.getTotalPages()).isEqualTo(2);
return page.iterator();
}
private void initializeRepository() {
repository.createTaskExecution(getTaskExecution("FOO3", "externalA"));
repository.createTaskExecution(getTaskExecution("FOO2", "externalB"));
repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
this.repository.createTaskExecution(getTaskExecution("FOO3", "externalA"));
this.repository.createTaskExecution(getTaskExecution("FOO2", "externalB"));
this.repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
}
private void initializeRepositoryNotInOrder() {
repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
repository.createTaskExecution(getTaskExecution("FOO2", "externalA"));
repository.createTaskExecution(getTaskExecution("FOO3", "externalB"));
this.repository.createTaskExecution(getTaskExecution("FOO1", "externalC"));
this.repository.createTaskExecution(getTaskExecution("FOO2", "externalA"));
this.repository.createTaskExecution(getTaskExecution("FOO3", "externalB"));
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -27,12 +27,11 @@ import java.util.UUID;
import org.junit.Before;
import org.junit.Test;
import org.springframework.cloud.task.repository.TaskExecution;
import org.springframework.cloud.task.util.TestVerifierUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Executes unit tests on MapTaskExecutionDaoTests.
@@ -40,7 +39,7 @@ import static org.junit.Assert.assertNull;
* @author Glenn Renfro
* @author Gunnar Hillert
*/
public class MapTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases{
public class MapTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases {
private MapTaskExecutionDao mapTaskExecutionDao;
@@ -52,122 +51,138 @@ public class MapTaskExecutionDaoTests extends BaseTaskExecutionDaoTestCases{
@Test
public void testStartTaskExecution() {
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, null, new ArrayList<String>(0), null);
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, 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.setTaskName(UUID.randomUUID().toString());
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao.getTaskExecutions();
assertNotNull("taskExecutionMap must not be null", taskExecutionMap);
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao
.getTaskExecutions();
assertThat(taskExecutionMap).as("taskExecutionMap must not be null").isNotNull();
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test
public void createEmptyTaskExecution() {
TaskExecution expectedTaskExecution = dao.createTaskExecution(null, null,
new ArrayList<String>(0), null);
TaskExecution expectedTaskExecution = this.dao.createTaskExecution(null, null,
new ArrayList<>(0), null);
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao.getTaskExecutions();
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao
.getTaskExecutions();
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test(expected = IllegalStateException.class)
public void completeTaskExecutionWithNoCreate() {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
}
@Test
public void saveTaskExecution(){
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution = this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
public void saveTaskExecution() {
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
expectedTaskExecution = this.dao.createTaskExecution(
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao.getTaskExecutions();
assertNotNull("taskExecutionMap must not be null", taskExecutionMap);
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao
.getTaskExecutions();
assertThat(taskExecutionMap).as("taskExecutionMap must not be null").isNotNull();
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test
public void completeTaskExecution(){
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution = this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
public void completeTaskExecution() {
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
expectedTaskExecution = this.dao.createTaskExecution(
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao.getTaskExecutions();
assertNotNull("taskExecutionMap must not be null", taskExecutionMap);
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao
.getTaskExecutions();
assertThat(taskExecutionMap).as("taskExecutionMap must not be null").isNotNull();
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test
public void testJobQueries(){
public void testJobQueries() {
List<TaskExecution> expectedTaskExecutionList = new ArrayList<>(2);
expectedTaskExecutionList.add(TestVerifierUtils.createSampleTaskExecutionNoArg());
expectedTaskExecutionList.add(TestVerifierUtils.createSampleTaskExecutionNoArg());
for (TaskExecution expectedTaskExecution : expectedTaskExecutionList) {
expectedTaskExecution = this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
expectedTaskExecution = this.dao.createTaskExecution(
expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
this.dao.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitCode(),
expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage());
}
Set<Long> jobIds = new HashSet<>(2);
jobIds.add(123L);
jobIds.add(456L);
this.mapTaskExecutionDao.getBatchJobAssociations().put(
expectedTaskExecutionList.get(0).getExecutionId(), jobIds);
this.mapTaskExecutionDao.getBatchJobAssociations()
.put(expectedTaskExecutionList.get(0).getExecutionId(), jobIds);
assertEquals(Long.valueOf(expectedTaskExecutionList.get(0).getExecutionId()),
this.dao.getTaskExecutionIdByJobExecutionId(123L));
assertEquals(Long.valueOf(expectedTaskExecutionList.get(0).getExecutionId()),
this.dao.getTaskExecutionIdByJobExecutionId(456L));
assertNull(this.dao.getTaskExecutionIdByJobExecutionId(789L));
assertThat(this.dao.getTaskExecutionIdByJobExecutionId(123L)).isEqualTo(
Long.valueOf(expectedTaskExecutionList.get(0).getExecutionId()));
assertThat(this.dao.getTaskExecutionIdByJobExecutionId(456L)).isEqualTo(
Long.valueOf(expectedTaskExecutionList.get(0).getExecutionId()));
assertThat(this.dao.getTaskExecutionIdByJobExecutionId(789L)).isNull();
}
@Test
public void testStartExecutionWithNullExternalExecutionIdExisting(){
TaskExecution expectedTaskExecution =
initializeTaskExecutionWithExternalExecutionId();
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao.getTaskExecutions();
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
null);
public void testStartExecutionWithNullExternalExecutionIdExisting() {
TaskExecution expectedTaskExecution = initializeTaskExecutionWithExternalExecutionId();
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao
.getTaskExecutions();
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), null);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
@Test
public void testStartExecutionWithNullExternalExecutionIdNonExisting(){
TaskExecution expectedTaskExecution =
initializeTaskExecutionWithExternalExecutionId();
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao.getTaskExecutions();
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(), expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
"BAR");
public void testStartExecutionWithNullExternalExecutionIdNonExisting() {
TaskExecution expectedTaskExecution = initializeTaskExecutionWithExternalExecutionId();
Map<Long, TaskExecution> taskExecutionMap = this.mapTaskExecutionDao
.getTaskExecutions();
this.dao.startTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), "BAR");
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
taskExecutionMap.get(expectedTaskExecution.getExecutionId()));
}
private TaskExecution initializeTaskExecutionWithExternalExecutionId() {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
return this.dao.createTaskExecution(expectedTaskExecution.getTaskName(),
expectedTaskExecution.getStartTime(), expectedTaskExecution.getArguments(),
"FOO1");
expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), "FOO1");
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -27,7 +27,7 @@ import org.springframework.cloud.task.util.TestDBUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import static org.junit.Assert.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Glenn Renfro
@@ -36,13 +36,22 @@ import static org.junit.Assert.assertEquals;
public class FindAllPagingQueryProviderTests {
private String databaseProductName;
private String expectedQuery;
private Pageable pageable = PageRequest.of(0, 10);
public FindAllPagingQueryProviderTests(String databaseProductName,
String expectedQuery) {
this.databaseProductName = databaseProductName;
this.expectedQuery = expectedQuery;
}
// @checkstyle:off
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"Oracle", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
return Arrays.asList(new Object[][] {
{ "Oracle", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROWNUM as "
@@ -50,41 +59,39 @@ public class FindAllPagingQueryProviderTests {
+ "END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID "
+ "FROM %PREFIX%EXECUTION ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC)) WHERE TMP_ROW_NUM >= 1 AND "
+ "TMP_ROW_NUM < 11"},
{"HSQL Database Engine","SELECT LIMIT 0 10 TASK_EXECUTION_ID, "
+ "TMP_ROW_NUM < 11" },
{ "HSQL Database Engine", "SELECT LIMIT 0 10 TASK_EXECUTION_ID, "
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, "
+ "ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM %PREFIX%EXECUTION ORDER BY "
+ "START_TIME DESC, TASK_EXECUTION_ID DESC"},
{"PostgreSQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "START_TIME DESC, TASK_EXECUTION_ID DESC" },
{ "PostgreSQL", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID "
+ "FROM %PREFIX%EXECUTION ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC LIMIT 10 OFFSET 0"},
{"MySQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "TASK_EXECUTION_ID DESC LIMIT 10 OFFSET 0" },
{ "MySQL", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "%PREFIX%EXECUTION ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"},
{"Microsoft SQL Server","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROW_NUMBER() "
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION) TASK_EXECUTION_PAGE "
+ "WHERE TMP_ROW_NUM >= 1 AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC"}
});
}
public FindAllPagingQueryProviderTests(String databaseProductName, String expectedQuery) {
this.databaseProductName = databaseProductName;
this.expectedQuery = expectedQuery;
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10" },
{ "Microsoft SQL Server",
"SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROW_NUMBER() "
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION) TASK_EXECUTION_PAGE "
+ "WHERE TMP_ROW_NUM >= 1 AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC" } });
}
// @checkstyle:on
@Test
public void testGeneratedQuery() throws Exception{
String actualQuery = TestDBUtils.getPagingQueryProvider(databaseProductName).getPageQuery(pageable);
assertEquals(String.format(
"the generated query for %s, was not the expected query",
databaseProductName), expectedQuery, actualQuery);
public void testGeneratedQuery() throws Exception {
String actualQuery = TestDBUtils.getPagingQueryProvider(this.databaseProductName)
.getPageQuery(this.pageable);
assertThat(actualQuery).as(
String.format("the generated query for %s, was not the expected query",
this.databaseProductName))
.isEqualTo(this.expectedQuery);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
package org.springframework.cloud.task.repository.database.support;
import org.junit.Test;
import org.springframework.cloud.task.util.TestDBUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
@@ -27,8 +28,9 @@ import org.springframework.data.domain.Pageable;
public class InvalidPagingQueryProviderTests {
@Test(expected = IllegalStateException.class)
public void testInvalidDatabase() throws Exception{
public void testInvalidDatabase() throws Exception {
Pageable pageable = PageRequest.of(0, 10);
TestDBUtils.getPagingQueryProvider("Invalid").getPageQuery(pageable);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -16,20 +16,19 @@
package org.springframework.cloud.task.repository.database.support;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Map;
import java.util.TreeMap;
import org.junit.Before;
import org.junit.Test;
import org.springframework.batch.item.database.Order;
import org.springframework.cloud.task.repository.dao.JdbcTaskExecutionDao;
import org.springframework.cloud.task.repository.database.PagingQueryProvider;
import org.springframework.cloud.task.util.TestDBUtils;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Glenn Renfro
*/
@@ -38,28 +37,28 @@ public class SqlPagingQueryProviderFactoryBeanTests {
private SqlPagingQueryProviderFactoryBean factoryBean;
@Before
public void setup() throws Exception{
factoryBean = new SqlPagingQueryProviderFactoryBean();
factoryBean.setDataSource(TestDBUtils.getMockDataSource("MySQL"));
factoryBean.setDatabaseType("Oracle");
factoryBean.setSelectClause(JdbcTaskExecutionDao.SELECT_CLAUSE);
factoryBean.setFromClause(JdbcTaskExecutionDao.FROM_CLAUSE);
public void setup() throws Exception {
this.factoryBean = new SqlPagingQueryProviderFactoryBean();
this.factoryBean.setDataSource(TestDBUtils.getMockDataSource("MySQL"));
this.factoryBean.setDatabaseType("Oracle");
this.factoryBean.setSelectClause(JdbcTaskExecutionDao.SELECT_CLAUSE);
this.factoryBean.setFromClause(JdbcTaskExecutionDao.FROM_CLAUSE);
Map<String, Order> orderMap = new TreeMap<>();
orderMap.put("START_TIME", Order.DESCENDING);
orderMap.put("TASK_EXECUTION_ID", Order.DESCENDING);
factoryBean.setSortKeys(orderMap);
this.factoryBean.setSortKeys(orderMap);
}
@Test
public void testDatabaseType() throws Exception{
PagingQueryProvider pagingQueryProvider = factoryBean.getObject();
assertThat(pagingQueryProvider, instanceOf(OraclePagingQueryProvider.class));
public void testDatabaseType() throws Exception {
PagingQueryProvider pagingQueryProvider = this.factoryBean.getObject();
assertThat(pagingQueryProvider).isInstanceOf(OraclePagingQueryProvider.class);
}
@Test
public void testIsSingleton(){
assertTrue(factoryBean.isSingleton());
public void testIsSingleton() {
assertThat(this.factoryBean.isSingleton()).isTrue();
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -28,7 +28,7 @@ import org.springframework.cloud.task.util.TestDBUtils;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import static org.junit.Assert.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Glenn Renfro
@@ -37,13 +37,22 @@ import static org.junit.Assert.assertEquals;
public class WhereClausePagingQueryProviderTests {
private String databaseProductName;
private String expectedQuery;
private Pageable pageable = PageRequest.of(0, 10);
public WhereClausePagingQueryProviderTests(String databaseProductName,
String expectedQuery) {
this.databaseProductName = databaseProductName;
this.expectedQuery = expectedQuery;
}
// @checkstyle:off
@Parameterized.Parameters
public static Collection<Object[]> data() {
return Arrays.asList(new Object[][]{
{"Oracle", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
return Arrays.asList(new Object[][] {
{ "Oracle", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROWNUM as "
@@ -52,46 +61,43 @@ public class WhereClausePagingQueryProviderTests {
+ "LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM %PREFIX%EXECUTION "
+ "WHERE TASK_EXECUTION_ID = '0000' ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC)) WHERE TMP_ROW_NUM >= 1 AND "
+ "TMP_ROW_NUM < 11"},
{"HSQL Database Engine","SELECT LIMIT 0 10 TASK_EXECUTION_ID, "
+ "TMP_ROW_NUM < 11" },
{ "HSQL Database Engine", "SELECT LIMIT 0 10 TASK_EXECUTION_ID, "
+ "START_TIME, END_TIME, TASK_NAME, EXIT_CODE, EXIT_MESSAGE, "
+ "ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM %PREFIX%EXECUTION "
+ "WHERE TASK_EXECUTION_ID = '0000' ORDER BY "
+ "START_TIME DESC, TASK_EXECUTION_ID DESC"},
{"PostgreSQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "START_TIME DESC, TASK_EXECUTION_ID DESC" },
{ "PostgreSQL", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID "
+ "FROM %PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = '0000' "
+ "ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC LIMIT 10 OFFSET 0"},
{"MySQL","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "TASK_EXECUTION_ID DESC LIMIT 10 OFFSET 0" },
{ "MySQL", "SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "%PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = '0000' "
+ "ORDER BY START_TIME DESC, "
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10"},
{"Microsoft SQL Server","SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROW_NUMBER() "
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = "
+ "'0000') TASK_EXECUTION_PAGE WHERE TMP_ROW_NUM >= 1 "
+ "AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC"}
});
}
public WhereClausePagingQueryProviderTests(String databaseProductName, String expectedQuery) {
this.databaseProductName = databaseProductName;
this.expectedQuery = expectedQuery;
+ "TASK_EXECUTION_ID DESC LIMIT 0, 10" },
{ "Microsoft SQL Server",
"SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, "
+ "TASK_NAME, EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID FROM "
+ "(SELECT TASK_EXECUTION_ID, START_TIME, END_TIME, TASK_NAME, "
+ "EXIT_CODE, EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, PARENT_EXECUTION_ID, ROW_NUMBER() "
+ "OVER (ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC) AS "
+ "TMP_ROW_NUM FROM %PREFIX%EXECUTION WHERE TASK_EXECUTION_ID = "
+ "'0000') TASK_EXECUTION_PAGE WHERE TMP_ROW_NUM >= 1 "
+ "AND TMP_ROW_NUM < 11 ORDER BY START_TIME DESC, TASK_EXECUTION_ID DESC" } });
}
// @checkstyle:on
@Test
public void testGeneratedQuery() throws Exception{
PagingQueryProvider pagingQueryProvider =
TestDBUtils.getPagingQueryProvider(databaseProductName,
"TASK_EXECUTION_ID = '0000'");
String actualQuery = pagingQueryProvider.getPageQuery(pageable);
assertEquals(String.format(
"the generated query for %s, was not the expected query",
databaseProductName), expectedQuery, actualQuery);
public void testGeneratedQuery() throws Exception {
PagingQueryProvider pagingQueryProvider = TestDBUtils.getPagingQueryProvider(
this.databaseProductName, "TASK_EXECUTION_ID = '0000'");
String actualQuery = pagingQueryProvider.getPageQuery(this.pageable);
assertThat(actualQuery).as(
String.format("the generated query for %s, was not the expected query",
this.databaseProductName))
.isEqualTo(this.expectedQuery);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -13,20 +13,22 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository.support;
import static org.junit.Assert.assertEquals;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.cloud.task.util.TestDBUtils;
import static org.assertj.core.api.Assertions.assertThat;
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.fromProductName;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.cloud.task.util.TestDBUtils;
/**
* Tests that the correct database names are selected from datasource metadata.
*
@@ -39,10 +41,10 @@ public class DatabaseTypeTests {
@Test
public void testFromProductName() {
assertEquals(HSQL, fromProductName("HSQL Database Engine"));
assertEquals(ORACLE, fromProductName("Oracle"));
assertEquals(POSTGRES, fromProductName("PostgreSQL"));
assertEquals(MYSQL, fromProductName("MySQL"));
assertThat(fromProductName("HSQL Database Engine")).isEqualTo(HSQL);
assertThat(fromProductName("Oracle")).isEqualTo(ORACLE);
assertThat(fromProductName("PostgreSQL")).isEqualTo(POSTGRES);
assertThat(fromProductName("MySQL")).isEqualTo(MYSQL);
}
@Test(expected = IllegalArgumentException.class)
@@ -53,25 +55,25 @@ public class DatabaseTypeTests {
@Test
public void testFromMetaDataForHsql() throws Exception {
DataSource ds = TestDBUtils.getMockDataSource("HSQL Database Engine");
assertEquals(HSQL, DatabaseType.fromMetaData(ds));
assertThat(DatabaseType.fromMetaData(ds)).isEqualTo(HSQL);
}
@Test
public void testFromMetaDataForOracle() throws Exception {
DataSource ds = TestDBUtils.getMockDataSource("Oracle");
assertEquals(ORACLE, DatabaseType.fromMetaData(ds));
assertThat(DatabaseType.fromMetaData(ds)).isEqualTo(ORACLE);
}
@Test
public void testFromMetaDataForPostgres() throws Exception {
DataSource ds = TestDBUtils.getMockDataSource("PostgreSQL");
assertEquals(POSTGRES, DatabaseType.fromMetaData(ds));
assertThat(DatabaseType.fromMetaData(ds)).isEqualTo(POSTGRES);
}
@Test
public void testFromMetaDataForMySQL() throws Exception {
DataSource ds = TestDBUtils.getMockDataSource("MySQL");
assertEquals(MYSQL, DatabaseType.fromMetaData(ds));
assertThat(DatabaseType.fromMetaData(ds)).isEqualTo(MYSQL);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -16,11 +16,6 @@
package org.springframework.cloud.task.repository.support;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -41,6 +36,7 @@ import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
@@ -56,6 +52,8 @@ import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Glenn Renfro
* @author Gunnar Hillert
@@ -67,6 +65,9 @@ public class SimpleTaskExplorerTests {
private final static String EXTERNAL_EXECUTION_ID = "123ABC";
@Rule
public ExpectedException expected = ExpectedException.none();
private AnnotationConfigApplicationContext context;
@Autowired
@@ -77,18 +78,14 @@ public class SimpleTaskExplorerTests {
private DaoType testType;
@Parameterized.Parameters
public static Collection<Object> data() {
return Arrays.asList(new Object[]{
DaoType.jdbc, DaoType.map });
}
public SimpleTaskExplorerTests(DaoType testType) {
this.testType = testType;
}
@Rule
public ExpectedException expected = ExpectedException.none();
@Parameterized.Parameters
public static Collection<Object> data() {
return Arrays.asList(new Object[] { DaoType.jdbc, DaoType.map });
}
@Before
public void testDefaultContext() throws Exception {
@@ -112,11 +109,11 @@ public class SimpleTaskExplorerTests {
public void getTaskExecution() {
Map<Long, TaskExecution> expectedResults = createSampleDataSet(5);
for (Long taskExecutionId : expectedResults.keySet()) {
TaskExecution actualTaskExecution =
taskExplorer.getTaskExecution(taskExecutionId);
assertNotNull(String.format(
"expected a taskExecution but got null for test type %s", testType),
actualTaskExecution);
TaskExecution actualTaskExecution = this.taskExplorer
.getTaskExecution(taskExecutionId);
assertThat(actualTaskExecution).as(String.format(
"expected a taskExecution but got null for test type %s",
this.testType)).isNotNull();
TestVerifierUtils.verifyTaskExecution(expectedResults.get(taskExecutionId),
actualTaskExecution);
}
@@ -126,11 +123,10 @@ public class SimpleTaskExplorerTests {
public void taskExecutionNotFound() {
createSampleDataSet(5);
TaskExecution actualTaskExecution =
taskExplorer.getTaskExecution(-5);
assertNull(String.format(
"expected null for actualTaskExecution %s", testType),
actualTaskExecution);
TaskExecution actualTaskExecution = this.taskExplorer.getTaskExecution(-5);
assertThat(actualTaskExecution).as(
String.format("expected null for actualTaskExecution %s", this.testType))
.isNull();
}
@Test
@@ -138,29 +134,30 @@ public class SimpleTaskExplorerTests {
Map<Long, TaskExecution> expectedResults = createSampleDataSet(5);
for (Map.Entry<Long, TaskExecution> entry : expectedResults.entrySet()) {
String taskName = entry.getValue().getTaskName();
assertEquals(String.format(
"task count for task name did not match expected result for testType %s",
testType),
1, taskExplorer.getTaskExecutionCountByTaskName(taskName));
assertThat(this.taskExplorer.getTaskExecutionCountByTaskName(taskName))
.as(String.format(
"task count for task name did not match expected result for testType %s",
this.testType))
.isEqualTo(1);
}
}
@Test
public void getTaskCount() {
createSampleDataSet(33);
assertEquals(String.format(
"task count did not match expected result for test Type %s",
testType),
33, taskExplorer.getTaskExecutionCount());
assertThat(this.taskExplorer.getTaskExecutionCount()).as(
String.format("task count did not match expected result for test Type %s",
this.testType))
.isEqualTo(33);
}
@Test
public void getRunningTaskCount() {
createSampleDataSet(33);
assertEquals(String.format(
"task count did not match expected result for test Type %s",
testType),
33, taskExplorer.getRunningTaskExecutionCount());
assertThat(this.taskExplorer.getRunningTaskExecutionCount()).as(
String.format("task count did not match expected result for test Type %s",
this.testType))
.isEqualTo(33);
}
@Test
@@ -169,31 +166,34 @@ public class SimpleTaskExplorerTests {
final int COMPLETE_COUNT = 5;
Map<Long, TaskExecution> expectedResults = new HashMap<>();
//Store completed jobs
// Store completed jobs
int i = 0;
for (; i < COMPLETE_COUNT; i++) {
createAndSaveTaskExecution(i);
}
for (; i < (COMPLETE_COUNT + TEST_COUNT); i++) {
TaskExecution expectedTaskExecution = this.taskRepository.
createTaskExecution(getSimpleTaskExecution());
expectedResults.put(expectedTaskExecution.getExecutionId(), expectedTaskExecution);
TaskExecution expectedTaskExecution = this.taskRepository
.createTaskExecution(getSimpleTaskExecution());
expectedResults.put(expectedTaskExecution.getExecutionId(),
expectedTaskExecution);
}
Pageable pageable = PageRequest.of(0, 10);
Page<TaskExecution> actualResults = taskExplorer.findRunningTaskExecutions(TASK_NAME, pageable);
assertEquals(String.format(
Page<TaskExecution> actualResults = this.taskExplorer
.findRunningTaskExecutions(TASK_NAME, pageable);
assertThat(actualResults.getNumberOfElements()).as(String.format(
"Running task count for task name did not match expected result for testType %s",
testType), TEST_COUNT, actualResults.getNumberOfElements());
this.testType)).isEqualTo(TEST_COUNT);
for (TaskExecution result : actualResults) {
assertTrue(String.format(
"result returned from repo %s not expected for testType %s",
result.getExecutionId(), testType),
expectedResults.containsKey(result.getExecutionId()));
assertNull(String.format("result had non null for endTime for the testType %s",
testType), result.getEndTime());
assertThat(expectedResults.containsKey(result.getExecutionId())).as(String
.format("result returned from repo %s not expected for testType %s",
result.getExecutionId(), this.testType))
.isTrue();
assertThat(result.getEndTime()).as(String.format(
"result had non null for endTime for the testType %s", this.testType))
.isNull();
}
}
@@ -203,30 +203,33 @@ public class SimpleTaskExplorerTests {
final int COMPLETE_COUNT = 7;
Map<Long, TaskExecution> expectedResults = new HashMap<>();
//Store completed jobs
// Store completed jobs
for (int i = 0; i < COMPLETE_COUNT; i++) {
createAndSaveTaskExecution(i);
}
for (int i = 0; i < TEST_COUNT; i++) {
TaskExecution expectedTaskExecution = this.taskRepository.
createTaskExecution(getSimpleTaskExecution());
expectedResults.put(expectedTaskExecution.getExecutionId(), expectedTaskExecution);
TaskExecution expectedTaskExecution = this.taskRepository
.createTaskExecution(getSimpleTaskExecution());
expectedResults.put(expectedTaskExecution.getExecutionId(),
expectedTaskExecution);
}
Pageable pageable = PageRequest.of(0, 10);
Page<TaskExecution> resultSet = taskExplorer.findTaskExecutionsByName(TASK_NAME, pageable);
assertEquals(String.format(
Page<TaskExecution> resultSet = this.taskExplorer
.findTaskExecutionsByName(TASK_NAME, pageable);
assertThat(resultSet.getNumberOfElements()).as(String.format(
"Running task count for task name did not match expected result for testType %s",
testType), TEST_COUNT, resultSet.getNumberOfElements());
this.testType)).isEqualTo(TEST_COUNT);
for (TaskExecution result : resultSet) {
assertTrue(String.format("result returned from %s repo %s not expected",
testType, result.getExecutionId()),
expectedResults.containsKey(result.getExecutionId()));
assertEquals(
String.format("taskName for taskExecution is incorrect for testType %s",
testType), TASK_NAME, result.getTaskName());
assertThat(expectedResults.containsKey(result.getExecutionId()))
.as(String.format("result returned from %s repo %s not expected",
this.testType, result.getExecutionId()))
.isTrue();
assertThat(result.getTaskName()).as(String.format(
"taskName for taskExecution is incorrect for testType %s",
this.testType)).isEqualTo(TASK_NAME);
}
}
@@ -238,10 +241,12 @@ public class SimpleTaskExplorerTests {
TaskExecution expectedTaskExecution = createAndSaveTaskExecution(i);
expectedResults.add(expectedTaskExecution.getTaskName());
}
List<String> actualTaskNames = taskExplorer.getTaskNames();
List<String> actualTaskNames = this.taskExplorer.getTaskNames();
for (String taskName : actualTaskNames) {
assertTrue(String.format("taskName was not in expected results for testType %s",
testType), expectedResults.contains(taskName));
assertThat(expectedResults.contains(taskName)).as(
String.format("taskName was not in expected results for testType %s",
this.testType))
.isTrue();
}
}
@@ -271,23 +276,26 @@ public class SimpleTaskExplorerTests {
@Test
public void findTasksForInvalidJob() {
assertNull(taskExplorer.getTaskExecutionIdByJobExecutionId(55555L));
assertThat(this.taskExplorer.getTaskExecutionIdByJobExecutionId(55555L)).isNull();
}
@Test
public void findJobsExecutionIdsForInvalidTask () {
assertEquals(0, taskExplorer.getJobExecutionIdsByTaskExecutionId(555555L).size());
public void findJobsExecutionIdsForInvalidTask() {
assertThat(this.taskExplorer.getJobExecutionIdsByTaskExecutionId(555555L).size())
.isEqualTo(0);
}
@Test
public void getLatestTaskExecutionForTaskName() {
Map<Long, TaskExecution> expectedResults = createSampleDataSet(5);
for (Map.Entry<Long, TaskExecution> taskExecutionMapEntry: expectedResults.entrySet()) {
TaskExecution latestTaskExecution =
taskExplorer.getLatestTaskExecutionForTaskName(taskExecutionMapEntry.getValue().getTaskName());
assertNotNull(String.format(
"expected a taskExecution but got null for test type %s", testType),
latestTaskExecution);
for (Map.Entry<Long, TaskExecution> taskExecutionMapEntry : expectedResults
.entrySet()) {
TaskExecution latestTaskExecution = this.taskExplorer
.getLatestTaskExecutionForTaskName(
taskExecutionMapEntry.getValue().getTaskName());
assertThat(latestTaskExecution).as(String.format(
"expected a taskExecution but got null for test type %s",
this.testType)).isNotNull();
TestVerifierUtils.verifyTaskExecution(
expectedResults.get(latestTaskExecution.getExecutionId()),
latestTaskExecution);
@@ -304,13 +312,14 @@ public class SimpleTaskExplorerTests {
taskNamesAsList.add(taskExecution.getTaskName());
}
final List<TaskExecution> latestTaskExecutions = taskExplorer.getLatestTaskExecutionsByTaskNames(
taskNamesAsList.toArray(new String[taskNamesAsList.size()]));
final List<TaskExecution> latestTaskExecutions = this.taskExplorer
.getLatestTaskExecutionsByTaskNames(
taskNamesAsList.toArray(new String[taskNamesAsList.size()]));
for (TaskExecution latestTaskExecution : latestTaskExecutions) {
assertNotNull(String.format(
"expected a taskExecution but got null for test type %s", testType),
latestTaskExecution);
assertThat(latestTaskExecution).as(String.format(
"expected a taskExecution but got null for test type %s",
this.testType)).isNotNull();
TestVerifierUtils.verifyTaskExecution(
expectedResults.get(latestTaskExecution.getExecutionId()),
latestTaskExecution);
@@ -318,38 +327,42 @@ public class SimpleTaskExplorerTests {
}
private void verifyPageResults(Pageable pageable, int totalNumberOfExecs) {
Map<Long, TaskExecution> expectedResults = createSampleDataSet(totalNumberOfExecs);
Map<Long, TaskExecution> expectedResults = createSampleDataSet(
totalNumberOfExecs);
List<Long> sortedExecIds = getSortedOfTaskExecIds(expectedResults);
Iterator<Long> expectedTaskExecutionIter = sortedExecIds.iterator();
//Verify pageable totals
Page<TaskExecution> taskPage = taskExplorer.findAll(pageable);
int pagesExpected = (int) Math.ceil(totalNumberOfExecs / ((double) pageable.getPageSize()));
assertEquals("actual page count return was not the expected total",
pagesExpected,
taskPage.getTotalPages());
assertEquals("actual element count was not the expected count", totalNumberOfExecs,
taskPage.getTotalElements());
// Verify pageable totals
Page<TaskExecution> taskPage = this.taskExplorer.findAll(pageable);
int pagesExpected = (int) Math
.ceil(totalNumberOfExecs / ((double) pageable.getPageSize()));
assertThat(taskPage.getTotalPages())
.as("actual page count return was not the expected total")
.isEqualTo(pagesExpected);
assertThat(taskPage.getTotalElements())
.as("actual element count was not the expected count")
.isEqualTo(totalNumberOfExecs);
//Verify pagination
// Verify pagination
Pageable actualPageable = PageRequest.of(0, pageable.getPageSize());
boolean hasMorePages = taskPage.hasContent();
int pageNumber = 0;
int elementCount = 0;
while (hasMorePages) {
taskPage = taskExplorer.findAll(actualPageable);
taskPage = this.taskExplorer.findAll(actualPageable);
hasMorePages = taskPage.hasNext();
List<TaskExecution> actualTaskExecutions = taskPage.getContent();
int expectedPageSize = pageable.getPageSize();
if (!hasMorePages && pageable.getPageSize() != actualTaskExecutions.size()) {
expectedPageSize = totalNumberOfExecs % pageable.getPageSize();
}
assertEquals(
String.format("Element count on page did not match on the %n page",
pageNumber), expectedPageSize, actualTaskExecutions.size());
assertThat(actualTaskExecutions.size()).as(String.format(
"Element count on page did not match on the %n page", pageNumber))
.isEqualTo(expectedPageSize);
for (TaskExecution actualExecution : actualTaskExecutions) {
assertEquals(String.format("Element on page %n did not match expected",
pageNumber), (long)expectedTaskExecutionIter.next(),
actualExecution.getExecutionId());
assertThat(actualExecution.getExecutionId())
.as(String.format("Element on page %n did not match expected",
pageNumber))
.isEqualTo((long) expectedTaskExecutionIter.next());
TestVerifierUtils.verifyTaskExecution(
expectedResults.get(actualExecution.getExecutionId()),
actualExecution);
@@ -358,9 +371,11 @@ public class SimpleTaskExplorerTests {
actualPageable = taskPage.nextPageable();
pageNumber++;
}
//Verify actual totals
assertEquals("Pages processed did not equal expected", pagesExpected, pageNumber);
assertEquals("Elements processed did not equal expected,", totalNumberOfExecs, elementCount);
// Verify actual totals
assertThat(pageNumber).as("Pages processed did not equal expected")
.isEqualTo(pagesExpected);
assertThat(elementCount).as("Elements processed did not equal expected,")
.isEqualTo(totalNumberOfExecs);
}
private TaskExecution createAndSaveTaskExecution(int i) {
@@ -376,7 +391,7 @@ public class SimpleTaskExplorerTests {
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
this.context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
}
@@ -386,11 +401,11 @@ public class SimpleTaskExplorerTests {
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
this.context.getAutowireCapableBeanFactory().autowireBeanProperties(this,
AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, false);
}
private Map<Long, TaskExecution> createSampleDataSet(int count){
private Map<Long, TaskExecution> createSampleDataSet(int count) {
Map<Long, TaskExecution> expectedResults = new HashMap<>();
for (int i = 0; i < count; i++) {
TaskExecution expectedTaskExecution = createAndSaveTaskExecution(i);
@@ -400,24 +415,25 @@ public class SimpleTaskExplorerTests {
return expectedResults;
}
private List<Long> getSortedOfTaskExecIds(Map<Long, TaskExecution> taskExecutionMap){
private List<Long> getSortedOfTaskExecIds(Map<Long, TaskExecution> taskExecutionMap) {
List<Long> sortedExecIds = new ArrayList<>(taskExecutionMap.size());
TreeSet<TaskExecution> sortedSet = getTreeSet();
sortedSet.addAll(taskExecutionMap.values());
Iterator <TaskExecution> iterator = sortedSet.descendingIterator();
while(iterator.hasNext()){
Iterator<TaskExecution> iterator = sortedSet.descendingIterator();
while (iterator.hasNext()) {
sortedExecIds.add(iterator.next().getExecutionId());
}
return sortedExecIds;
}
private TreeSet<TaskExecution> getTreeSet(){
return new TreeSet<TaskExecution>(new Comparator<TaskExecution>() {
private TreeSet<TaskExecution> getTreeSet() {
return new TreeSet<>(new Comparator<TaskExecution>() {
@Override
public int compare(TaskExecution e1, TaskExecution e2) {
int result = e1.getStartTime().compareTo(e2.getStartTime());
if (result == 0){
result = Long.valueOf(e1.getExecutionId()).compareTo(e2.getExecutionId());
if (result == 0) {
result = Long.valueOf(e1.getExecutionId())
.compareTo(e2.getExecutionId());
}
return result;
}
@@ -432,11 +448,20 @@ public class SimpleTaskExplorerTests {
return taskExecution;
}
private enum DaoType{jdbc, map}
private enum DaoType {
jdbc, map
}
@Configuration
public static class DataSourceConfiguration{}
public static class DataSourceConfiguration {
}
@Configuration
public static class EmptyConfiguration{}
public static class EmptyConfiguration {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,14 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository.support;
import org.junit.Test;
import org.springframework.context.support.GenericApplicationContext;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Michael Minella
@@ -34,7 +34,9 @@ public class SimpleTaskNameResolverTests {
SimpleTaskNameResolver taskNameResolver = new SimpleTaskNameResolver();
taskNameResolver.setApplicationContext(context);
assertTrue(taskNameResolver.getTaskName().startsWith("org.springframework.context.support.GenericApplicationContext"));
assertThat(taskNameResolver.getTaskName().startsWith(
"org.springframework.context.support.GenericApplicationContext"))
.isTrue();
}
@Test
@@ -45,7 +47,7 @@ public class SimpleTaskNameResolverTests {
SimpleTaskNameResolver taskNameResolver = new SimpleTaskNameResolver();
taskNameResolver.setApplicationContext(context);
assertTrue(taskNameResolver.getTaskName().startsWith("foo_bar"));
assertThat(taskNameResolver.getTaskName().startsWith("foo_bar")).isTrue();
}
@Test
@@ -56,7 +58,7 @@ public class SimpleTaskNameResolverTests {
SimpleTaskNameResolver taskNameResolver = new SimpleTaskNameResolver();
taskNameResolver.setApplicationContext(context);
assertEquals("foo", taskNameResolver.getTaskName());
assertThat(taskNameResolver.getTaskName()).isEqualTo("foo");
}
@Test
@@ -69,6 +71,7 @@ public class SimpleTaskNameResolverTests {
taskNameResolver.setConfiguredName("bar");
assertEquals("bar", taskNameResolver.getTaskName());
assertThat(taskNameResolver.getTaskName()).isEqualTo("bar");
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@ import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import static org.junit.Assert.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Tests for the SimpleTaskRepository that uses JDBC as a datastore.
@@ -48,9 +48,8 @@ import static org.junit.Assert.assertEquals;
* @author Ilayaperumal Gopinathan
*/
@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {EmbeddedDataSourceConfiguration.class,
SimpleTaskAutoConfiguration.class,
PropertyPlaceholderAutoConfiguration.class})
@ContextConfiguration(classes = { EmbeddedDataSourceConfiguration.class,
SimpleTaskAutoConfiguration.class, PropertyPlaceholderAutoConfiguration.class })
@DirtiesContext
public class SimpleTaskRepositoryJdbcTests {
@@ -63,47 +62,49 @@ public class SimpleTaskRepositoryJdbcTests {
@Test
@DirtiesContext
public void testCreateEmptyExecution() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution actualTaskExecution = TestDBUtils.getTaskExecutionFromDB(dataSource,
expectedTaskExecution.getExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
actualTaskExecution);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
TaskExecution actualTaskExecution = TestDBUtils.getTaskExecutionFromDB(
this.dataSource, expectedTaskExecution.getExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void testCreateTaskExecutionNoParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution actualTaskExecution = TestDBUtils.getTaskExecutionFromDB(dataSource,
expectedTaskExecution.getExecutionId());
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
TaskExecution actualTaskExecution = TestDBUtils.getTaskExecutionFromDB(
this.dataSource, expectedTaskExecution.getExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void testCreateTaskExecutionWithParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionWithParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionWithParams(this.taskRepository);
TaskExecution actualTaskExecution = TestDBUtils.getTaskExecutionFromDB(
dataSource, expectedTaskExecution.getExecutionId());
this.dataSource, expectedTaskExecution.getExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void startTaskExecutionWithParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setArguments(
Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), expectedTaskExecution.getExternalExecutionId());
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@@ -111,66 +112,68 @@ public class SimpleTaskRepositoryJdbcTests {
@Test
@DirtiesContext
public void startTaskExecutionWithNoParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), expectedTaskExecution.getExternalExecutionId());
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
public void testUpdateExternalExecutionId() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExternalExecutionId(UUID.randomUUID().toString());
taskRepository.updateExternalExecutionId(
this.taskRepository.updateExternalExecutionId(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource,
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test
public void testUpdateNullExternalExecutionId() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExternalExecutionId(null);
taskRepository.updateExternalExecutionId(
this.taskRepository.updateExternalExecutionId(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
TestDBUtils.getTaskExecutionFromDB(dataSource,
TestDBUtils.getTaskExecutionFromDB(this.dataSource,
expectedTaskExecution.getExecutionId()));
}
@Test(expected = IllegalStateException.class)
public void testInvalidExecutionIdForExternalExecutionIdUpdate() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExternalExecutionId(null);
taskRepository.updateExternalExecutionId(
-1,
this.taskRepository.updateExternalExecutionId(-1,
expectedTaskExecution.getExternalExecutionId());
}
@Test
@DirtiesContext
public void startTaskExecutionWithParent() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
expectedTaskExecution.setParentExecutionId(12345L);
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId(),
@@ -182,62 +185,79 @@ public class SimpleTaskRepositoryJdbcTests {
@Test
@DirtiesContext
public void testCompleteTaskExecution() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(77);
expectedTaskExecution.setExitMessage(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = TaskExecutionCreator.completeExecution(taskRepository, expectedTaskExecution);
TaskExecution actualTaskExecution = TaskExecutionCreator
.completeExecution(this.taskRepository, expectedTaskExecution);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
@DirtiesContext
public void testCreateTaskExecutionNoParamMaxExitDefaultMessageSize(){
TaskExecution expectedTaskExecution = TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
expectedTaskExecution.setExitMessage(new String(new char[SimpleTaskRepository.MAX_EXIT_MESSAGE_SIZE+1]));
public void testCreateTaskExecutionNoParamMaxExitDefaultMessageSize() {
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExitMessage(
new String(new char[SimpleTaskRepository.MAX_EXIT_MESSAGE_SIZE + 1]));
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(0);
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution, taskRepository);
assertEquals(SimpleTaskRepository.MAX_EXIT_MESSAGE_SIZE, actualTaskExecution.getExitMessage().length());
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution,
this.taskRepository);
assertThat(actualTaskExecution.getExitMessage().length())
.isEqualTo(SimpleTaskRepository.MAX_EXIT_MESSAGE_SIZE);
}
@Test
public void testCreateTaskExecutionNoParamMaxExitMessageSize() {
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(new TaskExecutionDaoFactoryBean(this.dataSource));
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(
new TaskExecutionDaoFactoryBean(this.dataSource));
simpleTaskRepository.setMaxExitMessageSize(5);
TaskExecution expectedTaskExecution = TaskExecutionCreator.createAndStoreTaskExecutionNoParams(simpleTaskRepository);
expectedTaskExecution.setExitMessage(new String(new char[SimpleTaskRepository.MAX_EXIT_MESSAGE_SIZE + 1]));
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(simpleTaskRepository);
expectedTaskExecution.setExitMessage(
new String(new char[SimpleTaskRepository.MAX_EXIT_MESSAGE_SIZE + 1]));
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(0);
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution, simpleTaskRepository);
assertEquals(5, actualTaskExecution.getExitMessage().length());
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution,
simpleTaskRepository);
assertThat(actualTaskExecution.getExitMessage().length()).isEqualTo(5);
}
@Test
@DirtiesContext
public void testCreateTaskExecutionNoParamMaxErrorDefaultMessageSize(){
TaskExecution expectedTaskExecution = TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
expectedTaskExecution.setErrorMessage(new String(new char[SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE+1]));
public void testCreateTaskExecutionNoParamMaxErrorDefaultMessageSize() {
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setErrorMessage(
new String(new char[SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE + 1]));
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(0);
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution, taskRepository);
assertEquals(SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE, actualTaskExecution.getErrorMessage().length());
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution,
this.taskRepository);
assertThat(actualTaskExecution.getErrorMessage().length())
.isEqualTo(SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE);
}
@Test
public void testCreateTaskExecutionNoParamMaxErrorMessageSize() {
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(new TaskExecutionDaoFactoryBean(this.dataSource));
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(
new TaskExecutionDaoFactoryBean(this.dataSource));
simpleTaskRepository.setMaxErrorMessageSize(5);
TaskExecution expectedTaskExecution = TaskExecutionCreator.createAndStoreTaskExecutionNoParams(simpleTaskRepository);
expectedTaskExecution.setErrorMessage(new String(new char[SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE + 1]));
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(simpleTaskRepository);
expectedTaskExecution.setErrorMessage(
new String(new char[SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE + 1]));
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(0);
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution, simpleTaskRepository);
assertEquals(5, actualTaskExecution.getErrorMessage().length());
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution,
simpleTaskRepository);
assertThat(actualTaskExecution.getErrorMessage().length()).isEqualTo(5);
}
@Test(expected = IllegalArgumentException.class)
@@ -246,9 +266,10 @@ public class SimpleTaskRepositoryJdbcTests {
final int MAX_ERROR_MESSAGE_SIZE = 20;
final int MAX_TASK_NAME_SIZE = 30;
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(
new TaskExecutionDaoFactoryBean(this.dataSource), MAX_EXIT_MESSAGE_SIZE, MAX_TASK_NAME_SIZE,
MAX_ERROR_MESSAGE_SIZE);
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
new TaskExecutionDaoFactoryBean(this.dataSource), MAX_EXIT_MESSAGE_SIZE,
MAX_TASK_NAME_SIZE, MAX_ERROR_MESSAGE_SIZE);
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
expectedTaskExecution.setTaskName(new String(new char[MAX_TASK_NAME_SIZE + 1]));
simpleTaskRepository.createTaskExecution(expectedTaskExecution);
}
@@ -257,8 +278,10 @@ public class SimpleTaskRepositoryJdbcTests {
public void testDefaultMaxTaskNameSizeForConstructor() {
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(
new TaskExecutionDaoFactoryBean(this.dataSource), null, null, null);
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
expectedTaskExecution.setTaskName(new String(new char[SimpleTaskRepository.MAX_TASK_NAME_SIZE + 1]));
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
expectedTaskExecution.setTaskName(
new String(new char[SimpleTaskRepository.MAX_TASK_NAME_SIZE + 1]));
simpleTaskRepository.createTaskExecution(expectedTaskExecution);
}
@@ -267,9 +290,10 @@ public class SimpleTaskRepositoryJdbcTests {
final int MAX_EXIT_MESSAGE_SIZE = 10;
final int MAX_ERROR_MESSAGE_SIZE = 20;
SimpleTaskRepository simpleTaskRepository = new SimpleTaskRepository(
new TaskExecutionDaoFactoryBean(this.dataSource), MAX_EXIT_MESSAGE_SIZE, null,
MAX_ERROR_MESSAGE_SIZE);
verifyTaskRepositoryConstructor(MAX_EXIT_MESSAGE_SIZE, MAX_ERROR_MESSAGE_SIZE, simpleTaskRepository);
new TaskExecutionDaoFactoryBean(this.dataSource), MAX_EXIT_MESSAGE_SIZE,
null, MAX_ERROR_MESSAGE_SIZE);
verifyTaskRepositoryConstructor(MAX_EXIT_MESSAGE_SIZE, MAX_ERROR_MESSAGE_SIZE,
simpleTaskRepository);
}
@Test
@@ -280,54 +304,63 @@ public class SimpleTaskRepositoryJdbcTests {
SimpleTaskRepository.MAX_ERROR_MESSAGE_SIZE, simpleTaskRepository);
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
@DirtiesContext
public void testCreateTaskExecutionNoParamMaxTaskName(){
public void testCreateTaskExecutionNoParamMaxTaskName() {
TaskExecution taskExecution = new TaskExecution();
taskExecution.setTaskName(
new String(new char[SimpleTaskRepository.MAX_TASK_NAME_SIZE+1]));
new String(new char[SimpleTaskRepository.MAX_TASK_NAME_SIZE + 1]));
taskExecution.setStartTime(new Date());
taskRepository.createTaskExecution(taskExecution);
this.taskRepository.createTaskExecution(taskExecution);
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
@DirtiesContext
public void testCreateTaskExecutionNegativeException(){
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
public void testCreateTaskExecutionNegativeException() {
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(-1);
TaskExecution actualTaskExecution = TaskExecutionCreator.completeExecution(taskRepository, expectedTaskExecution);
TaskExecution actualTaskExecution = TaskExecutionCreator
.completeExecution(this.taskRepository, expectedTaskExecution);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test(expected=IllegalArgumentException.class)
@Test(expected = IllegalArgumentException.class)
@DirtiesContext
public void testCreateTaskExecutionNullEndTime(){
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
public void testCreateTaskExecutionNullEndTime() {
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExitCode(-1);
TaskExecutionCreator.completeExecution(taskRepository, expectedTaskExecution);
TaskExecutionCreator.completeExecution(this.taskRepository,
expectedTaskExecution);
}
private TaskExecution completeTaskExecution(TaskExecution expectedTaskExecution, TaskRepository taskRepository) {
return taskRepository.completeTaskExecution(expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), new Date(),
expectedTaskExecution.getExitMessage(), expectedTaskExecution.getErrorMessage());
}
private void verifyTaskRepositoryConstructor(Integer maxExitMessage, Integer maxErrorMessage,
private TaskExecution completeTaskExecution(TaskExecution expectedTaskExecution,
TaskRepository taskRepository) {
TaskExecution expectedTaskExecution = TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
expectedTaskExecution.setErrorMessage(new String(new char[maxErrorMessage+ 1]));
return taskRepository.completeTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), new Date(),
expectedTaskExecution.getExitMessage(),
expectedTaskExecution.getErrorMessage());
}
private void verifyTaskRepositoryConstructor(Integer maxExitMessage,
Integer maxErrorMessage, TaskRepository taskRepository) {
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(taskRepository);
expectedTaskExecution.setErrorMessage(new String(new char[maxErrorMessage + 1]));
expectedTaskExecution.setExitMessage(new String(new char[maxExitMessage + 1]));
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(0);
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution, taskRepository);
assertEquals(maxErrorMessage.intValue(), actualTaskExecution.getErrorMessage().length());
assertEquals(maxExitMessage.intValue(), actualTaskExecution.getExitMessage().length());
TaskExecution actualTaskExecution = completeTaskExecution(expectedTaskExecution,
taskRepository);
assertThat(actualTaskExecution.getErrorMessage().length())
.isEqualTo(maxErrorMessage.intValue());
assertThat(actualTaskExecution.getExitMessage().length())
.isEqualTo(maxExitMessage.intValue());
}
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -49,72 +49,78 @@ public class SimpleTaskRepositoryMapTests {
@Test
public void testCreateEmptyExecution() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
getSingleTaskExecutionFromMapRepository(
expectedTaskExecution.getExecutionId()));
}
@Test
public void testCreateTaskExecutionNoParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
getSingleTaskExecutionFromMapRepository(
expectedTaskExecution.getExecutionId()));
}
@Test
public void testUpdateExternalExecutionId() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExternalExecutionId(UUID.randomUUID().toString());
taskRepository.updateExternalExecutionId(
this.taskRepository.updateExternalExecutionId(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
getSingleTaskExecutionFromMapRepository(
expectedTaskExecution.getExecutionId()));
}
@Test
public void testUpdateNullExternalExecutionId() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExternalExecutionId(null);
taskRepository.updateExternalExecutionId(
this.taskRepository.updateExternalExecutionId(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
getSingleTaskExecutionFromMapRepository(
expectedTaskExecution.getExecutionId()));
}
@Test(expected = IllegalArgumentException.class)
public void testInvalidExecutionIdForExternalExecutionIdUpdate() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExternalExecutionId(null);
taskRepository.updateExternalExecutionId(
-1,
this.taskRepository.updateExternalExecutionId(-1,
expectedTaskExecution.getExternalExecutionId());
}
@Test
public void testCreateTaskExecutionWithParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionWithParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionWithParams(this.taskRepository);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution,
getSingleTaskExecutionFromMapRepository(expectedTaskExecution.getExecutionId()));
getSingleTaskExecutionFromMapRepository(
expectedTaskExecution.getExecutionId()));
}
@Test
public void startTaskExecutionWithParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
expectedTaskExecution.setArguments(Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setArguments(
Collections.singletonList("foo=" + UUID.randomUUID().toString()));
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId(),
@@ -125,59 +131,65 @@ public class SimpleTaskRepositoryMapTests {
@Test
public void startTaskExecutionWithNoParam() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), expectedTaskExecution.getExternalExecutionId());
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
public void startTaskExecutionWithParent() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreEmptyTaskExecution(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreEmptyTaskExecution(this.taskRepository);
expectedTaskExecution.setStartTime(new Date());
expectedTaskExecution.setTaskName(UUID.randomUUID().toString());
expectedTaskExecution.setParentExecutionId(12345L);
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(expectedTaskExecution.getExecutionId(),
TaskExecution actualTaskExecution = this.taskRepository.startTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getTaskName(), expectedTaskExecution.getStartTime(),
expectedTaskExecution.getArguments(), expectedTaskExecution.getExternalExecutionId());
expectedTaskExecution.getArguments(),
expectedTaskExecution.getExternalExecutionId());
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
@Test
public void testCompleteTaskExecution() {
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setEndTime(new Date());
expectedTaskExecution.setExitCode(0);
TaskExecution actualTaskExecution = TaskExecutionCreator.completeExecution(taskRepository, expectedTaskExecution);
TaskExecution actualTaskExecution = TaskExecutionCreator
.completeExecution(this.taskRepository, expectedTaskExecution);
TestVerifierUtils.verifyTaskExecution(expectedTaskExecution, actualTaskExecution);
}
private TaskExecution getSingleTaskExecutionFromMapRepository(long taskExecutionId){
Map<Long, TaskExecution> taskMap = ((MapTaskExecutionDao)
((SimpleTaskRepository)taskRepository).getTaskExecutionDao()).getTaskExecutions();
private TaskExecution getSingleTaskExecutionFromMapRepository(long taskExecutionId) {
Map<Long, TaskExecution> taskMap = ((MapTaskExecutionDao) ((SimpleTaskRepository) this.taskRepository)
.getTaskExecutionDao()).getTaskExecutions();
assertTrue("taskExecutionId must be in MapTaskExecutionRepository",
taskMap.containsKey(taskExecutionId));
return taskMap.get(taskExecutionId);
}
@Test(expected=IllegalArgumentException.class)
public void testCreateTaskExecutionNullEndTime(){
TaskExecution expectedTaskExecution =
TaskExecutionCreator.createAndStoreTaskExecutionNoParams(taskRepository);
@Test(expected = IllegalArgumentException.class)
public void testCreateTaskExecutionNullEndTime() {
TaskExecution expectedTaskExecution = TaskExecutionCreator
.createAndStoreTaskExecutionNoParams(this.taskRepository);
expectedTaskExecution.setExitCode(-1);
TaskExecutionCreator.completeExecution(taskRepository, expectedTaskExecution);
TaskExecutionCreator.completeExecution(this.taskRepository,
expectedTaskExecution);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -33,9 +33,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
@@ -44,11 +42,12 @@ import static org.mockito.Mockito.mock;
* @author Glenn Renfro
*/
public class TaskDatabaseInitializerTests {
private AnnotationConfigApplicationContext context;
@Rule
public ExpectedException expected = ExpectedException.none();
private AnnotationConfigApplicationContext context;
@After
public void close() {
if (this.context != null) {
@@ -59,21 +58,23 @@ public class TaskDatabaseInitializerTests {
@Test
public void testDefaultContext() {
this.context = new AnnotationConfigApplicationContext();
this.context.register( TestConfiguration.class,
this.context.register(TestConfiguration.class,
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertEquals(0, new JdbcTemplate(this.context.getBean(DataSource.class))
.queryForList("select * from TASK_EXECUTION").size());
assertThat(new JdbcTemplate(this.context.getBean(DataSource.class))
.queryForList("select * from TASK_EXECUTION").size()).isEqualTo(0);
}
@Test
public void testNoDatabase() {
this.context = new AnnotationConfigApplicationContext(EmptyConfiguration.class);
SimpleTaskRepository repository = new SimpleTaskRepository(new TaskExecutionDaoFactoryBean());
assertThat(repository.getTaskExecutionDao(), instanceOf(MapTaskExecutionDao.class));
SimpleTaskRepository repository = new SimpleTaskRepository(
new TaskExecutionDaoFactoryBean());
assertThat(repository.getTaskExecutionDao())
.isInstanceOf(MapTaskExecutionDao.class);
MapTaskExecutionDao dao = (MapTaskExecutionDao) repository.getTaskExecutionDao();
assertEquals(0, dao.getTaskExecutions().size());
assertThat(dao.getTaskExecutions().size()).isEqualTo(0);
}
@Test
@@ -83,20 +84,24 @@ public class TaskDatabaseInitializerTests {
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
this.context.refresh();
assertEquals(0, this.context.getBeanNamesForType(SimpleTaskRepository.class).length);
assertThat(this.context.getBeanNamesForType(SimpleTaskRepository.class).length)
.isEqualTo(0);
}
@Test(expected = BeanCreationException.class)
public void testMultipleDataSourcesContext() {
this.context = new AnnotationConfigApplicationContext();
this.context.register( SimpleTaskAutoConfiguration.class,
this.context.register(SimpleTaskAutoConfiguration.class,
EmbeddedDataSourceConfiguration.class,
PropertyPlaceholderAutoConfiguration.class);
DataSource dataSource = mock(DataSource.class);
context.getBeanFactory().registerSingleton("mockDataSource", dataSource);
this.context.getBeanFactory().registerSingleton("mockDataSource", dataSource);
this.context.refresh();
}
@Configuration
public static class EmptyConfiguration {}
public static class EmptyConfiguration {
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.task.repository.support;
import javax.sql.DataSource;
@@ -31,8 +32,7 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Michael Minella
@@ -43,19 +43,20 @@ public class TaskExecutionDaoFactoryBeanTests {
@After
public void tearDown() {
if(this.context != null) {
if (this.context != null) {
this.context.close();
}
}
@Test
public void testGetObjectType() {
assertEquals(new TaskExecutionDaoFactoryBean().getObjectType(), TaskExecutionDao.class);
assertThat(TaskExecutionDao.class)
.isEqualTo(new TaskExecutionDaoFactoryBean().getObjectType());
}
@Test
public void testIsSingleton() {
assertTrue(new TaskExecutionDaoFactoryBean().isSingleton());
assertThat(new TaskExecutionDaoFactoryBean().isSingleton()).isTrue();
}
@Test(expected = IllegalArgumentException.class)
@@ -63,46 +64,49 @@ public class TaskExecutionDaoFactoryBeanTests {
new TaskExecutionDaoFactoryBean(null);
}
@Test
public void testMapTaskExecutionDaoWithoutAppContext() throws Exception {
TaskExecutionDaoFactoryBean factoryBean = new TaskExecutionDaoFactoryBean();
TaskExecutionDao taskExecutionDao = factoryBean.getObject();
assertTrue(taskExecutionDao instanceof MapTaskExecutionDao);
assertThat(taskExecutionDao instanceof MapTaskExecutionDao).isTrue();
TaskExecutionDao taskExecutionDao2 = factoryBean.getObject();
assertTrue(taskExecutionDao == taskExecutionDao2);
assertThat(taskExecutionDao == taskExecutionDao2).isTrue();
}
@Test
public void testDefaultDataSourceConfiguration() throws Exception {
this.context = new AnnotationConfigApplicationContext(DefaultDataSourceConfiguration.class);
this.context = new AnnotationConfigApplicationContext(
DefaultDataSourceConfiguration.class);
DataSource dataSource = this.context.getBean(DataSource.class);
TaskExecutionDaoFactoryBean factoryBean = new TaskExecutionDaoFactoryBean(dataSource);
TaskExecutionDaoFactoryBean factoryBean = new TaskExecutionDaoFactoryBean(
dataSource);
TaskExecutionDao taskExecutionDao = factoryBean.getObject();
assertTrue(taskExecutionDao instanceof JdbcTaskExecutionDao);
assertThat(taskExecutionDao instanceof JdbcTaskExecutionDao).isTrue();
TaskExecutionDao taskExecutionDao2 = factoryBean.getObject();
assertTrue(taskExecutionDao == taskExecutionDao2);
assertThat(taskExecutionDao == taskExecutionDao2).isTrue();
}
@Test
public void testSettingTablePrefix() throws Exception {
this.context = new AnnotationConfigApplicationContext(DefaultDataSourceConfiguration.class);
this.context = new AnnotationConfigApplicationContext(
DefaultDataSourceConfiguration.class);
DataSource dataSource = this.context.getBean(DataSource.class);
TaskExecutionDaoFactoryBean factoryBean = new TaskExecutionDaoFactoryBean(dataSource, "foo_");
TaskExecutionDaoFactoryBean factoryBean = new TaskExecutionDaoFactoryBean(
dataSource, "foo_");
TaskExecutionDao taskExecutionDao = factoryBean.getObject();
assertEquals("foo_", ReflectionTestUtils.getField(taskExecutionDao, "tablePrefix"));
assertThat(ReflectionTestUtils.getField(taskExecutionDao, "tablePrefix"))
.isEqualTo("foo_");
}
@Configuration
@@ -110,8 +114,11 @@ public class TaskExecutionDaoFactoryBeanTests {
@Bean
public DataSource dataSource() {
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2);
EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2);
return builder.build();
}
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -32,34 +32,35 @@ public class TaskExecutionCreator {
/**
* Creates a sample TaskExecution and stores it in the taskRepository.
*
* @param taskRepository the taskRepository where the taskExecution should be stored.
* @return the taskExecution created.
*/
public static TaskExecution createAndStoreEmptyTaskExecution(TaskRepository taskRepository) {
public static TaskExecution createAndStoreEmptyTaskExecution(
TaskRepository taskRepository) {
return taskRepository.createTaskExecution();
}
/**
* Creates a sample TaskExecution and stores it in the taskRepository.
*
* @param taskRepository the taskRepository where the taskExecution should be stored.
* @return the taskExecution created.
*/
public static TaskExecution createAndStoreTaskExecutionNoParams(TaskRepository taskRepository) {
public static TaskExecution createAndStoreTaskExecutionNoParams(
TaskRepository taskRepository) {
TaskExecution expectedTaskExecution = taskRepository.createTaskExecution();
return expectedTaskExecution;
}
/**
* Creates a sample TaskExecution and stores it in the taskRepository with params.
*
* @param taskRepository the taskRepository where the taskExecution should be stored.
* @return the taskExecution created.
*/
public static TaskExecution createAndStoreTaskExecutionWithParams(TaskRepository taskRepository) {
TaskExecution expectedTaskExecution = TestVerifierUtils.createSampleTaskExecutionNoArg();
List<String> params = new ArrayList<String>();
public static TaskExecution createAndStoreTaskExecutionWithParams(
TaskRepository taskRepository) {
TaskExecution expectedTaskExecution = TestVerifierUtils
.createSampleTaskExecutionNoArg();
List<String> params = new ArrayList<>();
params.add(UUID.randomUUID().toString());
params.add(UUID.randomUUID().toString());
expectedTaskExecution.setArguments(params);
@@ -69,14 +70,16 @@ public class TaskExecutionCreator {
/**
* Updates a sample TaskExecution in the taskRepository.
*
* @param taskRepository the taskRepository where the taskExecution should be updated.
* @return the taskExecution created.
*/
public static TaskExecution completeExecution(TaskRepository taskRepository,
TaskExecution expectedTaskExecution) {
return taskRepository.completeTaskExecution(expectedTaskExecution.getExecutionId(),
return taskRepository.completeTaskExecution(
expectedTaskExecution.getExecutionId(),
expectedTaskExecution.getExitCode(), expectedTaskExecution.getEndTime(),
expectedTaskExecution.getExitMessage(), expectedTaskExecution.getErrorMessage());
expectedTaskExecution.getExitMessage(),
expectedTaskExecution.getErrorMessage());
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import javax.sql.DataSource;
import org.springframework.batch.item.database.Order;
@@ -40,7 +41,7 @@ import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.jdbc.support.incrementer.DataFieldMaxValueIncrementer;
import org.springframework.util.StringUtils;
import static org.junit.Assert.assertEquals;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
@@ -60,28 +61,29 @@ public class TestDBUtils {
* @return taskExecution retrieved from the database.
*/
public static TaskExecution getTaskExecutionFromDB(DataSource dataSource,
long taskExecutionId) {
String sql = "SELECT * FROM TASK_EXECUTION WHERE "
+ "TASK_EXECUTION_ID = '"
long taskExecutionId) {
String sql = "SELECT * FROM TASK_EXECUTION WHERE " + "TASK_EXECUTION_ID = '"
+ taskExecutionId + "'";
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
List<TaskExecution> rows = jdbcTemplate.query(sql, new RowMapper<TaskExecution>(){
@Override
public TaskExecution mapRow(ResultSet rs, int rownumber) throws SQLException {
TaskExecution taskExecution=new TaskExecution(rs.getLong("TASK_EXECUTION_ID"),
StringUtils.hasText(rs.getString("EXIT_CODE")) ? Integer.valueOf(rs.getString("EXIT_CODE")) : null,
rs.getString("TASK_NAME"),
rs.getTimestamp("START_TIME"),
rs.getTimestamp("END_TIME"),
rs.getString("EXIT_MESSAGE"),
new ArrayList<String>(0),
rs.getString("ERROR_MESSAGE"),
rs.getString("EXTERNAL_EXECUTION_ID"));
return taskExecution;
}
});
assertEquals("only one row should be returned", 1, rows.size());
List<TaskExecution> rows = jdbcTemplate.query(sql,
new RowMapper<TaskExecution>() {
@Override
public TaskExecution mapRow(ResultSet rs, int rownumber)
throws SQLException {
TaskExecution taskExecution = new TaskExecution(
rs.getLong("TASK_EXECUTION_ID"),
StringUtils.hasText(rs.getString("EXIT_CODE"))
? Integer.valueOf(rs.getString("EXIT_CODE"))
: null,
rs.getString("TASK_NAME"), rs.getTimestamp("START_TIME"),
rs.getTimestamp("END_TIME"), rs.getString("EXIT_MESSAGE"),
new ArrayList<>(0), rs.getString("ERROR_MESSAGE"),
rs.getString("EXTERNAL_EXECUTION_ID"));
return taskExecution;
}
});
assertThat(rows.size()).as("only one row should be returned").isEqualTo(1);
TaskExecution taskExecution = rows.get(0);
populateParamsToDB(dataSource, taskExecution);
@@ -92,21 +94,23 @@ public class TestDBUtils {
* Create a pagingQueryProvider specific database type with a findAll.
* @param databaseProductName of the database.
* @return a PagingQueryPovider that will return all the requested information.
* @throws Exception
* @throws Exception exception
*/
public static PagingQueryProvider getPagingQueryProvider(String databaseProductName) throws Exception{
public static PagingQueryProvider getPagingQueryProvider(String databaseProductName)
throws Exception {
return getPagingQueryProvider(databaseProductName, null);
}
/**
* Create a pagingQueryProvider specific database type with a query containing a where clause.
* Create a pagingQueryProvider specific database type with a query containing a where
* clause.
* @param databaseProductName of the database.
* @param whereClause to be applied to the query.
* @param whereClause to be applied to the query.
* @return a PagingQueryProvider that will return the requested information.
* @throws Exception
* @throws Exception exception
*/
public static PagingQueryProvider getPagingQueryProvider(String databaseProductName,
String whereClause) throws Exception{
String whereClause) throws Exception {
DataSource dataSource = getMockDataSource(databaseProductName);
Map<String, Order> orderMap = new TreeMap<>();
orderMap.put("START_TIME", Order.DESCENDING);
@@ -114,7 +118,7 @@ public class TestDBUtils {
SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean();
factoryBean.setSelectClause(JdbcTaskExecutionDao.SELECT_CLAUSE);
factoryBean.setFromClause(JdbcTaskExecutionDao.FROM_CLAUSE);
if(whereClause != null){
if (whereClause != null) {
factoryBean.setWhereClause(whereClause);
}
factoryBean.setSortKeys(orderMap);
@@ -134,9 +138,10 @@ public class TestDBUtils {
* Creates a mock DataSource for use in testing.
* @param databaseProductName the name of the database type to mock.
* @return a mock DataSource.
* @throws Exception
* @throws Exception exception
*/
public static DataSource getMockDataSource(String databaseProductName) throws Exception {
public static DataSource getMockDataSource(String databaseProductName)
throws Exception {
DatabaseMetaData dmd = mock(DatabaseMetaData.class);
DataSource ds = mock(DataSource.class);
Connection con = mock(Connection.class);
@@ -148,12 +153,13 @@ public class TestDBUtils {
/**
* Creates a incrementer for the DataSource.
* @param dataSource the datasource that the incrementer will use to record current id.
* @param dataSource the datasource that the incrementer will use to record current
* id.
* @return a DataFieldMaxValueIncrementer object.
*/
public static DataFieldMaxValueIncrementer getIncrementer(DataSource dataSource){
DataFieldMaxValueIncrementerFactory incrementerFactory =
new DefaultDataFieldMaxValueIncrementerFactory(dataSource);
public static DataFieldMaxValueIncrementer getIncrementer(DataSource dataSource) {
DataFieldMaxValueIncrementerFactory incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(
dataSource);
String databaseType = null;
try {
databaseType = DatabaseType.fromMetaData(dataSource).name();
@@ -161,11 +167,11 @@ public class TestDBUtils {
catch (MetaDataAccessException e) {
throw new IllegalStateException(e);
}
return incrementerFactory.getIncrementer(databaseType,
"TASK_SEQ");
return incrementerFactory.getIncrementer(databaseType, "TASK_SEQ");
}
private static void populateParamsToDB(DataSource dataSource, TaskExecution taskExecution) {
private static void populateParamsToDB(DataSource dataSource,
TaskExecution taskExecution) {
String sql = "SELECT * FROM TASK_EXECUTION_PARAMS WHERE TASK_EXECUTION_ID = '"
+ taskExecution.getExecutionId() + "'";
@@ -177,4 +183,5 @@ public class TestDBUtils {
}
taskExecution.setArguments(arguments);
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -46,11 +46,11 @@ import org.springframework.context.annotation.Configuration;
@EnableConfigurationProperties(TaskProperties.class)
public class TestDefaultConfiguration implements InitializingBean {
private TaskExecutionDaoFactoryBean factoryBean;
@Autowired
TaskProperties taskProperties;
private TaskExecutionDaoFactoryBean factoryBean;
@Autowired(required = false)
private ApplicationArguments applicationArguments;
@@ -61,7 +61,7 @@ public class TestDefaultConfiguration implements InitializingBean {
}
@Bean
public TaskRepository taskRepository(){
public TaskRepository taskRepository() {
return new SimpleTaskRepository(this.factoryBean);
}
@@ -76,19 +76,21 @@ public class TestDefaultConfiguration implements InitializingBean {
}
@Bean
public TaskListenerExecutorObjectFactory taskListenerExecutorObjectProvider(ConfigurableApplicationContext context) {
public TaskListenerExecutorObjectFactory taskListenerExecutorObjectProvider(
ConfigurableApplicationContext context) {
return new TaskListenerExecutorObjectFactory(context);
}
@Bean
public TaskLifecycleListener taskHandler(TaskExplorer taskExplorer){
public TaskLifecycleListener taskHandler(TaskExplorer taskExplorer) {
return new TaskLifecycleListener(taskRepository(), taskNameResolver(),
applicationArguments, taskExplorer, taskProperties, taskListenerExecutorObjectProvider(context));
this.applicationArguments, taskExplorer, this.taskProperties,
taskListenerExecutorObjectProvider(this.context));
}
@Override
public void afterPropertiesSet() throws Exception {
if(this.context.getBeanNamesForType(DataSource.class).length == 1){
if (this.context.getBeanNamesForType(DataSource.class).length == 1) {
DataSource dataSource = this.context.getBean(DataSource.class);
this.factoryBean = new TaskExecutionDaoFactoryBean(dataSource);
}
@@ -96,4 +98,5 @@ public class TestDefaultConfiguration implements InitializingBean {
this.factoryBean = new TaskExecutionDaoFactoryBean();
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016 the original author or authors.
* Copyright 2015-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,20 +19,26 @@ package org.springframework.cloud.task.util;
import org.springframework.cloud.task.repository.TaskExecution;
/**
* Provides the basic infrastructure for evaluating if task listener performed
* properly.
* Provides the basic infrastructure for evaluating if task listener performed properly.
*
* @author Glenn Renfro
*/
public abstract class TestListener {
public static final String START_MESSAGE = "FOO";
public static final String ERROR_MESSAGE = "BAR";
public static final String END_MESSAGE = "BAZ";
protected boolean isTaskStartup;
protected boolean isTaskEnd;
protected boolean isTaskFailed;
protected TaskExecution taskExecution;
protected Throwable throwable;
/**
@@ -40,15 +46,15 @@ public abstract class TestListener {
* @return true if task listener was called during task creation, else false.
*/
public boolean isTaskStartup() {
return isTaskStartup;
return this.isTaskStartup;
}
/**
* Indicates if the task listener was called during task end.
* @return true if the task listener was called during task end, else false.
* @return true if the task listener was called during task end, else false.
*/
public boolean isTaskEnd() {
return isTaskEnd;
return this.isTaskEnd;
}
/**
@@ -56,20 +62,21 @@ public abstract class TestListener {
* @return true if task listener was called during task failure, else false.
*/
public boolean isTaskFailed() {
return isTaskFailed;
return this.isTaskFailed;
}
/**
* Task Execution that was updated during listener call.
*/
public TaskExecution getTaskExecution() {
return taskExecution;
return this.taskExecution;
}
/**
* The throwable that was sent with the task if task failed.
*/
public Throwable getThrowable() {
return throwable;
return this.throwable;
}
}

View File

@@ -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");
* you may not use this file except in compliance with the License.
@@ -31,17 +31,14 @@ import org.slf4j.LoggerFactory;
import org.springframework.cloud.task.repository.TaskExecution;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Matchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
/**
* Offers utils to test the results produced by the code being tested.
* Offers utils to test the results produced by the code being tested.
*
* @author Glenn Renfro
*/
@@ -51,11 +48,11 @@ public class TestVerifierUtils {
/**
* Creates a mock {@link Appender} to be added to the root logger.
*
* @return reference to the mock appender.
*/
public static Appender getMockAppender() {
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory
.getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
final Appender mockAppender = mock(Appender.class);
when(mockAppender.getName()).thenReturn("MOCK");
root.addAppender(mockAppender);
@@ -63,24 +60,24 @@ public class TestVerifierUtils {
}
/**
* Verifies that the log sample is contained within the content that was written
* to the mock appender.
*
* Verifies that the log sample is contained within the content that was written to
* the mock appender.
* @param mockAppender The appender that is associated with the test.
* @param logSample The string to search for in the log entry.
* @param logSample The string to search for in the log entry.
*/
public static void verifyLogEntryExists(Appender mockAppender, final String logSample) {
public static void verifyLogEntryExists(Appender mockAppender,
final String logSample) {
verify(mockAppender).doAppend(argThat(new ArgumentMatcher() {
@Override
public boolean matches(final Object argument) {
return ((LoggingEvent) argument).getFormattedMessage().contains(logSample);
return ((LoggingEvent) argument).getFormattedMessage()
.contains(logSample);
}
}));
}
/**
* Creates a fully populated TaskExecution (except args) for testing.
*
* @return
*/
public static TaskExecution createSampleTaskExecutionNoArg() {
@@ -89,13 +86,12 @@ public class TestVerifierUtils {
long executionId = randomGenerator.nextLong();
String taskName = UUID.randomUUID().toString();
return new TaskExecution(executionId, null, taskName,
startTime, null, null, new ArrayList<String>(), null, null);
return new TaskExecution(executionId, null, taskName, startTime, null, null,
new ArrayList<>(), null, null);
}
/**
* Creates a fully populated TaskExecution (except args) for testing.
*
* @return
*/
public static TaskExecution endSampleTaskExecutionNoArg() {
@@ -107,13 +103,12 @@ public class TestVerifierUtils {
String taskName = UUID.randomUUID().toString();
String exitMessage = UUID.randomUUID().toString();
return new TaskExecution(executionId, exitCode, taskName,
startTime, endTime, exitMessage, new ArrayList<String>(), null, null);
return new TaskExecution(executionId, exitCode, taskName, startTime, endTime,
exitMessage, new ArrayList<>(), null, null);
}
/**
* Creates a fully populated TaskExecution for testing.
*
* @return
*/
public static TaskExecution createSampleTaskExecution(long executionId) {
@@ -121,66 +116,65 @@ public class TestVerifierUtils {
String taskName = UUID.randomUUID().toString();
String externalExecutionId = UUID.randomUUID().toString();
List<String> args = new ArrayList<>(ARG_SIZE);
for (int i = 0; i < ARG_SIZE; i++){
for (int i = 0; i < ARG_SIZE; i++) {
args.add(UUID.randomUUID().toString());
}
return new TaskExecution(executionId, null, taskName,
startTime, null, null, args, null, externalExecutionId);
return new TaskExecution(executionId, null, taskName, startTime, null, null, args,
null, externalExecutionId);
}
/**
* Verifies that all the fields in between the expected and actual are the same;
*
* @param expectedTaskExecution The expected value for the task execution.
* @param actualTaskExecution The actual value for the task execution.
* @param actualTaskExecution The actual value for the task execution.
*/
public static void verifyTaskExecution(TaskExecution expectedTaskExecution,
TaskExecution actualTaskExecution) {
assertEquals("taskExecutionId must be equal", expectedTaskExecution.getExecutionId(),
actualTaskExecution.getExecutionId());
assertEquals("startTime must be equal",
expectedTaskExecution.getStartTime(),
actualTaskExecution.getStartTime());
assertEquals("endTime must be equal",
expectedTaskExecution.getEndTime(),
actualTaskExecution.getEndTime());
assertEquals("exitCode must be equal",
expectedTaskExecution.getExitCode(),
actualTaskExecution.getExitCode());
assertEquals("taskName must be equal",
expectedTaskExecution.getTaskName(),
actualTaskExecution.getTaskName());
assertEquals("exitMessage must be equal",
expectedTaskExecution.getExitMessage(),
actualTaskExecution.getExitMessage());
assertEquals("errorMessage must be equal",
expectedTaskExecution.getErrorMessage(),
actualTaskExecution.getErrorMessage());
assertEquals("externalExecutionId must be equal",
expectedTaskExecution.getExternalExecutionId(),
actualTaskExecution.getExternalExecutionId());
assertEquals("parentExecutionId must be equal",
expectedTaskExecution.getParentExecutionId(),
actualTaskExecution.getParentExecutionId());
TaskExecution actualTaskExecution) {
assertThat(actualTaskExecution.getExecutionId())
.as("taskExecutionId must be equal")
.isEqualTo(expectedTaskExecution.getExecutionId());
if (actualTaskExecution.getStartTime() != null) {
assertThat(actualTaskExecution.getStartTime()).as("startTime must be equal")
.hasSameTimeAs(expectedTaskExecution.getStartTime());
}
if (actualTaskExecution.getEndTime() != null) {
assertThat(actualTaskExecution.getEndTime()).as("endTime must be equal")
.hasSameTimeAs(expectedTaskExecution.getEndTime());
}
assertThat(actualTaskExecution.getExitCode()).as("exitCode must be equal")
.isEqualTo(expectedTaskExecution.getExitCode());
assertThat(actualTaskExecution.getTaskName()).as("taskName must be equal")
.isEqualTo(expectedTaskExecution.getTaskName());
assertThat(actualTaskExecution.getExitMessage()).as("exitMessage must be equal")
.isEqualTo(expectedTaskExecution.getExitMessage());
assertThat(actualTaskExecution.getErrorMessage()).as("errorMessage must be equal")
.isEqualTo(expectedTaskExecution.getErrorMessage());
assertThat(actualTaskExecution.getExternalExecutionId())
.as("externalExecutionId must be equal")
.isEqualTo(expectedTaskExecution.getExternalExecutionId());
assertThat(actualTaskExecution.getParentExecutionId())
.as("parentExecutionId must be equal")
.isEqualTo(expectedTaskExecution.getParentExecutionId());
if (expectedTaskExecution.getArguments() != null) {
assertNotNull("arguments should not be null",
actualTaskExecution.getArguments());
assertEquals("arguments result set count should match expected count",
expectedTaskExecution.getArguments().size(),
actualTaskExecution.getArguments().size());
assertThat(actualTaskExecution.getArguments())
.as("arguments should not be null").isNotNull();
assertThat(actualTaskExecution.getArguments().size())
.as("arguments result set count should match expected count")
.isEqualTo(expectedTaskExecution.getArguments().size());
}
else {
assertNull("arguments should be null", actualTaskExecution.getArguments());
assertThat(actualTaskExecution.getArguments()).as("arguments should be null")
.isNull();
}
Set<String> args = new HashSet<String>();
Set<String> args = new HashSet<>();
for (String param : expectedTaskExecution.getArguments()) {
args.add(param);
}
for (String arg : actualTaskExecution.getArguments()) {
assertTrue("arg must exist in the repository", args.contains(arg));
assertThat(args.contains(arg)).as("arg must exist in the repository")
.isTrue();
}
}
}