Updated to files to fit the Standard.
This commit is contained in:
@@ -96,16 +96,14 @@ public class DefaultTaskConfigurer implements TaskConfigurer {
|
||||
* 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);
|
||||
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean(this.dataSource, tablePrefix);
|
||||
}
|
||||
else {
|
||||
taskExecutionDaoFactoryBean = new TaskExecutionDaoFactoryBean();
|
||||
@@ -136,27 +134,22 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,13 +55,12 @@ import org.springframework.util.CollectionUtils;
|
||||
@EnableTransactionManagement
|
||||
@EnableConfigurationProperties({ TaskProperties.class })
|
||||
// @checkstyle:off
|
||||
@ConditionalOnProperty(prefix = "spring.cloud.task.autoconfiguration", name = "enabled",
|
||||
havingValue = "true", matchIfMissing = true)
|
||||
@ConditionalOnProperty(prefix = "spring.cloud.task.autoconfiguration", name = "enabled", havingValue = "true",
|
||||
matchIfMissing = true)
|
||||
// @checkstyle:on
|
||||
public class SimpleTaskAutoConfiguration {
|
||||
|
||||
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;
|
||||
@@ -85,7 +84,6 @@ public class SimpleTaskAutoConfiguration {
|
||||
return this.taskRepository;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
public PlatformTransactionManager springCloudTaskTransactionManager() {
|
||||
return this.platformTransactionManager;
|
||||
@@ -104,8 +102,7 @@ public class SimpleTaskAutoConfiguration {
|
||||
@Bean
|
||||
@Lazy(false)
|
||||
public TaskRepositoryInitializer taskRepositoryInitializer() {
|
||||
TaskRepositoryInitializer taskRepositoryInitializer = new TaskRepositoryInitializer(
|
||||
this.taskProperties);
|
||||
TaskRepositoryInitializer taskRepositoryInitializer = new TaskRepositoryInitializer(this.taskProperties);
|
||||
DataSource initializerDataSource = getDefaultConfigurer().getTaskDataSource();
|
||||
if (initializerDataSource != null) {
|
||||
taskRepositoryInitializer.setDataSource(initializerDataSource);
|
||||
@@ -114,7 +111,6 @@ public class SimpleTaskAutoConfiguration {
|
||||
return taskRepositoryInitializer;
|
||||
}
|
||||
|
||||
|
||||
@Bean
|
||||
@Profile("cloud")
|
||||
TaskObservationCloudKeyValues taskObservationCloudKeyValues() {
|
||||
@@ -132,8 +128,7 @@ public class SimpleTaskAutoConfiguration {
|
||||
|
||||
TaskConfigurer taskConfigurer = getDefaultConfigurer();
|
||||
|
||||
logger.debug(String.format("Using %s TaskConfigurer",
|
||||
taskConfigurer.getClass().getName()));
|
||||
logger.debug(String.format("Using %s TaskConfigurer", taskConfigurer.getClass().getName()));
|
||||
|
||||
this.taskRepository = taskConfigurer.getTaskRepository();
|
||||
this.platformTransactionManager = taskConfigurer.getTransactionManager();
|
||||
@@ -148,18 +143,14 @@ public class SimpleTaskAutoConfiguration {
|
||||
|
||||
if (configurers < 1) {
|
||||
TaskConfigurer taskConfigurer;
|
||||
if (!CollectionUtils.isEmpty(this.dataSources)
|
||||
&& this.dataSources.size() == 1) {
|
||||
taskConfigurer = new DefaultTaskConfigurer(
|
||||
this.dataSources.iterator().next(),
|
||||
if (!CollectionUtils.isEmpty(this.dataSources) && this.dataSources.size() == 1) {
|
||||
taskConfigurer = new DefaultTaskConfigurer(this.dataSources.iterator().next(),
|
||||
this.taskProperties.getTablePrefix(), this.context);
|
||||
}
|
||||
else {
|
||||
taskConfigurer = new DefaultTaskConfigurer(
|
||||
this.taskProperties.getTablePrefix());
|
||||
taskConfigurer = new DefaultTaskConfigurer(this.taskProperties.getTablePrefix());
|
||||
}
|
||||
this.context.getBeanFactory().registerSingleton("taskConfigurer",
|
||||
taskConfigurer);
|
||||
this.context.getBeanFactory().registerSingleton("taskConfigurer", taskConfigurer);
|
||||
return taskConfigurer;
|
||||
}
|
||||
else {
|
||||
@@ -167,8 +158,7 @@ public class SimpleTaskAutoConfiguration {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,14 +167,12 @@ public class SimpleTaskAutoConfiguration {
|
||||
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))
|
||||
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);
|
||||
throw new IllegalStateException("To use the default TaskConfigurer the context must contain no more than"
|
||||
+ " one DataSource, found " + dataSources);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,29 +73,27 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
||||
|
||||
private PlatformTransactionManager platformTransactionManager;
|
||||
|
||||
public SingleInstanceTaskListener(LockRegistry lockRegistry,
|
||||
TaskNameResolver taskNameResolver, TaskProperties taskProperties,
|
||||
ApplicationEventPublisher applicationEventPublisher,
|
||||
public SingleInstanceTaskListener(LockRegistry lockRegistry, TaskNameResolver taskNameResolver,
|
||||
TaskProperties taskProperties, ApplicationEventPublisher applicationEventPublisher,
|
||||
ApplicationContext applicationContext) {
|
||||
this.lockRegistry = lockRegistry;
|
||||
this.taskNameResolver = taskNameResolver;
|
||||
this.taskProperties = taskProperties;
|
||||
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
|
||||
this.lockRegistry);
|
||||
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(this.lockRegistry);
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public SingleInstanceTaskListener(DataSource dataSource,
|
||||
TaskNameResolver taskNameResolver, TaskProperties taskProperties,
|
||||
ApplicationEventPublisher applicationEventPublisher,
|
||||
public SingleInstanceTaskListener(DataSource dataSource, TaskNameResolver taskNameResolver,
|
||||
TaskProperties taskProperties, ApplicationEventPublisher applicationEventPublisher,
|
||||
ApplicationContext applicationContext) {
|
||||
this.taskNameResolver = taskNameResolver;
|
||||
this.applicationEventPublisher = applicationEventPublisher;
|
||||
this.dataSource = dataSource;
|
||||
this.taskProperties = taskProperties;
|
||||
this.applicationContext = applicationContext;
|
||||
this.platformTransactionManager = this.applicationContext.getBean("springCloudTaskTransactionManager", PlatformTransactionManager.class);
|
||||
this.platformTransactionManager = this.applicationContext.getBean("springCloudTaskTransactionManager",
|
||||
PlatformTransactionManager.class);
|
||||
}
|
||||
|
||||
@BeforeTask
|
||||
@@ -103,12 +101,9 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
||||
if (this.lockRegistry == null) {
|
||||
this.lockRegistry = getDefaultLockRegistry(taskExecution.getExecutionId());
|
||||
}
|
||||
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(
|
||||
this.lockRegistry,
|
||||
new DefaultCandidate(String.valueOf(taskExecution.getExecutionId()),
|
||||
this.taskNameResolver.getTaskName()));
|
||||
this.lockRegistryLeaderInitiator
|
||||
.setApplicationEventPublisher(this.applicationEventPublisher);
|
||||
this.lockRegistryLeaderInitiator = new LockRegistryLeaderInitiator(this.lockRegistry, new DefaultCandidate(
|
||||
String.valueOf(taskExecution.getExecutionId()), this.taskNameResolver.getTaskName()));
|
||||
this.lockRegistryLeaderInitiator.setApplicationEventPublisher(this.applicationEventPublisher);
|
||||
this.lockRegistryLeaderInitiator.setPublishFailedEvents(true);
|
||||
this.lockRegistryLeaderInitiator.start();
|
||||
while (!this.lockReady) {
|
||||
@@ -119,15 +114,13 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
||||
logger.warn("Thread Sleep Failed", ex);
|
||||
}
|
||||
if (this.lockFailed) {
|
||||
String errorMessage = String.format(
|
||||
"Task with name \"%s\" is already running.",
|
||||
String errorMessage = String.format("Task with name \"%s\" is already running.",
|
||||
this.taskNameResolver.getTaskName());
|
||||
try {
|
||||
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);
|
||||
}
|
||||
@@ -140,8 +133,7 @@ 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();
|
||||
}
|
||||
|
||||
@@ -156,8 +148,7 @@ public class SingleInstanceTaskListener implements ApplicationListener<Applicati
|
||||
}
|
||||
|
||||
private LockRegistry getDefaultLockRegistry(long executionId) {
|
||||
DefaultLockRepository lockRepository = new DefaultLockRepository(this.dataSource,
|
||||
String.valueOf(executionId));
|
||||
DefaultLockRepository lockRepository = new DefaultLockRepository(this.dataSource, String.valueOf(executionId));
|
||||
lockRepository.setPrefix(this.taskProperties.getTablePrefix());
|
||||
lockRepository.setTimeToLive(this.taskProperties.getSingleInstanceLockTtl());
|
||||
lockRepository.setApplicationContext(this.applicationContext);
|
||||
|
||||
@@ -36,8 +36,7 @@ import org.springframework.integration.support.locks.PassThruLockRegistry;
|
||||
|
||||
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnProperty(prefix = "spring.cloud.task", name = "single-instance-enabled",
|
||||
havingValue = "true")
|
||||
@ConditionalOnProperty(prefix = "spring.cloud.task", name = "single-instance-enabled", havingValue = "true")
|
||||
public class SingleTaskConfiguration {
|
||||
|
||||
@Autowired
|
||||
@@ -52,12 +51,12 @@ public class SingleTaskConfiguration {
|
||||
@Bean
|
||||
public SingleInstanceTaskListener taskListener(TaskNameResolver resolver, ApplicationContext applicationContext) {
|
||||
if (this.taskConfigurer.getTaskDataSource() == null) {
|
||||
return new SingleInstanceTaskListener(new PassThruLockRegistry(), resolver,
|
||||
this.taskProperties, this.applicationEventPublisher, applicationContext);
|
||||
return new SingleInstanceTaskListener(new PassThruLockRegistry(), resolver, this.taskProperties,
|
||||
this.applicationEventPublisher, applicationContext);
|
||||
}
|
||||
|
||||
return new SingleInstanceTaskListener(this.taskConfigurer.getTaskDataSource(),
|
||||
resolver, this.taskProperties, this.applicationEventPublisher, applicationContext);
|
||||
return new SingleInstanceTaskListener(this.taskConfigurer.getTaskDataSource(), resolver, this.taskProperties,
|
||||
this.applicationEventPublisher, applicationContext);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -43,8 +43,7 @@ import org.springframework.context.annotation.Configuration;
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public class TaskLifecycleConfiguration {
|
||||
|
||||
protected static final Log logger = LogFactory
|
||||
.getLog(TaskLifecycleConfiguration.class);
|
||||
protected static final Log logger = LogFactory.getLog(TaskLifecycleConfiguration.class);
|
||||
|
||||
private TaskProperties taskProperties;
|
||||
|
||||
@@ -67,12 +66,11 @@ public class TaskLifecycleConfiguration {
|
||||
private TaskObservationCloudKeyValues taskObservationCloudKeyValues;
|
||||
|
||||
@Autowired
|
||||
public TaskLifecycleConfiguration(TaskProperties taskProperties,
|
||||
ConfigurableApplicationContext context, TaskRepository taskRepository,
|
||||
TaskExplorer taskExplorer, TaskNameResolver taskNameResolver,
|
||||
ObjectProvider<ApplicationArguments> applicationArguments,
|
||||
@Autowired(required = false) ObservationRegistry observationRegistry,
|
||||
@Autowired(required = false) TaskObservationCloudKeyValues taskObservationCloudKeyValues) {
|
||||
public TaskLifecycleConfiguration(TaskProperties taskProperties, ConfigurableApplicationContext context,
|
||||
TaskRepository taskRepository, TaskExplorer taskExplorer, TaskNameResolver taskNameResolver,
|
||||
ObjectProvider<ApplicationArguments> applicationArguments,
|
||||
@Autowired(required = false) ObservationRegistry observationRegistry,
|
||||
@Autowired(required = false) TaskObservationCloudKeyValues taskObservationCloudKeyValues) {
|
||||
|
||||
this.taskProperties = taskProperties;
|
||||
this.context = context;
|
||||
@@ -96,11 +94,10 @@ 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(this.context),
|
||||
this.observationRegistry, taskObservationCloudKeyValues);
|
||||
this.taskLifecycleListener = new TaskLifecycleListener(this.taskRepository, this.taskNameResolver,
|
||||
this.applicationArguments, this.taskExplorer, this.taskProperties,
|
||||
new TaskListenerExecutorObjectFactory(this.context), this.observationRegistry,
|
||||
taskObservationCloudKeyValues);
|
||||
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
@@ -103,4 +103,5 @@ public class TaskObservationCloudKeyValues {
|
||||
public void setInstanceIndex(String instanceIndex) {
|
||||
this.instanceIndex = instanceIndex;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -36,4 +36,5 @@ public class DefaultTaskObservationConvention implements TaskObservationConventi
|
||||
public String getName() {
|
||||
return "spring.cloud.task.runner";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,8 +51,9 @@ class ObservationApplicationRunner implements ApplicationRunner {
|
||||
@Override
|
||||
public void run(ApplicationArguments args) throws Exception {
|
||||
TaskObservationContext context = new TaskObservationContext(this.beanName);
|
||||
Observation observation = TaskDocumentedObservation.TASK_RUNNER_OBSERVATION.observation(this.taskObservationConvention, INSTANCE, context, registry())
|
||||
.contextualName(this.beanName);
|
||||
Observation observation = TaskDocumentedObservation.TASK_RUNNER_OBSERVATION
|
||||
.observation(this.taskObservationConvention, INSTANCE, context, registry())
|
||||
.contextualName(this.beanName);
|
||||
|
||||
try (Observation.Scope scope = observation.start().openScope()) {
|
||||
this.delegate.run(args);
|
||||
|
||||
@@ -50,8 +50,9 @@ class ObservationCommandLineRunner implements CommandLineRunner {
|
||||
@Override
|
||||
public void run(String... args) throws Exception {
|
||||
TaskObservationContext context = new TaskObservationContext(this.beanName);
|
||||
Observation observation = TaskDocumentedObservation.TASK_RUNNER_OBSERVATION.observation(this.taskObservationConvention, INSTANCE, context, registry())
|
||||
.contextualName(this.beanName);
|
||||
Observation observation = TaskDocumentedObservation.TASK_RUNNER_OBSERVATION
|
||||
.observation(this.taskObservationConvention, INSTANCE, context, registry())
|
||||
.contextualName(this.beanName);
|
||||
try (Observation.Scope scope = observation.start().openScope()) {
|
||||
this.delegate.run(args);
|
||||
}
|
||||
@@ -70,4 +71,5 @@ class ObservationCommandLineRunner implements CommandLineRunner {
|
||||
}
|
||||
return this.registry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,12 +39,14 @@ import org.springframework.context.annotation.Configuration;
|
||||
public class ObservationTaskAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
static ObservationCommandLineRunnerBeanPostProcessor observedCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) {
|
||||
static ObservationCommandLineRunnerBeanPostProcessor observedCommandLineRunnerBeanPostProcessor(
|
||||
BeanFactory beanFactory) {
|
||||
return new ObservationCommandLineRunnerBeanPostProcessor(beanFactory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
static ObservationApplicationRunnerBeanPostProcessor observedApplicationRunnerBeanPostProcessor(BeanFactory beanFactory) {
|
||||
static ObservationApplicationRunnerBeanPostProcessor observedApplicationRunnerBeanPostProcessor(
|
||||
BeanFactory beanFactory) {
|
||||
return new ObservationApplicationRunnerBeanPostProcessor(beanFactory);
|
||||
}
|
||||
|
||||
|
||||
@@ -57,5 +57,7 @@ enum TaskDocumentedObservation implements DocumentedObservation {
|
||||
return "spring.cloud.task.runner.bean-name";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -35,4 +35,5 @@ public class TaskObservationContext extends Observation.Context {
|
||||
public String getBeanName() {
|
||||
return beanName;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -30,4 +30,5 @@ public interface TaskObservationConvention extends Observation.ObservationConven
|
||||
default boolean supportsContext(Observation.Context context) {
|
||||
return context instanceof TaskObservationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,8 +21,7 @@ import io.micrometer.common.KeyValues;
|
||||
import org.springframework.cloud.task.repository.TaskExecution;
|
||||
|
||||
/**
|
||||
* /**
|
||||
* Default {@link TaskExecutionObservationConvention} implementation.
|
||||
* /** Default {@link TaskExecutionObservationConvention} implementation.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
* @since 3.0.0
|
||||
@@ -41,15 +40,16 @@ public class DefaultTaskExecutionObservationConvention implements TaskExecutionO
|
||||
|
||||
private KeyValues getKeyValuesForTaskExecution(TaskExecutionObservationContext context) {
|
||||
TaskExecution execution = context.getTaskExecution();
|
||||
return KeyValues.of(
|
||||
TaskExecutionObservation.TaskKeyValues.TASK_STATUS.getKeyName(), context.getStatus(),
|
||||
TaskExecutionObservation.TaskKeyValues.TASK_EXIT_CODE.getKeyName(), String.valueOf(execution.getExitCode()),
|
||||
TaskExecutionObservation.TaskKeyValues.TASK_EXECUTION_ID.getKeyName(),
|
||||
String.valueOf(execution.getExecutionId()));
|
||||
return KeyValues.of(TaskExecutionObservation.TaskKeyValues.TASK_STATUS.getKeyName(), context.getStatus(),
|
||||
TaskExecutionObservation.TaskKeyValues.TASK_EXIT_CODE.getKeyName(),
|
||||
String.valueOf(execution.getExitCode()),
|
||||
TaskExecutionObservation.TaskKeyValues.TASK_EXECUTION_ID.getKeyName(),
|
||||
String.valueOf(execution.getExecutionId()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "spring.cloud.task";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -22,7 +22,8 @@ package org.springframework.cloud.task.listener;
|
||||
*
|
||||
* @author Michael Minella
|
||||
* @since 1.2
|
||||
* @deprecated since 3.0 in favor of the default implementations of {@link TaskExecutionListener}
|
||||
* @deprecated since 3.0 in favor of the default implementations of
|
||||
* {@link TaskExecutionListener}
|
||||
*/
|
||||
@Deprecated
|
||||
public class TaskExecutionListenerSupport implements TaskExecutionListener {
|
||||
|
||||
@@ -27,6 +27,7 @@ import io.micrometer.observation.docs.DocumentedObservation;
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public enum TaskExecutionObservation implements DocumentedObservation {
|
||||
|
||||
/**
|
||||
* Metrics created around a task execution.
|
||||
*/
|
||||
@@ -41,6 +42,7 @@ public enum TaskExecutionObservation implements DocumentedObservation {
|
||||
return "spring.cloud.task";
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public KeyName[] getLowCardinalityKeyNames() {
|
||||
return TaskKeyValues.values();
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.cloud.task.repository.TaskExecution;
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public class TaskExecutionObservationContext extends Observation.Context {
|
||||
|
||||
private final TaskExecution taskExecution;
|
||||
|
||||
private String exceptionMessage = "none";
|
||||
@@ -57,4 +58,5 @@ public class TaskExecutionObservationContext extends Observation.Context {
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,10 +24,12 @@ import io.micrometer.observation.Observation;
|
||||
* @author Glenn Renfro
|
||||
* @since 3.0.0
|
||||
*/
|
||||
public interface TaskExecutionObservationConvention extends Observation.ObservationConvention<TaskExecutionObservationContext> {
|
||||
public interface TaskExecutionObservationConvention
|
||||
extends Observation.ObservationConvention<TaskExecutionObservationContext> {
|
||||
|
||||
@Override
|
||||
default boolean supportsContext(Observation.Context context) {
|
||||
return context instanceof TaskExecutionObservationContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@ import org.springframework.util.StringUtils;
|
||||
* @author Michael Minella
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class TaskLifecycleListener implements ApplicationListener<ApplicationEvent>,
|
||||
SmartLifecycle, DisposableBean, Ordered {
|
||||
public class TaskLifecycleListener
|
||||
implements ApplicationListener<ApplicationEvent>, SmartLifecycle, DisposableBean, Ordered {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(TaskLifecycleListener.class);
|
||||
|
||||
@@ -135,18 +135,16 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
* @param taskListenerExecutorObjectFactory {@link TaskListenerExecutorObjectFactory}
|
||||
* to initialize TaskListenerExecutor for a task
|
||||
*/
|
||||
public TaskLifecycleListener(TaskRepository taskRepository,
|
||||
TaskNameResolver taskNameResolver, ApplicationArguments applicationArguments,
|
||||
TaskExplorer taskExplorer, TaskProperties taskProperties,
|
||||
public TaskLifecycleListener(TaskRepository taskRepository, TaskNameResolver taskNameResolver,
|
||||
ApplicationArguments applicationArguments, TaskExplorer taskExplorer, TaskProperties taskProperties,
|
||||
TaskListenerExecutorObjectFactory taskListenerExecutorObjectFactory,
|
||||
@Autowired(required = false) ObservationRegistry observationRegistry,
|
||||
TaskObservationCloudKeyValues taskObservationCloudKeyValues) {
|
||||
@Autowired(required = false) ObservationRegistry observationRegistry,
|
||||
TaskObservationCloudKeyValues taskObservationCloudKeyValues) {
|
||||
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;
|
||||
@@ -155,7 +153,8 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
this.taskProperties = taskProperties;
|
||||
this.taskListenerExecutorObjectFactory = taskListenerExecutorObjectFactory;
|
||||
observationRegistry = observationRegistry == null ? ObservationRegistry.NOOP : observationRegistry;
|
||||
this.taskObservations = new TaskObservations(observationRegistry, taskObservationCloudKeyValues, observationConvention);
|
||||
this.taskObservations = new TaskObservations(observationRegistry, taskObservationCloudKeyValues,
|
||||
observationConvention);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,8 +169,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent applicationEvent) {
|
||||
if (applicationEvent instanceof ApplicationFailedEvent) {
|
||||
this.applicationFailedException = ((ApplicationFailedEvent) applicationEvent)
|
||||
.getException();
|
||||
this.applicationFailedException = ((ApplicationFailedEvent) applicationEvent).getException();
|
||||
doTaskEnd();
|
||||
}
|
||||
else if (applicationEvent instanceof ExitCodeEvent) {
|
||||
@@ -196,21 +194,18 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
this.taskExecution.setEndTime(new Date());
|
||||
|
||||
if (this.applicationFailedException != null) {
|
||||
this.taskExecution.setErrorMessage(
|
||||
stackTraceToString(this.applicationFailedException));
|
||||
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.taskExecution.getExitMessage(), this.taskExecution.getErrorMessage());
|
||||
|
||||
this.finished = true;
|
||||
|
||||
@@ -220,8 +215,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
|
||||
}
|
||||
else if (!this.started) {
|
||||
logger.error("An event to end a task has been received for a task that has "
|
||||
+ "not yet started.");
|
||||
logger.error("An event to end a task has been received for a task that has " + "not yet started.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,12 +234,10 @@ 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();
|
||||
}
|
||||
}
|
||||
@@ -268,11 +260,9 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
this.taskExecutionListeners = new ArrayList<>();
|
||||
this.taskListenerExecutorObjectFactory.getObject();
|
||||
if (!CollectionUtils.isEmpty(this.taskExecutionListenersFromContext)) {
|
||||
this.taskExecutionListeners
|
||||
.addAll(this.taskExecutionListenersFromContext);
|
||||
this.taskExecutionListeners.addAll(this.taskExecutionListenersFromContext);
|
||||
}
|
||||
this.taskExecutionListeners
|
||||
.add(this.taskListenerExecutorObjectFactory.getObject());
|
||||
this.taskExecutionListeners.add(this.taskListenerExecutorObjectFactory.getObject());
|
||||
|
||||
List<String> args = new ArrayList<>(0);
|
||||
|
||||
@@ -282,35 +272,27 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
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",
|
||||
Assert.notNull(taskExecution, String.format("Invalid TaskExecution, ID %s not found",
|
||||
this.taskProperties.getExecutionid()));
|
||||
this.taskExecution = this.taskRepository.startTaskExecution(
|
||||
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(),
|
||||
this.taskNameResolver.getTaskName(), new Date(), args,
|
||||
this.taskProperties.getExternalExecutionId(),
|
||||
this.taskProperties.getParentExecutionId());
|
||||
this.taskProperties.getExternalExecutionId(), this.taskProperties.getParentExecutionId());
|
||||
}
|
||||
else {
|
||||
TaskExecution taskExecution = new TaskExecution();
|
||||
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));
|
||||
@@ -326,8 +308,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
private TaskExecution invokeOnTaskStartup(TaskExecution taskExecution) {
|
||||
this.taskObservations.onTaskStartup(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);
|
||||
@@ -360,8 +341,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);
|
||||
@@ -371,8 +352,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
return listenerTaskExecution;
|
||||
}
|
||||
|
||||
private TaskExecution invokeOnTaskError(TaskExecution taskExecution,
|
||||
Throwable throwable) {
|
||||
private TaskExecution invokeOnTaskError(TaskExecution taskExecution, Throwable throwable) {
|
||||
if (this.taskObservations != null) {
|
||||
this.taskObservations.onTaskFailed(throwable);
|
||||
}
|
||||
@@ -388,8 +368,7 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
String errorMessage;
|
||||
if (StringUtils.hasText(listenerTaskExecution.getErrorMessage())) {
|
||||
errorMessage = String.format("%s :While handling " + "this error: %s",
|
||||
listenerException.getMessage(),
|
||||
listenerTaskExecution.getErrorMessage());
|
||||
listenerException.getMessage(), listenerTaskExecution.getErrorMessage());
|
||||
}
|
||||
else {
|
||||
errorMessage = listenerTaskExecution.getErrorMessage();
|
||||
@@ -405,14 +384,12 @@ public class TaskLifecycleListener implements ApplicationListener<ApplicationEve
|
||||
|
||||
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(),
|
||||
Collections.unmodifiableList(taskExecution.getArguments()),
|
||||
taskExecution.getErrorMessage(), taskExecution.getExternalExecutionId());
|
||||
return new TaskExecution(taskExecution.getExecutionId(), taskExecution.getExitCode(),
|
||||
taskExecution.getTaskName(), startTime, endTime, taskExecution.getExitMessage(),
|
||||
Collections.unmodifiableList(taskExecution.getArguments()), taskExecution.getErrorMessage(),
|
||||
taskExecution.getExternalExecutionId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -49,13 +49,11 @@ import org.springframework.core.annotation.AnnotationUtils;
|
||||
* @author Isik Erhan
|
||||
* @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;
|
||||
|
||||
@@ -75,8 +73,7 @@ public class TaskListenerExecutorObjectFactory
|
||||
this.afterTaskInstances = new HashMap<>();
|
||||
this.failedTaskInstances = new HashMap<>();
|
||||
initializeExecutor();
|
||||
return new TaskListenerExecutor(this.beforeTaskInstances, this.afterTaskInstances,
|
||||
this.failedTaskInstances);
|
||||
return new TaskListenerExecutor(this.beforeTaskInstances, this.afterTaskInstances, this.failedTaskInstances);
|
||||
}
|
||||
|
||||
private void initializeExecutor() {
|
||||
@@ -92,8 +89,7 @@ public class TaskListenerExecutorObjectFactory
|
||||
// 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) {
|
||||
@@ -105,10 +101,7 @@ public class TaskListenerExecutorObjectFactory
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,9 +110,7 @@ public class TaskListenerExecutorObjectFactory
|
||||
}
|
||||
catch (RuntimeException ex) {
|
||||
throw new BeanInitializationException(
|
||||
"Failed to process @BeforeTask "
|
||||
+ "annotation on bean with name '" + beanName
|
||||
+ "'",
|
||||
"Failed to process @BeforeTask " + "annotation on bean with name '" + beanName + "'",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
@@ -130,12 +121,11 @@ public class TaskListenerExecutorObjectFactory
|
||||
|
||||
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);
|
||||
@@ -143,22 +133,19 @@ public class TaskListenerExecutorObjectFactory
|
||||
}
|
||||
if (!beforeTaskMethods.isEmpty()) {
|
||||
for (Method beforeTaskMethod : beforeTaskMethods.keySet()) {
|
||||
this.beforeTaskInstances
|
||||
.computeIfAbsent(beforeTaskMethod, k -> new LinkedHashSet<>())
|
||||
this.beforeTaskInstances.computeIfAbsent(beforeTaskMethod, k -> new LinkedHashSet<>())
|
||||
.add(this.context.getBean(beanName));
|
||||
}
|
||||
}
|
||||
if (!afterTaskMethods.isEmpty()) {
|
||||
for (Method afterTaskMethod : afterTaskMethods.keySet()) {
|
||||
this.afterTaskInstances
|
||||
.computeIfAbsent(afterTaskMethod, k -> new LinkedHashSet<>())
|
||||
this.afterTaskInstances.computeIfAbsent(afterTaskMethod, k -> new LinkedHashSet<>())
|
||||
.add(this.context.getBean(beanName));
|
||||
}
|
||||
}
|
||||
if (!failedTaskMethods.isEmpty()) {
|
||||
for (Method failedTaskMethod : failedTaskMethods.keySet()) {
|
||||
this.failedTaskInstances
|
||||
.computeIfAbsent(failedTaskMethod, k -> new LinkedHashSet<>())
|
||||
this.failedTaskInstances.computeIfAbsent(failedTaskMethod, k -> new LinkedHashSet<>())
|
||||
.add(this.context.getBean(beanName));
|
||||
}
|
||||
}
|
||||
@@ -167,11 +154,10 @@ public class TaskListenerExecutorObjectFactory
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,8 +51,9 @@ public class TaskObservations {
|
||||
|
||||
private Observation.ObservationConvention customObservationConvention;
|
||||
|
||||
public TaskObservations(ObservationRegistry observationRegistry, TaskObservationCloudKeyValues taskObservationCloudKeyValues,
|
||||
Observation.ObservationConvention customObservationConvention) {
|
||||
public TaskObservations(ObservationRegistry observationRegistry,
|
||||
TaskObservationCloudKeyValues taskObservationCloudKeyValues,
|
||||
Observation.ObservationConvention customObservationConvention) {
|
||||
this.observationRegistry = observationRegistry;
|
||||
this.taskObservationCloudKeyValues = taskObservationCloudKeyValues;
|
||||
this.customObservationConvention = customObservationConvention;
|
||||
@@ -68,34 +69,38 @@ public class TaskObservations {
|
||||
|
||||
public void onTaskStartup(TaskExecution taskExecution) {
|
||||
|
||||
|
||||
this.taskObservationContext = new TaskExecutionObservationContext(taskExecution);
|
||||
|
||||
Observation observation = TaskExecutionObservation.TASK_ACTIVE.observation(this.customObservationConvention, new DefaultTaskExecutionObservationConvention(), this.taskObservationContext, this.observationRegistry)
|
||||
.contextualName(String.valueOf(taskExecution.getExecutionId()))
|
||||
.keyValuesProvider(this.observationsProvider)
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_NAME.getKeyName(), getValueOrDefault(taskExecution.getTaskName()))
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_EXECUTION_ID.getKeyName(), "" + taskExecution.getExecutionId())
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_PARENT_EXECUTION_ID.getKeyName(),
|
||||
(getValueOrDefault(taskExecution.getParentExecutionId())))
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_EXTERNAL_EXECUTION_ID.getKeyName(),
|
||||
(getValueOrDefault(taskExecution.getExternalExecutionId())));
|
||||
Observation observation = TaskExecutionObservation.TASK_ACTIVE
|
||||
.observation(this.customObservationConvention, new DefaultTaskExecutionObservationConvention(),
|
||||
this.taskObservationContext, this.observationRegistry)
|
||||
.contextualName(String.valueOf(taskExecution.getExecutionId()))
|
||||
.keyValuesProvider(this.observationsProvider)
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_NAME.getKeyName(),
|
||||
getValueOrDefault(taskExecution.getTaskName()))
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_EXECUTION_ID.getKeyName(),
|
||||
"" + taskExecution.getExecutionId())
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_PARENT_EXECUTION_ID.getKeyName(),
|
||||
(getValueOrDefault(taskExecution.getParentExecutionId())))
|
||||
.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_EXTERNAL_EXECUTION_ID.getKeyName(),
|
||||
(getValueOrDefault(taskExecution.getExternalExecutionId())));
|
||||
|
||||
if (taskObservationCloudKeyValues != null) {
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_ORG_NAME.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getOrganizationName());
|
||||
this.taskObservationCloudKeyValues.getOrganizationName());
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_SPACE_ID.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getSpaceId());
|
||||
this.taskObservationCloudKeyValues.getSpaceId());
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_SPACE_NAME.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getSpaceName());
|
||||
this.taskObservationCloudKeyValues.getSpaceName());
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_APP_ID.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getApplicationId());
|
||||
this.taskObservationCloudKeyValues.getApplicationId());
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_APP_NAME.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getApplicationName());
|
||||
this.taskObservationCloudKeyValues.getApplicationName());
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_APP_VERSION.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getApplicationVersion());
|
||||
observation.lowCardinalityKeyValue(TaskExecutionObservation.TaskKeyValues.TASK_CF_INSTANCE_INDEX.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getInstanceIndex());
|
||||
this.taskObservationCloudKeyValues.getApplicationVersion());
|
||||
observation.lowCardinalityKeyValue(
|
||||
TaskExecutionObservation.TaskKeyValues.TASK_CF_INSTANCE_INDEX.getKeyName(),
|
||||
this.taskObservationCloudKeyValues.getInstanceIndex());
|
||||
}
|
||||
observation.start();
|
||||
|
||||
@@ -107,8 +112,8 @@ public class TaskObservations {
|
||||
}
|
||||
|
||||
public void onTaskFailed(Throwable throwable) {
|
||||
this.taskObservationContext.setStatus(STATUS_FAILURE);
|
||||
this.scope.getCurrentObservation().error(throwable);
|
||||
this.taskObservationContext.setStatus(STATUS_FAILURE);
|
||||
this.scope.getCurrentObservation().error(throwable);
|
||||
}
|
||||
|
||||
public void onTaskEnd(TaskExecution taskExecution) {
|
||||
@@ -118,4 +123,5 @@ public class TaskObservations {
|
||||
this.scope.getCurrentObservation().stop();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -42,8 +42,7 @@ public class TaskListenerExecutor implements TaskExecutionListener {
|
||||
private Map<Method, Set<Object>> failedTaskInstances;
|
||||
|
||||
public TaskListenerExecutor(Map<Method, Set<Object>> beforeTaskInstances,
|
||||
Map<Method, Set<Object>> afterTaskInstances,
|
||||
Map<Method, Set<Object>> failedTaskInstances) {
|
||||
Map<Method, Set<Object>> afterTaskInstances, Map<Method, Set<Object>> failedTaskInstances) {
|
||||
|
||||
this.beforeTaskInstances = beforeTaskInstances;
|
||||
this.afterTaskInstances = afterTaskInstances;
|
||||
@@ -56,8 +55,7 @@ public class TaskListenerExecutor implements TaskExecutionListener {
|
||||
*/
|
||||
@Override
|
||||
public void onTaskStartup(TaskExecution taskExecution) {
|
||||
executeTaskListener(taskExecution, this.beforeTaskInstances.keySet(),
|
||||
this.beforeTaskInstances);
|
||||
executeTaskListener(taskExecution, this.beforeTaskInstances.keySet(), this.beforeTaskInstances);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -66,8 +64,7 @@ public class TaskListenerExecutor implements TaskExecutionListener {
|
||||
*/
|
||||
@Override
|
||||
public void onTaskEnd(TaskExecution taskExecution) {
|
||||
executeTaskListener(taskExecution, this.afterTaskInstances.keySet(),
|
||||
this.afterTaskInstances);
|
||||
executeTaskListener(taskExecution, this.afterTaskInstances.keySet(), this.afterTaskInstances);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,8 +74,8 @@ public class TaskListenerExecutor implements TaskExecutionListener {
|
||||
*/
|
||||
@Override
|
||||
public void onTaskFailed(TaskExecution taskExecution, Throwable throwable) {
|
||||
executeTaskListenerWithThrowable(taskExecution, throwable,
|
||||
this.failedTaskInstances.keySet(), this.failedTaskInstances);
|
||||
executeTaskListenerWithThrowable(taskExecution, throwable, this.failedTaskInstances.keySet(),
|
||||
this.failedTaskInstances);
|
||||
}
|
||||
|
||||
private void executeTaskListener(TaskExecution taskExecution, Set<Method> methods,
|
||||
@@ -89,27 +86,24 @@ public class TaskListenerExecutor implements TaskExecutionListener {
|
||||
method.invoke(instance, 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",
|
||||
throw new TaskExecutionException(
|
||||
"taskExecution parameter " + "is required for @BeforeTask and @AfterTask annotated methods",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void executeTaskListenerWithThrowable(TaskExecution taskExecution,
|
||||
Throwable throwable, Set<Method> methods,
|
||||
private void executeTaskListenerWithThrowable(TaskExecution taskExecution, Throwable throwable, Set<Method> methods,
|
||||
Map<Method, Set<Object>> instances) {
|
||||
for (Method method : methods) {
|
||||
for (Object instance : instances.get(method)) {
|
||||
@@ -117,19 +111,17 @@ public class TaskListenerExecutor implements TaskExecutionListener {
|
||||
method.invoke(instance, 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) {
|
||||
throw new TaskExecutionException(
|
||||
"taskExecution and throwable parameters "
|
||||
+ "are required for @FailedTask annotated methods",
|
||||
e);
|
||||
throw new TaskExecutionException("taskExecution and throwable parameters "
|
||||
+ "are required for @FailedTask annotated methods", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,9 +90,9 @@ public class TaskExecution {
|
||||
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) {
|
||||
public TaskExecution(long executionId, Integer exitCode, String taskName, 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;
|
||||
@@ -107,12 +107,11 @@ public class TaskExecution {
|
||||
this.parentExecutionId = parentExecutionId;
|
||||
}
|
||||
|
||||
public TaskExecution(long executionId, Integer exitCode, String taskName,
|
||||
Date startTime, Date endTime, String exitMessage, List<String> arguments,
|
||||
String errorMessage, String externalExecutionId) {
|
||||
public TaskExecution(long executionId, Integer exitCode, String taskName, 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() {
|
||||
@@ -193,12 +192,10 @@ public class TaskExecution {
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
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
|
||||
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 + '}';
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,7 @@ public interface TaskRepository {
|
||||
* @return the updated {@link TaskExecution}
|
||||
*/
|
||||
@Transactional("springCloudTaskTransactionManager")
|
||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||
String exitMessage);
|
||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage);
|
||||
|
||||
/**
|
||||
* Notifies the repository that a taskExecution has completed.
|
||||
@@ -53,8 +52,8 @@ public interface TaskRepository {
|
||||
* @since 1.1.0
|
||||
*/
|
||||
@Transactional("springCloudTaskTransactionManager")
|
||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||
String exitMessage, String errorMessage);
|
||||
TaskExecution completeTaskExecution(long executionId, Integer exitCode, Date endTime, String exitMessage,
|
||||
String errorMessage);
|
||||
|
||||
/**
|
||||
* Notifies the repository that a taskExecution needs to be created.
|
||||
@@ -99,8 +98,8 @@ public interface TaskRepository {
|
||||
* @return TaskExecution created based on the parameters.
|
||||
*/
|
||||
@Transactional("springCloudTaskTransactionManager")
|
||||
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.
|
||||
@@ -122,7 +121,7 @@ public interface TaskRepository {
|
||||
* a TaskExecution.
|
||||
*/
|
||||
@Transactional("springCloudTaskTransactionManager")
|
||||
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);
|
||||
|
||||
}
|
||||
|
||||
@@ -66,10 +66,8 @@ 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 ";
|
||||
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.
|
||||
@@ -116,15 +114,13 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
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 "
|
||||
+ "EXIT_MESSAGE, ERROR_MESSAGE, LAST_UPDATED, EXTERNAL_EXECUTION_ID, " + "PARENT_EXECUTION_ID "
|
||||
+ "from %PREFIX%EXECUTION where TASK_EXECUTION_ID = :taskExecutionId";
|
||||
|
||||
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";
|
||||
@@ -138,8 +134,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
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 "
|
||||
+ " 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 "
|
||||
@@ -152,6 +147,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
private static final String FIND_JOB_EXECUTION_BY_TASK_EXECUTION_ID = "SELECT JOB_EXECUTION_ID "
|
||||
+ "FROM %PREFIX%TASK_BATCH WHERE TASK_EXECUTION_ID = :taskExecutionId";
|
||||
|
||||
private static final Set<String> validSortColumns = new HashSet<>(10);
|
||||
|
||||
static {
|
||||
@@ -168,9 +164,13 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
private final NamedParameterJdbcTemplate jdbcTemplate;
|
||||
|
||||
private String tablePrefix = TaskProperties.DEFAULT_TABLE_PREFIX;
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
private LinkedHashMap<String, Order> orderMap;
|
||||
|
||||
private DataFieldMaxValueIncrementer taskIncrementer;
|
||||
|
||||
/**
|
||||
@@ -199,25 +199,22 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@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 nextExecutionId = getNextExecutionId();
|
||||
|
||||
TaskExecution taskExecution = new TaskExecution(nextExecutionId, null, taskName,
|
||||
startTime, null, null, arguments, null, externalExecutionId);
|
||||
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("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);
|
||||
@@ -228,25 +225,20 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution startTaskExecution(long executionId, String taskName,
|
||||
Date startTime, List<String> arguments, String externalExecutionId) {
|
||||
return startTaskExecution(executionId, taskName, startTime, arguments,
|
||||
externalExecutionId, null);
|
||||
public TaskExecution startTaskExecution(long executionId, String taskName, 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) {
|
||||
TaskExecution taskExecution = new TaskExecution(executionId, null, taskName,
|
||||
startTime, null, null, arguments, null, externalExecutionId,
|
||||
parentExecutionId);
|
||||
public TaskExecution startTaskExecution(long executionId, String taskName, Date startTime, List<String> arguments,
|
||||
String externalExecutionId, Long parentExecutionId) {
|
||||
TaskExecution taskExecution = new TaskExecution(executionId, null, taskName, 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("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);
|
||||
|
||||
@@ -257,8 +249,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
else {
|
||||
updateString += START_TASK_EXECUTION_EXTERNAL_ID_SUFFIX;
|
||||
queryParameters.addValue("externalExecutionId", externalExecutionId,
|
||||
Types.VARCHAR);
|
||||
queryParameters.addValue("externalExecutionId", externalExecutionId, Types.VARCHAR);
|
||||
}
|
||||
|
||||
this.jdbcTemplate.update(getQuery(updateString), queryParameters);
|
||||
@@ -267,22 +258,20 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeTaskExecution(long taskExecutionId, Integer exitCode,
|
||||
Date endTime, String exitMessage, String errorMessage) {
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
||||
public void completeTaskExecution(long taskExecutionId, Integer exitCode, Date endTime, String exitMessage,
|
||||
String errorMessage) {
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource().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 (this.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("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)
|
||||
@@ -292,20 +281,18 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@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);
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource().addValue("taskExecutionId",
|
||||
executionId, Types.BIGINT);
|
||||
|
||||
try {
|
||||
TaskExecution taskExecution = this.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;
|
||||
}
|
||||
@@ -317,12 +304,12 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
@Override
|
||||
public long getTaskExecutionCountByTaskName(String taskName) {
|
||||
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||
.addValue("taskName", taskName, Types.VARCHAR);
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource().addValue("taskName", taskName,
|
||||
Types.VARCHAR);
|
||||
|
||||
try {
|
||||
return this.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;
|
||||
@@ -331,12 +318,11 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
@Override
|
||||
public long getRunningTaskExecutionCountByTaskName(String taskName) {
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||
.addValue("taskName", taskName, Types.VARCHAR);
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource().addValue("taskName", taskName,
|
||||
Types.VARCHAR);
|
||||
|
||||
try {
|
||||
return this.jdbcTemplate.queryForObject(
|
||||
getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), queryParameters,
|
||||
return this.jdbcTemplate.queryForObject(getQuery(RUNNING_TASK_EXECUTION_COUNT_BY_NAME), queryParameters,
|
||||
Long.class);
|
||||
}
|
||||
catch (EmptyResultDataAccessException e) {
|
||||
@@ -349,8 +335,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
try {
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource();
|
||||
return this.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;
|
||||
@@ -369,15 +355,14 @@ 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();
|
||||
@@ -387,8 +372,7 @@ 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;
|
||||
}
|
||||
@@ -397,8 +381,7 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Only expected a single TaskExecution but received "
|
||||
+ taskExecutions.size());
|
||||
"Only expected a single TaskExecution but received " + taskExecutions.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,8 +389,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
public long getTaskExecutionCount() {
|
||||
|
||||
try {
|
||||
return this.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;
|
||||
@@ -415,32 +398,26 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
|
||||
Pageable pageable) {
|
||||
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE,
|
||||
RUNNING_TASK_WHERE_CLAUSE,
|
||||
new MapSqlParameterSource("taskName", taskName),
|
||||
getRunningTaskExecutionCountByTaskName(taskName));
|
||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
|
||||
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE, RUNNING_TASK_WHERE_CLAUSE,
|
||||
new MapSqlParameterSource("taskName", taskName), getRunningTaskExecutionCountByTaskName(taskName));
|
||||
}
|
||||
|
||||
@Override
|
||||
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));
|
||||
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));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTaskNames() {
|
||||
return this.jdbcTemplate.queryForList(getQuery(FIND_TASK_NAMES),
|
||||
new MapSqlParameterSource(), String.class);
|
||||
return this.jdbcTemplate.queryForList(getQuery(FIND_TASK_NAMES), new MapSqlParameterSource(), String.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TaskExecution> findAll(Pageable pageable) {
|
||||
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE, null,
|
||||
new MapSqlParameterSource(), getTaskExecutionCount());
|
||||
return queryForPageableResults(pageable, SELECT_CLAUSE, FROM_CLAUSE, null, new MapSqlParameterSource(),
|
||||
getTaskExecutionCount());
|
||||
}
|
||||
|
||||
public void setTaskIncrementer(DataFieldMaxValueIncrementer taskIncrementer) {
|
||||
@@ -453,12 +430,11 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
@Override
|
||||
public Long getTaskExecutionIdByJobExecutionId(long jobExecutionId) {
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||
.addValue("jobExecutionId", jobExecutionId, Types.BIGINT);
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource().addValue("jobExecutionId",
|
||||
jobExecutionId, Types.BIGINT);
|
||||
|
||||
try {
|
||||
return this.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) {
|
||||
@@ -468,21 +444,18 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
@Override
|
||||
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource()
|
||||
.addValue("taskExecutionId", taskExecutionId, Types.BIGINT);
|
||||
final MapSqlParameterSource queryParameters = new MapSqlParameterSource().addValue("taskExecutionId",
|
||||
taskExecutionId, Types.BIGINT);
|
||||
|
||||
try {
|
||||
return this.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"));
|
||||
jobExecutionIds.add(resultSet.getLong("JOB_EXECUTION_ID"));
|
||||
}
|
||||
|
||||
return jobExecutionIds;
|
||||
@@ -495,23 +468,18 @@ 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);
|
||||
|
||||
if (this.jdbcTemplate.update(
|
||||
getQuery(UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID),
|
||||
queryParameters) != 1) {
|
||||
throw new IllegalStateException(
|
||||
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||
if (this.jdbcTemplate.update(getQuery(UPDATE_TASK_EXECUTION_EXTERNAL_EXECUTION_ID), queryParameters) != 1) {
|
||||
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) {
|
||||
private Page<TaskExecution> queryForPageableResults(Pageable pageable, String selectClause, String fromClause,
|
||||
String whereClause, MapSqlParameterSource queryParameters, long totalCount) {
|
||||
SqlPagingQueryProviderFactoryBean factoryBean = new SqlPagingQueryProviderFactoryBean();
|
||||
factoryBean.setSelectClause(selectClause);
|
||||
factoryBean.setFromClause(fromClause);
|
||||
@@ -551,8 +519,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
String query = pagingQueryProvider.getPageQuery(pageable);
|
||||
List<TaskExecution> resultList = this.jdbcTemplate.query(getQuery(query),
|
||||
queryParameters, new TaskExecutionRowMapper());
|
||||
List<TaskExecution> resultList = this.jdbcTemplate.query(getQuery(query), queryParameters,
|
||||
new TaskExecutionRowMapper());
|
||||
return new PageImpl<>(resultList, pageable, totalCount);
|
||||
}
|
||||
|
||||
@@ -572,8 +540,8 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method that inserts an individual records into the TASK_EXECUTION_PARAMS
|
||||
* table.
|
||||
* Convenience method that inserts an individual records into the
|
||||
* TASK_EXECUTION_PARAMS table.
|
||||
* @param taskExecutionId id of a task execution
|
||||
* @param taskParam task parameters
|
||||
*/
|
||||
@@ -613,11 +581,10 @@ public class JdbcTaskExecutionDao implements TaskExecutionDao {
|
||||
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 {
|
||||
|
||||
@@ -58,34 +58,30 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@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);
|
||||
TaskExecution taskExecution = new TaskExecution(taskExecutionId, null, taskName, 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) {
|
||||
return startTaskExecution(executionId, taskName, startTime, arguments,
|
||||
externalExecutionid, null);
|
||||
public TaskExecution startTaskExecution(long executionId, String taskName, 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) {
|
||||
public TaskExecution startTaskExecution(long executionId, String taskName, Date startTime, List<String> arguments,
|
||||
String externalExecutionid, Long parentExecutionId) {
|
||||
TaskExecution taskExecution = this.taskExecutions.get(executionId);
|
||||
taskExecution.setTaskName(taskName);
|
||||
taskExecution.setStartTime(startTime);
|
||||
@@ -98,11 +94,10 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void completeTaskExecution(long executionId, Integer exitCode, Date endTime,
|
||||
String exitMessage, String errorMessage) {
|
||||
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.");
|
||||
throw new IllegalStateException("Invalid TaskExecution, ID " + executionId + " not found.");
|
||||
}
|
||||
|
||||
TaskExecution taskExecution = this.taskExecutions.get(executionId);
|
||||
@@ -113,8 +108,7 @@ 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);
|
||||
}
|
||||
|
||||
@@ -138,8 +132,7 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
public long getRunningTaskExecutionCountByTaskName(String taskName) {
|
||||
int count = 0;
|
||||
for (Map.Entry<Long, TaskExecution> entry : this.taskExecutions.entrySet()) {
|
||||
if (entry.getValue().getTaskName().equals(taskName)
|
||||
&& entry.getValue().getEndTime() == null) {
|
||||
if (entry.getValue().getTaskName().equals(taskName) && entry.getValue().getEndTime() == null) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -163,30 +156,25 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@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 : this.taskExecutions.entrySet()) {
|
||||
if (entry.getValue().getTaskName().equals(taskName)
|
||||
&& entry.getValue().getEndTime() == null) {
|
||||
if (entry.getValue().getTaskName().equals(taskName) && entry.getValue().getEndTime() == null) {
|
||||
result.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
return getPageFromList(new ArrayList<>(result), pageable,
|
||||
getRunningTaskExecutionCountByTaskName(taskName));
|
||||
return getPageFromList(new ArrayList<>(result), pageable, getRunningTaskExecutionCountByTaskName(taskName));
|
||||
}
|
||||
|
||||
@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 : this.taskExecutions.entrySet()) {
|
||||
if (entry.getValue().getTaskName().equals(taskName)) {
|
||||
filteredSet.add(entry.getValue());
|
||||
}
|
||||
}
|
||||
return getPageFromList(new ArrayList<>(filteredSet), pageable,
|
||||
getTaskExecutionCountByTaskName(taskName));
|
||||
return getPageFromList(new ArrayList<>(filteredSet), pageable, getTaskExecutionCountByTaskName(taskName));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -220,8 +208,7 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
|
||||
found:
|
||||
|
||||
for (Map.Entry<Long, Set<Long>> association : this.batchJobAssociations
|
||||
.entrySet()) {
|
||||
for (Map.Entry<Long, Set<Long>> association : this.batchJobAssociations.entrySet()) {
|
||||
for (Long curJobExecutionId : association.getValue()) {
|
||||
if (curJobExecutionId.equals(jobExecutionId)) {
|
||||
taskId = association.getKey();
|
||||
@@ -236,8 +223,7 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
@Override
|
||||
public Set<Long> getJobExecutionIdsByTaskExecutionId(long taskExecutionId) {
|
||||
if (this.batchJobAssociations.containsKey(taskExecutionId)) {
|
||||
return Collections
|
||||
.unmodifiableSet(this.batchJobAssociations.get(taskExecutionId));
|
||||
return Collections.unmodifiableSet(this.batchJobAssociations.get(taskExecutionId));
|
||||
}
|
||||
else {
|
||||
return new TreeSet<>();
|
||||
@@ -245,11 +231,9 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateExternalExecutionId(long taskExecutionId,
|
||||
String externalExecutionId) {
|
||||
public void updateExternalExecutionId(long taskExecutionId, String externalExecutionId) {
|
||||
TaskExecution taskExecution = this.taskExecutions.get(taskExecutionId);
|
||||
Assert.notNull(taskExecution,
|
||||
"Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||
Assert.notNull(taskExecution, "Invalid TaskExecution, ID " + taskExecutionId + " not found.");
|
||||
taskExecution.setExternalExecutionId(externalExecutionId);
|
||||
}
|
||||
|
||||
@@ -263,22 +247,17 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
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());
|
||||
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();
|
||||
return new PageImpl<>(
|
||||
executionList.subList((int) pageable.getOffset(), (int) toIndex),
|
||||
pageable, maxSize);
|
||||
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), pageable, maxSize);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -294,34 +273,29 @@ 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());
|
||||
if (tempTaskExecution == null
|
||||
|| tempTaskExecution.getStartTime()
|
||||
.before(taskExecutionMapEntry.getValue().getStartTime())
|
||||
|| (tempTaskExecution.getStartTime()
|
||||
.equals(taskExecutionMapEntry.getValue().getStartTime())
|
||||
&& tempTaskExecution.getExecutionId() < taskExecutionMapEntry
|
||||
.getValue().getExecutionId())) {
|
||||
|| 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;
|
||||
}
|
||||
@@ -329,8 +303,7 @@ 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;
|
||||
}
|
||||
@@ -339,25 +312,19 @@ public class MapTaskExecutionDao implements TaskExecutionDao {
|
||||
}
|
||||
else {
|
||||
throw new IllegalStateException(
|
||||
"Only expected a single TaskExecution but received "
|
||||
+ taskExecutions.size());
|
||||
"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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ public interface TaskExecutionDao {
|
||||
* @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}.
|
||||
@@ -55,8 +55,8 @@ 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.
|
||||
@@ -69,8 +69,8 @@ public interface TaskExecutionDao {
|
||||
* 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.
|
||||
@@ -84,8 +84,8 @@ public interface TaskExecutionDao {
|
||||
* 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.
|
||||
@@ -96,8 +96,8 @@ public interface TaskExecutionDao {
|
||||
* @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}.
|
||||
@@ -106,8 +106,7 @@ public interface TaskExecutionDao {
|
||||
* @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.
|
||||
|
||||
@@ -144,13 +144,11 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
||||
sql.append(" WHERE ").append(this.whereClause);
|
||||
}
|
||||
List<String> namedParameters = new ArrayList<>();
|
||||
this.parameterCount = JdbcParameterUtils
|
||||
.countParameterPlaceholders(sql.toString(), namedParameters);
|
||||
this.parameterCount = JdbcParameterUtils.countParameterPlaceholders(sql.toString(), namedParameters);
|
||||
if (namedParameters.size() > 0) {
|
||||
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);
|
||||
}
|
||||
this.usingNamedParameters = true;
|
||||
}
|
||||
@@ -159,8 +157,7 @@ public abstract class AbstractSqlPagingQueryProvider implements PagingQueryProvi
|
||||
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 {
|
||||
|
||||
@@ -32,17 +32,15 @@ public class Db2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
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()));
|
||||
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < " + (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);
|
||||
|
||||
@@ -29,10 +29,8 @@ public class H2PagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
|
||||
@Override
|
||||
public String getPageQuery(Pageable pageable) {
|
||||
String limitClause = new StringBuilder().append("OFFSET ")
|
||||
.append(pageable.getOffset()).append(" ROWS FETCH NEXT ")
|
||||
.append(pageable.getPageSize()).append(" ROWS ONLY")
|
||||
.toString();
|
||||
String limitClause = new StringBuilder().append("OFFSET ").append(pageable.getOffset())
|
||||
.append(" ROWS FETCH NEXT ").append(pageable.getPageSize()).append(" ROWS ONLY").toString();
|
||||
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, limitClause);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,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();
|
||||
String topClause = new StringBuilder().append("LIMIT ").append(pageable.getOffset()).append(" ")
|
||||
.append(pageable.getPageSize()).toString();
|
||||
return SqlPagingQueryUtils.generateTopJumpToQuery(this, topClause);
|
||||
}
|
||||
|
||||
|
||||
@@ -28,9 +28,8 @@ 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();
|
||||
String topClause = new StringBuilder().append("LIMIT ").append(pageable.getOffset()).append(", ")
|
||||
.append(pageable.getPageSize()).toString();
|
||||
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, topClause);
|
||||
}
|
||||
|
||||
|
||||
@@ -31,17 +31,15 @@ public class OraclePagingQueryProvider extends AbstractSqlPagingQueryProvider {
|
||||
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()));
|
||||
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < " + (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(", ").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);
|
||||
|
||||
@@ -29,8 +29,7 @@ public class PostgresPagingQueryProvider extends AbstractSqlPagingQueryProvider
|
||||
|
||||
@Override
|
||||
public String getPageQuery(Pageable pageable) {
|
||||
String limitClause = new StringBuilder().append("LIMIT ")
|
||||
.append(pageable.getPageSize()).append(" OFFSET ")
|
||||
String limitClause = new StringBuilder().append("LIMIT ").append(pageable.getPageSize()).append(" OFFSET ")
|
||||
.append(pageable.getOffset()).toString();
|
||||
return SqlPagingQueryUtils.generateLimitJumpToQuery(this, limitClause);
|
||||
}
|
||||
|
||||
@@ -47,8 +47,7 @@ import static org.springframework.cloud.task.repository.support.DatabaseType.SQL
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
*/
|
||||
public class SqlPagingQueryProviderFactoryBean
|
||||
implements FactoryBean<PagingQueryProvider> {
|
||||
public class SqlPagingQueryProviderFactoryBean implements FactoryBean<PagingQueryProvider> {
|
||||
|
||||
private DataSource dataSource;
|
||||
|
||||
@@ -134,20 +133,16 @@ public class SqlPagingQueryProviderFactoryBean
|
||||
|
||||
DatabaseType type;
|
||||
try {
|
||||
type = this.databaseType != null
|
||||
? DatabaseType.valueOf(this.databaseType.toUpperCase())
|
||||
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 = this.providers.get(type);
|
||||
Assert.state(provider != null,
|
||||
"Should not happen: missing PagingQueryProvider for DatabaseType="
|
||||
+ type);
|
||||
Assert.state(provider != null, "Should not happen: missing PagingQueryProvider for DatabaseType=" + type);
|
||||
|
||||
provider.setFromClause(this.fromClause);
|
||||
provider.setWhereClause(this.whereClause);
|
||||
|
||||
@@ -37,13 +37,11 @@ public final class SqlPagingQueryUtils {
|
||||
* @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);
|
||||
|
||||
@@ -57,14 +55,11 @@ public final class SqlPagingQueryUtils {
|
||||
* @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();
|
||||
@@ -76,8 +71,8 @@ public final class SqlPagingQueryUtils {
|
||||
* @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) {
|
||||
@@ -87,8 +82,7 @@ public final class SqlPagingQueryUtils {
|
||||
}
|
||||
}
|
||||
else {
|
||||
sql.append(provider.getWhereClause() == null ? ""
|
||||
: " WHERE " + provider.getWhereClause());
|
||||
sql.append(provider.getWhereClause() == null ? "" : " WHERE " + provider.getWhereClause());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,16 +31,14 @@ public class SqlServerPagingQueryProvider extends AbstractSqlPagingQueryProvider
|
||||
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()));
|
||||
"TMP_ROW_NUM >= " + offset + " AND TMP_ROW_NUM < " + (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(", ").append("ROW_NUMBER() OVER (ORDER BY ")
|
||||
.append(SqlPagingQueryUtils.buildSortClause(this))
|
||||
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());
|
||||
SqlPagingQueryUtils.buildWhereClause(this, remainingPageQuery, sql);
|
||||
sql.append(") TASK_EXECUTION_PAGE ");
|
||||
|
||||
@@ -109,24 +109,22 @@ public enum DatabaseType {
|
||||
* @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 SQLException, MetaDataAccessException {
|
||||
String databaseProductName = JdbcUtils
|
||||
.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() {
|
||||
public static DatabaseType fromMetaData(DataSource dataSource) throws SQLException, MetaDataAccessException {
|
||||
String databaseProductName = JdbcUtils.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() {
|
||||
|
||||
@Override
|
||||
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
|
||||
return dbmd.getDatabaseProductName();
|
||||
}
|
||||
}).toString();
|
||||
if (StringUtils.hasText(databaseProductName)
|
||||
&& !databaseProductName.equals("DB2/Linux")
|
||||
@Override
|
||||
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
|
||||
return dbmd.getDatabaseProductName();
|
||||
}
|
||||
}).toString();
|
||||
if (StringUtils.hasText(databaseProductName) && !databaseProductName.equals("DB2/Linux")
|
||||
&& databaseProductName.startsWith("DB2")) {
|
||||
String databaseProductVersion = JdbcUtils
|
||||
.extractDatabaseMetaData(dataSource, new DatabaseMetaDataCallback() {
|
||||
|
||||
@Override
|
||||
public Object processMetaData(DatabaseMetaData dbmd) throws SQLException, MetaDataAccessException {
|
||||
public Object processMetaData(DatabaseMetaData dbmd)
|
||||
throws SQLException, MetaDataAccessException {
|
||||
return dbmd.getDatabaseProductVersion();
|
||||
}
|
||||
}).toString();
|
||||
@@ -139,8 +137,7 @@ public enum DatabaseType {
|
||||
}
|
||||
else if (databaseProductName.indexOf("AS") != -1
|
||||
&& (databaseProductVersion.startsWith("QSQ") || databaseProductVersion
|
||||
.substring(databaseProductVersion.indexOf('V'))
|
||||
.matches("V\\dR\\d[mM]\\d"))) {
|
||||
.substring(databaseProductVersion.indexOf('V')).matches("V\\dR\\d[mM]\\d"))) {
|
||||
databaseProductName = "DB2AS400";
|
||||
}
|
||||
else {
|
||||
@@ -164,8 +161,7 @@ public enum DatabaseType {
|
||||
productName = "MySQL";
|
||||
}
|
||||
if (!dbNameMap.containsKey(productName)) {
|
||||
throw new IllegalArgumentException(
|
||||
"DatabaseType not found for product name: [" + productName + "]");
|
||||
throw new IllegalArgumentException("DatabaseType not found for product name: [" + productName + "]");
|
||||
}
|
||||
else {
|
||||
return dbNameMap.get(productName);
|
||||
|
||||
@@ -39,8 +39,7 @@ 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();
|
||||
@@ -56,8 +55,7 @@ public class SimpleTaskExplorer implements TaskExplorer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName,
|
||||
Pageable pageable) {
|
||||
public Page<TaskExecution> findRunningTaskExecutions(String taskName, Pageable pageable) {
|
||||
return this.taskExecutionDao.findRunningTaskExecutions(taskName, pageable);
|
||||
}
|
||||
|
||||
@@ -82,8 +80,7 @@ public class SimpleTaskExplorer implements TaskExplorer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page<TaskExecution> findTaskExecutionsByName(String taskName,
|
||||
Pageable pageable) {
|
||||
public Page<TaskExecution> findTaskExecutionsByName(String taskName, Pageable pageable) {
|
||||
return this.taskExecutionDao.findTaskExecutionsByName(taskName, pageable);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,8 +46,7 @@ public class SimpleTaskNameResolver implements TaskNameResolver, ApplicationCont
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.context = applicationContext;
|
||||
}
|
||||
|
||||
|
||||
@@ -65,19 +65,15 @@ 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");
|
||||
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;
|
||||
}
|
||||
@@ -91,24 +87,21 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
}
|
||||
|
||||
@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);
|
||||
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='"
|
||||
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 this.taskExecutionDao.getTaskExecution(executionId);
|
||||
@@ -118,9 +111,8 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
public TaskExecution createTaskExecution(TaskExecution taskExecution) {
|
||||
initialize();
|
||||
validateCreateInformation(taskExecution);
|
||||
TaskExecution daoTaskExecution = this.taskExecutionDao.createTaskExecution(
|
||||
taskExecution.getTaskName(), taskExecution.getStartTime(),
|
||||
taskExecution.getArguments(), taskExecution.getExternalExecutionId(),
|
||||
TaskExecution daoTaskExecution = this.taskExecutionDao.createTaskExecution(taskExecution.getTaskName(),
|
||||
taskExecution.getStartTime(), taskExecution.getArguments(), taskExecution.getExternalExecutionId(),
|
||||
taskExecution.getParentExecutionId());
|
||||
logger.debug("Creating: " + taskExecution.toString());
|
||||
return daoTaskExecution;
|
||||
@@ -129,8 +121,8 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
@Override
|
||||
public TaskExecution createTaskExecution(String name) {
|
||||
initialize();
|
||||
TaskExecution taskExecution = this.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;
|
||||
}
|
||||
@@ -141,10 +133,9 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution startTaskExecution(long executionid, String taskName,
|
||||
Date startTime, List<String> arguments, String externalExecutionId) {
|
||||
return startTaskExecution(executionid, taskName, startTime, arguments,
|
||||
externalExecutionId, null);
|
||||
public TaskExecution startTaskExecution(long executionid, String taskName, Date startTime, List<String> arguments,
|
||||
String externalExecutionId) {
|
||||
return startTaskExecution(executionid, taskName, startTime, arguments, externalExecutionId, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -154,13 +145,11 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaskExecution startTaskExecution(long executionid, String taskName,
|
||||
Date startTime, List<String> arguments, String externalExecutionId,
|
||||
Long parentExecutionId) {
|
||||
public TaskExecution startTaskExecution(long executionid, String taskName, Date startTime, List<String> arguments,
|
||||
String externalExecutionId, Long parentExecutionId) {
|
||||
initialize();
|
||||
TaskExecution taskExecution = this.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;
|
||||
}
|
||||
@@ -181,8 +170,7 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
this.initialized = true;
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException("Unable to create the TaskExecutionDao",
|
||||
e);
|
||||
throw new IllegalStateException("Unable to create the TaskExecutionDao", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -192,18 +180,14 @@ public class SimpleTaskRepository implements TaskRepository {
|
||||
* @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.");
|
||||
|
||||
@@ -22,6 +22,7 @@ import org.springframework.jdbc.support.incrementer.AbstractSequenceMaxValueIncr
|
||||
|
||||
/**
|
||||
* Incrementer using SQL Server's sequence.
|
||||
*
|
||||
* @author Glenn Renfro
|
||||
* @since 2.3.2
|
||||
*/
|
||||
@@ -30,8 +31,10 @@ public class SqlServerSequenceMaxValueIncrementer extends AbstractSequenceMaxVal
|
||||
SqlServerSequenceMaxValueIncrementer(DataSource dataSource, String incrementerName) {
|
||||
super(dataSource, incrementerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getSequenceQuery() {
|
||||
return "select next value for " + getIncrementerName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -100,8 +100,8 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
||||
String incrementerName = this.tablePrefix + "SEQ";
|
||||
DataFieldMaxValueIncrementerFactory incrementerFactory = new DefaultDataFieldMaxValueIncrementerFactory(
|
||||
dataSource);
|
||||
DataFieldMaxValueIncrementer incrementer = incrementerFactory
|
||||
.getIncrementer(databaseType, incrementerName);
|
||||
DataFieldMaxValueIncrementer incrementer = incrementerFactory.getIncrementer(databaseType,
|
||||
incrementerName);
|
||||
if (!isSqlServerTableSequenceAvailable(incrementerName)) {
|
||||
incrementer = new SqlServerSequenceMaxValueIncrementer(dataSource, this.tablePrefix + "SEQ");
|
||||
}
|
||||
@@ -135,8 +135,8 @@ public class TaskExecutionDaoFactoryBean implements FactoryBean<TaskExecutionDao
|
||||
catch (SQLException 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"));
|
||||
}
|
||||
|
||||
private boolean isSqlServerTableSequenceAvailable(String incrementerName) {
|
||||
|
||||
@@ -84,9 +84,7 @@ 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);
|
||||
@@ -99,10 +97,9 @@ public final class TaskRepositoryInitializer implements InitializingBean {
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
boolean isInitializeEnabled = (this.taskProperties.isInitializeEnabled() != null)
|
||||
? this.taskProperties.isInitializeEnabled()
|
||||
: this.taskInitializationEnabled;
|
||||
if (this.dataSource != null && isInitializeEnabled && this.taskProperties
|
||||
.getTablePrefix().equals(TaskProperties.DEFAULT_TABLE_PREFIX)) {
|
||||
? this.taskProperties.isInitializeEnabled() : this.taskInitializationEnabled;
|
||||
if (this.dataSource != null && isInitializeEnabled
|
||||
&& this.taskProperties.getTablePrefix().equals(TaskProperties.DEFAULT_TABLE_PREFIX)) {
|
||||
String platform = getDatabaseType(this.dataSource);
|
||||
if ("hsql".equals(platform)) {
|
||||
platform = "hsqldb";
|
||||
@@ -124,8 +121,7 @@ public final class TaskRepositoryInitializer implements InitializingBean {
|
||||
schemaLocation = schemaLocation.replace("@@platform@@", platform);
|
||||
populator.addScript(this.resourceLoader.getResource(schemaLocation));
|
||||
populator.setContinueOnError(true);
|
||||
logger.debug(
|
||||
String.format("Initializing task schema for %s database", platform));
|
||||
logger.debug(String.format("Initializing task schema for %s database", platform));
|
||||
DatabasePopulatorUtils.execute(populator, this.dataSource);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user