8. Configuration

Spring Cloud Task provides an out of the box configuration as defined in the DefaultTaskConfigurer and SimpleTaskConfiguration. This section will walk through the defaults as well as how to customize Spring Cloud Task for your needs

8.1 DataSource

Spring Cloud Task utilizes a datasource for storing the results of task executions. By default, we provide an in memory instance of H2 to provide a simple method of bootstrapping development. However, in a production environment, you’ll want to configure your own DataSource.

If your application utilizes only a single DataSource and that will serve as both your business schema as well as the task repository, all you need to do is provide any DataSource (via Spring Boot’s configuration conventions is the easiest way). This will be automatically used by Spring Cloud Task for the repository.

If your application utilizes more than one DataSource, you’ll need to configure the task repository with the appropriate DataSource. This customization can be done via an implementation of the TaskConfigurer.

8.2 Table Prefix

One modifiable property of the TaskRepository is the table prefix for the task tables. By default they are all prefaced with TASK_. TASK_EXECUTION and TASK_EXECUTION_PARAMS are two examples. However, there are potential reasons to modify this prefix. If the schema names needs to be prepended to the table names, or if more than one set of task tables is needed within the same schema, then the table prefix will need to be changed. This is done by setting the spring.cloud.task.tablePrefix to the prefix that is required.

 spring.cloud.task.tablePrefix=<yourPrefix>

8.3 Enable/Disable table initialization

In cases where you are creating the task tables and do not wish for Spring Cloud Task to create them at task startup set the spring.cloud.task.initialize.enable property to false. It is currently defaulted to true.

 spring.cloud.task.initialize.enable=<true or false>

8.4 Externally Generated Task Id

In some cases a user wants to allow for the time difference between when a task is requested and when the infrastructure actually launches it. Spring Cloud Task allows a user to create a TaskExecution at the time the task is requested. Then pass the execution ID of the generated TaskExecution to the task so that it can update the TaskExecution through the task’s lifecycle.

The TaskExecution can be created by calling the createTaskExecution method on an implementation of the TaskRepository that references the datastore storing the TaskExecutions.

In order to configure your Task to use a generated TaskExecutionId add the following property:

 spring.cloud.task.executionid=<yourtaskId>

8.5 External Task Id

Spring Cloud Task allows a user to store an external task Id for each TaskExecution. An example of this would be a task id that is provided by Cloud Foundry when a task is launched on the platform. In order to configure your Task to use a generated TaskExecutionId add the following property:

spring.cloud.task.external-execution-id=<externalTaskId>

8.6 Parent Task Id

Spring Cloud Task allows a user to store an parent task Id for each TaskExecution. An example of this would be a task that executes another task or tasks and the user would like to store what task launched the child tasks. In order to configure your Task to set a parent TaskExecutionId add the following property on the child task:

spring.cloud.task.parent-execution-id=<parentExecutionTaskId>

8.7 TaskConfigurer

The TaskConfigurer is a strategy interface allowing for users to customize the way components of Spring Cloud Task are configured. By default, we provide the DefaultTaskConfigurer that provides logical defaults (Map based in memory components useful for development if no DataSource is provided and JDBC based components if there is a DataSource available.

The TaskConfigurer allows the configuration of three main components:

ComponentDescriptionDefault (provided by DefaultTaskConfigurer)

TaskRepository

The implementation of the TaskRepository to be used.

SimpleTaskRepository

TaskExplorer

The implementation of the TaskExplorer (a component for read only access to the task repository) to be used.

SimpleTaskExplorer

PlatformTransactionManager

A transaction manager to be used when executing updates for tasks.

DataSourceTransactionManager if a DataSource is used, ResourcelessTransactionManager if it is not.

Customizing any of the above is accomplished via a custom implementation of the TaskConfigurer interface. Typically, extending the DefaultTaskConfigurer (which is provided out of the box if a TaskConfigurer is not found) and overriding the required getter is sufficient, however, implementing your own from scratch may be required.

8.8 Task Name

In most cases, the name of the task will be the application name as configured via Spring Boot. However, there are some cases, where you may want to map the run of a task to a different name. Spring Data Flow is an example of this (where you want the task to be run with the name of the task definition). Because of this, we offer the ability to customize how the task is named via the TaskNameResolver interface.

By default, Spring Cloud Task provides the SimpleTaskNameResolver which will use the following options (in order of precedence):

  1. A Spring Boot property (configured any of the ways Spring Boot allows) spring.cloud.task.name.
  2. The application name as resolved using Spring Boot’s rules (obtained via ApplicationContext#getId).

8.9 Task Execution Listener

Allows a user to register listeners for specific events that occur during the task lifecycle. This is done by creating a class that implements the TaskExecutionListener interface. The class that implements the TaskExecutionListener interface will be notified for the following events:

  1. onTaskStartup - prior to the storing the TaskExecution into the TaskRepository
  2. onTaskEnd - prior to the updating of the TaskExecution entry in the TaskRepository marking the final state of the task.
  3. onTaskFailed - prior to the onTaskEnd method being invoked when an unhandled exception is thrown by the task.

Spring Cloud Task also allows a user add TaskExecution Listeners to methods within a bean by using the following method annotations:

  1. @BeforeTask - prior to the storing the TaskExecution into the TaskRepository
  2. @AfterTask - prior to the updating of the TaskExecution entry in the TaskRepository marking the final state of the task.
  3. @FailedTask - prior to the @AfterTask method being invoked when an unhandled exception is thrown by the task.
 public class MyBean {

	@BeforeTask
	public void methodA(TaskExecution taskExecution) {
	}

	@AfterTask
	public void methodB(TaskExecution taskExecution) {
	}

	@FailedTask
	public void methodC(TaskExecution taskExecution, Throwable throwable) {
	}
}

8.9.1 Exceptions Thrown by Task Execution Listener

In the case that an exception is thrown by a TaskExecutionListener event handler, all listener processing for that event handler will stop. For example: if three onTaskStartup listeners have established and the first onTaskStartup event handler throws an exception then the other two onTaskStartup methods will not be called. However the other event handlers (onTaskEnd, onTaskFailed) for the TaskExecutionListeners will be called.

The exit code returned when a exception is thrown by a TaskExecutionListener event handler will be the exit code that was reported by the ExitCodeEvent. If no ExitCodeEvent is emitted then the Exception thrown will be evaluated to see if it is of type ExitCodeGenerator , if so it will return the exit code from the ExitCodeGenerator else one will be returned.

8.9.2 Exit Messages

A user is allowed to set the exit message for a task programmatically via a TaskExecutionListener. This is done by setting the TaskExecution’s exitMessage that is passed into the TaskExecutionListener. For example if we want to use a method that is annotated with @AfterTask ExecutionListener :

@AfterTask
public void afterMe(TaskExecution taskExecution) {
    taskExecution.setExitMessage("AFTER EXIT MESSAGE");
}

Since a ExitMessage can be set at any of the listener events (onTaskStartup, onTaskFailed, and onTaskEnd) the order of precedence is:

  1. onTaskEnd
  2. onTaskFailed
  3. onTaskStartup

For example if a user sets a exitMessage for the onTaskStartup and onTaskFailed listeners and the task ends without failing then the exitMessage from the onTaskStartup will be stored in the repo, else if a failure occurs then the exitMessage from the onTaskFailed will be stored. Also if a user sets the exitMessage with a onTaskEnd listener then the exitMessage from the onTaskEnd will supersede the exit messages from both the onTaskStartup and onTaskFailed.

8.10 Restricting Spring Cloud Task Instances

Allows a user to establish that only one task with a given task name can be run at a time. To do this the user establishes the task name and sets spring.cloud.task.singleInstanceEnabled=true for each task execution. While the first task execution is running, any other time user tries to run a task with the same task name and spring.cloud.task.singleInstanceEnabled=true the task will fail with the following error message Task with name "application" is already running. The default for spring.cloud.task.singleInstanceEnabled is false.

 spring.cloud.task.singleInstanceEnabled=<true or false>

In order for this feature to be used you must include the following Spring Integration dependencies to your application:

---
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-core</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-jdbc</artifactId>
</dependency>
---