Spring Cloud Task provides a ready-to-use configuration, as defined in the
DefaultTaskConfigurer
and SimpleTaskConfiguration
classes. This section walks through
the defaults and how to customize Spring Cloud Task for your needs.
Spring Cloud Task uses 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 probably want to
configure your own DataSource
.
If your application uses only a single DataSource
and that serves as both your business
schema and the task repository, all you need to do is provide any DataSource
(the
easiest way to do so is through Spring Boot’s configuration conventions). This
DataSource
is automatically used by Spring Cloud Task for the repository.
If your application uses more than one DataSource
, you need to configure the task
repository with the appropriate DataSource
. This customization can be done through an
implementation of TaskConfigurer
.
One modifiable property of 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 name needs to be prepended to the table names or if more than one set of task
tables is needed within the same schema, you must change the table prefix. You can do so
by setting the spring.cloud.task.tablePrefix
to the prefix you need, as follows:
spring.cloud.task.tablePrefix=yourPrefix
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
, as follows:
spring.cloud.task.initialize.enable=false
It defaults to true
.
In some cases, you may want to allow for the time difference between when a task is
requested and when the infrastructure actually launches it. Spring Cloud Task lets you
create a TaskExecution
when 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.
A TaskExecution
can be created by calling the createTaskExecution
method on an
implementation of the TaskRepository
that references the datastore that holds
the TaskExecution
objects.
In order to configure your Task to use a generated TaskExecutionId
, add the
following property:
spring.cloud.task.executionid=yourtaskId
Spring Cloud Task lets you store an external task ID for each
TaskExecution
. An example of this would be a task ID 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>
Spring Cloud Task lets you store a parent task ID for each TaskExecution
. An example of
this would be a task that executes another task or tasks and you want to record which task
launched each of 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>
The TaskConfigurer
is a strategy interface that lets you 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 (useful if there is a DataSource
available).
The TaskConfigurer
lets you configure three main components:
Component | Description | Default (provided by DefaultTaskConfigurer ) |
---|---|---|
| The implementation of the |
|
| The implementation of the |
|
| A transaction manager to be used when running updates for tasks. |
|
You can customize any of the components described in the preceding table by creating a
custom implementation of the TaskConfigurer
interface. Typically, extending the
DefaultTaskConfigurer
(which is provided if a TaskConfigurer
is not found) and
overriding the required getter is sufficient. However, implementing your own from scratch
may be required.
In most cases, the name of the task is the application name as configured in Spring
Boot. However, there are some cases where you may want to map the run of a task to a
different name. Spring Cloud Data Flow is an example of this (because you probably 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, through the TaskNameResolver
interface.
By default, Spring Cloud Task provides the SimpleTaskNameResolver
, which uses the
following options (in order of precedence):
spring.cloud.task.name
.ApplicationContext#getId
).TaskExecutionListener
lets you register listeners for specific events that occur during
the task lifecycle. To do so, create a class that implements the
TaskExecutionListener
interface. The class that implements the TaskExecutionListener
interface is notified of the following events:
onTaskStartup
: Prior to storing the TaskExecution
into the TaskRepository
.onTaskEnd
: Prior to updating the TaskExecution
entry in the TaskRepository
and
marking the final state of the task.onTaskFailed
: Prior to the onTaskEnd
method being invoked when an unhandled
exception is thrown by the task.Spring Cloud Task also lets you add TaskExecution
Listeners to methods within a bean
by using the following method annotations:
@BeforeTask
: Prior to the storing the TaskExecution
into the TaskRepository
@AfterTask
: Prior to the updating of the TaskExecution
entry in the TaskRepository
marking the final state of the task.@FailedTask
: Prior to the @AfterTask
method being invoked when an unhandled
exception is thrown by the task.The following example shows the three annotations in use:
public class MyBean { @BeforeTask public void methodA(TaskExecution taskExecution) { } @AfterTask public void methodB(TaskExecution taskExecution) { } @FailedTask public void methodC(TaskExecution taskExecution, Throwable throwable) { } }
If an exception is thrown by a TaskExecutionListener
event handler, all listener
processing for that event handler stops. For example, if three onTaskStartup
listeners
have started and the first onTaskStartup
event handler throws an exception, the other
two onTaskStartup
methods are not called. However, the other event handlers (onTaskEnd
and onTaskFailed
) for the TaskExecutionListeners
are called.
The exit code returned when a exception is thrown by a TaskExecutionListener
event handler is the exit code that was reported by the
ExitCodeEvent.
If no ExitCodeEvent
is emitted, the Exception thrown is evaluated to see
if it is of type
ExitCodeGenerator.
If so, it returns the exit code from the ExitCodeGenerator
. Otherwise, 1
is returned.
You can set the exit message for a task programmatically by using a
TaskExecutionListener
. This is done by setting the TaskExecution’s
exitMessage
,
which then gets passed into the TaskExecutionListener
. The following example shows
a method that is annotated with the @AfterTask
ExecutionListener
:
@AfterTask public void afterMe(TaskExecution taskExecution) { taskExecution.setExitMessage("AFTER EXIT MESSAGE"); }
An ExitMessage
can be set at any of the listener events (onTaskStartup
,
onTaskFailed
, and onTaskEnd
). The order of precedence for the three listeners follows:
onTaskEnd
onTaskFailed
onTaskStartup
For example, if you set an exitMessage
for the onTaskStartup
and onTaskFailed
listeners and the task ends without failing, the exitMessage
from the onTaskStartup
is stored in the repository. Otherwise, if a failure occurs, the exitMessage
from
the onTaskFailed
is stored. Also if you set the exitMessage
with an
onTaskEnd
listener, the exitMessage
from the onTaskEnd
supersedes
the exit messages from both the onTaskStartup
and onTaskFailed
.
Spring Cloud Task lets you establish that only one task with a given task name can be run
at a time. To do so, you need to establish the task name and set
spring.cloud.task.singleInstanceEnabled=true
for each task execution. While the first
task execution is running, any other time you try to run a task with the same
task name and`spring.cloud.task.singleInstanceEnabled=true`, the
task fails with the following error message: Task with name "application" is already
running.
The default value for spring.cloud.task.singleInstanceEnabled
is false
. The
following example shows how to set spring.cloud.task.singleInstanceEnabled
to true
:
spring.cloud.task.singleInstanceEnabled=true or false
To use this feature, you must add 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>