Full editing pass
I corrected spelling and grammar and gave it a voice (flat, corporate) consistent with our other docs. I added a couple TODOs where I thought another sample would help. Incorporated Glenn Renfro's comments Glenn gave my work a thorough review (thanks, Glenn!). This commit incorporates his changes. One more change I missed one of Glenn's fixes (by forgetting to save one last time before the previous commit). I have corrected that oversight
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
|
||||
[[appendix-building-the-documentation]]
|
||||
== Building this documentation
|
||||
== Building This Documentation
|
||||
|
||||
This project uses Maven to generate this documentation. To generate it for yourself,
|
||||
execute the command: `$ ./mvnw clean package -P full`.
|
||||
This project uses Maven to generate this documentation. To generate it for yourself,
|
||||
run the following command: `$ ./mvnw clean package -P full`.
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
[[appendix-task-repository-schema]]
|
||||
== Task repository schema
|
||||
== Task Repository Schema
|
||||
|
||||
[[partintro]]
|
||||
--
|
||||
@@ -8,4 +7,3 @@ This appendix provides an ERD for the database schema used in the task repositor
|
||||
--
|
||||
|
||||
image::task_schema.png[]
|
||||
|
||||
|
||||
@@ -4,37 +4,40 @@
|
||||
|
||||
[[partintro]]
|
||||
--
|
||||
This section goes into more detail about Spring Cloud Task's integrations with Spring
|
||||
Batch. Tracking the association between a job execution and the task it was executed
|
||||
within as well as remote partitioning via Spring Cloud Deployer are all covered within
|
||||
This section goes into more detail about Spring Cloud Task's integration with Spring
|
||||
Batch. Tracking the association between a job execution and the task in which it was
|
||||
executed as well as remote partitioning through Spring Cloud Deployer are covered in
|
||||
this section.
|
||||
--
|
||||
|
||||
[[batch-association]]
|
||||
== Associating A Job Execution To The Task In Which It Was Executed
|
||||
== Associating a Job Execution to the Task in which It Was Executed
|
||||
|
||||
Spring Boot provides facilities for the execution of batch jobs easily within an über-jar.
|
||||
Spring Boot's support of this functionality allows for a developer to execute multiple
|
||||
batch jobs within that execution. Spring Cloud Task provides the ability to associate the
|
||||
execution of a job (a job execution) with a task's execution so that one can be traced
|
||||
back to the other.
|
||||
Spring Boot provides facilities for the execution of batch jobs within an über-jar.
|
||||
Spring Boot's support of this functionality lets a developer execute multiple batch jobs
|
||||
within that execution. Spring Cloud Task provides the ability to associate the execution
|
||||
of a job (a job execution) with a task's execution so that one can be traced back to the
|
||||
other.
|
||||
|
||||
This functionality is accomplished by using the `TaskBatchExecutionListener`. By default,
|
||||
this listener is auto configured in any context that has both a Spring Batch Job configured
|
||||
(via having a bean of type `Job` defined in the context) and the spring-cloud-task-batch jar
|
||||
is available within the classpath. The listener will be injected into all jobs.
|
||||
Spring Cloud Task achieves this functionality by using the `TaskBatchExecutionListener`.
|
||||
By default,
|
||||
this listener is auto configured in any context that has both a Spring Batch Job
|
||||
configured (by having a bean of type `Job` defined in the context) and the
|
||||
`spring-cloud-task-batch` jar on the classpath. The listener is injected into all jobs
|
||||
that meet those conditions.
|
||||
|
||||
[[batch-association-override]]
|
||||
=== Overriding the TaskBatchExecutionListener
|
||||
|
||||
To prevent the listener from being injected into any batch jobs within the current context,
|
||||
the autoconfiguration can be disabled via standard Spring Boot mechanisms.
|
||||
To prevent the listener from being injected into any batch jobs within the current
|
||||
context, you can disable the autoconfiguration by using standard Spring Boot mechanisms.
|
||||
|
||||
To only have the listener injected into particular jobs within the context, the
|
||||
`batchTaskExecutionListenerBeanPostProcessor` may be overridden and a list of job bean ids
|
||||
can be provided:
|
||||
To only have the listener injected into particular jobs within the context, override the
|
||||
`batchTaskExecutionListenerBeanPostProcessor` and provide a list of job bean IDs, as shown
|
||||
in the following example:
|
||||
|
||||
```
|
||||
[source,java]
|
||||
----
|
||||
public TaskBatchExecutionListenerBeanPostProcessor batchTaskExecutionListenerBeanPostProcessor() {
|
||||
TaskBatchExecutionListenerBeanPostProcessor postProcessor =
|
||||
new TaskBatchExecutionListenerBeanPostProcessor();
|
||||
@@ -43,29 +46,31 @@ public TaskBatchExecutionListenerBeanPostProcessor batchTaskExecutionListenerBea
|
||||
|
||||
return postProcessor;
|
||||
}
|
||||
```
|
||||
NOTE: A sample batch application can be found in the samples module
|
||||
of the Spring Cloud Task Project
|
||||
----
|
||||
|
||||
NOTE: You can find a sample batch application in the samples module of the Spring Cloud
|
||||
Task Project,
|
||||
https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples/batch-job[here].
|
||||
|
||||
|
||||
[[batch-partitioning]]
|
||||
== Remote Partitioning
|
||||
|
||||
Spring Cloud Deployer provides facilities for launching Spring Boot based applications on
|
||||
most cloud infrastructures. The `DeployerPartitionHandler` and
|
||||
Spring Cloud Deployer provides facilities for launching Spring Boot-based applications on
|
||||
most cloud infrastructures. The `DeployerPartitionHandler` and
|
||||
`DeployerStepExecutionHandler` delegate the launching of worker step executions to Spring
|
||||
Cloud Deployer.
|
||||
|
||||
To configure the `DeployerStepExecutionHandler`, a `Resource` representing the Spring Boot
|
||||
über-jar to be executed, a `TaskLauncher`, and a `JobExplorer` are all required. You can
|
||||
configure any environment properties as well as the max number of workers to be executing
|
||||
at once, the interval to poll for the results (defaults to 10 seconds), and a timeout
|
||||
(defaults to -1 or no timeout). An example of configuring this `PartitionHandler` would
|
||||
look like the following:
|
||||
To configure the `DeployerStepExecutionHandler`, you must provide a `Resource`
|
||||
representing the Spring Boot über-jar to be executed, a `TaskLauncher`, and a
|
||||
`JobExplorer`. You can configure any environment properties as well as the max number of
|
||||
workers to be executing at once, the interval to poll for the results (defaults to 10
|
||||
seconds), and a timeout (defaults to -1 or no timeout). The following example shows how
|
||||
configuring this `PartitionHandler` might look:
|
||||
|
||||
```
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public PartitionHandler partitionHandler(TaskLauncher taskLauncher,
|
||||
JobExplorer jobExplorer) throws Exception {
|
||||
@@ -88,28 +93,31 @@ public PartitionHandler partitionHandler(TaskLauncher taskLauncher,
|
||||
commandLineArgs.add("--spring.cloud.task.initialize.enable=false");
|
||||
commandLineArgs.add("--spring.batch.initializer.enabled=false");
|
||||
|
||||
partitionHandler.setCommandLineArgsProvider(new PassThroughCommandLineArgsProvider(commandLineArgs));
|
||||
partitionHandler.setCommandLineArgsProvider(
|
||||
new PassThroughCommandLineArgsProvider(commandLineArgs));
|
||||
partitionHandler.setEnvironmentVariablesProvider(new NoOpEnvironmentVariablesProvider());
|
||||
partitionHandler.setMaxWorkers(2);
|
||||
partitionHandler.setApplicationName("PartitionedBatchJobTask");
|
||||
|
||||
return partitionHandler;
|
||||
}
|
||||
```
|
||||
----
|
||||
|
||||
NOTE: When passing environment variables to partitions, each partition may
|
||||
be on a different machine with a different environment settings.
|
||||
So only pass those that are required.
|
||||
be on a different machine with different environment settings.
|
||||
Consequently, you should pass only those environment variables that are required.
|
||||
|
||||
The `Resource` to be executed is expected to be a Spring Boot über-jar with a
|
||||
`DeployerStepExecutionHandler` configured as a `CommandLineRunner` in the current context.
|
||||
The repository enumerated in the example above should be the location of the remote repository
|
||||
from which the über-jar is located. Both the master and slave are expected to have
|
||||
visibility into the same data store being used as the job repository and task repository.
|
||||
Once the underlying infrastructure has bootstrapped the Spring Boot jar and Spring Boot
|
||||
has launched the `DeployerStepExecutionHandler`, the step handler will execute the Step
|
||||
requested. An example of configuring the `DefaultStepExecutionHandler` is show below:
|
||||
The repository enumerated in the preceding example should be the remote repository in
|
||||
which the über-jar is located. Both the master and slave are expected to have visibility
|
||||
into the same data store being used as the job repository and task repository. Once the
|
||||
underlying infrastructure has bootstrapped the Spring Boot jar and Spring Boot has
|
||||
launched the `DeployerStepExecutionHandler`, the step handler executes the requested
|
||||
`Step`. The following example shows how to configure the `DefaultStepExecutionHandler`:
|
||||
|
||||
```
|
||||
[source,java]
|
||||
----
|
||||
@Bean
|
||||
public DeployerStepExecutionHandler stepExecutionHandler(JobExplorer jobExplorer) {
|
||||
DeployerStepExecutionHandler handler =
|
||||
@@ -117,24 +125,30 @@ public DeployerStepExecutionHandler stepExecutionHandler(JobExplorer jobExplorer
|
||||
|
||||
return handler;
|
||||
}
|
||||
```
|
||||
NOTE: A sample remote partition application can be found in the samples module
|
||||
of the Spring Cloud Task Project
|
||||
----
|
||||
|
||||
NOTE: You can find a sample remote partition application in the samples module of the
|
||||
Spring Cloud Task project,
|
||||
https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples/partitioned-batch-job[here].
|
||||
|
||||
=== Notes on developing a batch partitioned app for the Yarn platform
|
||||
=== Notes on Developing a Batch-partitioned Application for the Yarn Platform
|
||||
|
||||
* When deploying partitioned apps on the Yarn platform be sure to use the
|
||||
* When deploying partitioned applications on the Yarn platform, you must use the
|
||||
following dependency for the Spring Cloud Yarn Deployer
|
||||
(with a version 1.0.2 or higher):
|
||||
```
|
||||
+
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-deployer-yarn</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
* Add the following dependency to the dependency management for a transient dependency required by Yarn:
|
||||
```
|
||||
----
|
||||
* For a transient dependency required by Yarn, add the following dependency to the
|
||||
dependency management:
|
||||
+
|
||||
[source,xml]
|
||||
----
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
...
|
||||
@@ -146,45 +160,53 @@ following dependency for the Spring Cloud Yarn Deployer
|
||||
</dependencies>
|
||||
...
|
||||
</dependencyManagement>
|
||||
```
|
||||
* Also add the following property to your application.properties: `spring.yarn.container.keepContextAlive=false`.
|
||||
* When setting up environment variables for the partitions in the PartitionHandler it is recommended that you do not
|
||||
copy the current working environment properties.
|
||||
----
|
||||
* You should also add the following property to your application.properties:
|
||||
`spring.yarn.container.keepContextAlive=false`.
|
||||
* When setting up environment variables for the partitions in the PartitionHandler, we
|
||||
recommend that you do not copy the current working environment properties.
|
||||
|
||||
=== Notes on developing a batch partitioned app for the Kubernetes platform
|
||||
* When deploying partitioned apps on the Kubernetes platform be sure to use the
|
||||
following dependency for the Spring Cloud Kubernetes Deployer:
|
||||
```
|
||||
=== Notes on Developing a Batch-partitioned application for the Kubernetes Platform
|
||||
|
||||
* When deploying partitioned apps on the Kubernetes platform, you must use the following
|
||||
dependency for the Spring Cloud Kubernetes Deployer:
|
||||
+
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-deployer-kubernetes</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
----
|
||||
* The application name for the task application and its partitions need to follow
|
||||
the following regex pattern: `[a-z0-9]([-a-z0-9]*[a-z0-9])`.
|
||||
Otherwise, an exception is thrown.
|
||||
|
||||
* Application name for the task application and its partitions need to follow
|
||||
the following regex pattern `[a-z0-9]([-a-z0-9]*[a-z0-9])`.
|
||||
Else an exception will be thrown.
|
||||
=== Notes on Developing a Batch-partitioned Application for the Mesos Platform
|
||||
|
||||
=== Notes on developing a batch partitioned app for the Mesos platform
|
||||
* When deploying partitioned apps on the Mesos platform be sure to use the
|
||||
following dependency for the Spring Cloud Mesos Deployer:
|
||||
```
|
||||
* When deploying partitioned apps on the Mesos platform, you must use the following
|
||||
dependency for the Spring Cloud Mesos Deployer:
|
||||
+
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-deployer-mesos</artifactId>
|
||||
</dependency>
|
||||
```
|
||||
----
|
||||
|
||||
* When configuring the partition handler, do not add any command line arguments to
|
||||
the `CommandLineArgsProvider`. This is due to Chronos adding the command line
|
||||
args to the Mesos ID. Thus when launching the partition on Mesos this can cause
|
||||
the partition to fail to start if command line arg contains characters such as
|
||||
`/` or `:`.
|
||||
* When configuring the partition handler, do not add any command line arguments to the
|
||||
`CommandLineArgsProvider`. You need to avoid adding arguments, because Chronos adds the
|
||||
command line args to the Mesos ID. If the command line arguments contains characters such
|
||||
as `/` or `:` when launching the partition on Mesos, the partition fails to start .
|
||||
|
||||
=== Notes on developing a batch partitioned app for the Cloud Foundry platform
|
||||
* When deploying partitioned apps on the Cloud Foundry platform be sure to use
|
||||
the following dependencies for the Spring Cloud Cloud Foundry Deployer:
|
||||
```
|
||||
=== Notes on Developing a Batch-partitioned Application for the Cloud Foundry Platform
|
||||
|
||||
* When deploying partitioned apps on the Cloud Foundry platform, you must use the
|
||||
following dependencies for the Spring Cloud Foundry Deployer:
|
||||
+
|
||||
[source,xml]
|
||||
----
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-deployer-cloudfoundry</artifactId>
|
||||
@@ -199,25 +221,25 @@ the following dependencies for the Spring Cloud Cloud Foundry Deployer:
|
||||
<artifactId>reactor-netty</artifactId>
|
||||
<version>0.5.1.RELEASE</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
----
|
||||
* When configuring the partition handler, Cloud Foundry Deployment
|
||||
environment variables need to be established so that the partition handler
|
||||
can start the partitions. The following list shows the required environment
|
||||
variables:
|
||||
- spring_cloud_deployer_cloudfoundry_url
|
||||
- spring_cloud_deployer_cloudfoundry_org
|
||||
- spring_cloud_deployer_cloudfoundry_space
|
||||
- spring_cloud_deployer_cloudfoundry_domain
|
||||
- spring_cloud_deployer_cloudfoundry_username
|
||||
- spring_cloud_deployer_cloudfoundry_password
|
||||
- spring_cloud_deployer_cloudfoundry_services
|
||||
- spring_cloud_deployer_cloudfoundry_taskTimeout
|
||||
- `spring_cloud_deployer_cloudfoundry_url`
|
||||
- `spring_cloud_deployer_cloudfoundry_org`
|
||||
- `spring_cloud_deployer_cloudfoundry_space`
|
||||
- `spring_cloud_deployer_cloudfoundry_domain`
|
||||
- `spring_cloud_deployer_cloudfoundry_username`
|
||||
- `spring_cloud_deployer_cloudfoundry_password`
|
||||
- `spring_cloud_deployer_cloudfoundry_services`
|
||||
- `spring_cloud_deployer_cloudfoundry_taskTimeout`
|
||||
|
||||
An example set of deployment environment variables for a partitioned task that
|
||||
uses a `mysql` database service would look something like this:
|
||||
uses a `mysql` database service might resemble the following:
|
||||
|
||||
```
|
||||
[source,bash]
|
||||
----
|
||||
spring_cloud_deployer_cloudfoundry_url=https://api.local.pcfdev.io
|
||||
spring_cloud_deployer_cloudfoundry_org=pcfdev-org
|
||||
spring_cloud_deployer_cloudfoundry_space=pcfdev-space
|
||||
@@ -226,37 +248,38 @@ spring_cloud_deployer_cloudfoundry_username=admin
|
||||
spring_cloud_deployer_cloudfoundry_password=admin
|
||||
spring_cloud_deployer_cloudfoundry_services=mysql
|
||||
spring_cloud_deployer_cloudfoundry_taskTimeout=300
|
||||
```
|
||||
----
|
||||
|
||||
NOTE: When using PCF-Dev the following environment variable is also required:
|
||||
NOTE: When using PCF-Dev, the following environment variable is also required:
|
||||
`spring_cloud_deployer_cloudfoundry_skipSslValidation=true`
|
||||
|
||||
[[batch-informational-messages]]
|
||||
== Batch Informational Messages
|
||||
|
||||
Spring Cloud Task provides the ability for batch jobs to emit informational messages. This
|
||||
is covered in detail in the section
|
||||
<<stream.adoc#stream-integration-batch-events, Spring Batch Events>>.
|
||||
Spring Cloud Task provides the ability for batch jobs to emit informational messages. The
|
||||
"`<<stream.adoc#stream-integration-batch-events>>`" section covers this feature in detail.
|
||||
|
||||
[[batch-failures-and-tasks]]
|
||||
== Batch Job Exit Codes
|
||||
|
||||
As discussed before Spring Cloud Task applications support the ability to record the exit code of a task execution.
|
||||
However in cases where a user is running a Spring Batch Job within a task, regardless of how the Batch Job
|
||||
Execution completes the result of the task will always be zero when using default Batch/Boot behavior.
|
||||
Keep in mind that a task is a boot application and the exit code returned from
|
||||
the task is the same as a boot application.
|
||||
To override this behavior and allow the task to return an exit code other than zero
|
||||
(either 1 `the default` or based on the
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-application-exit[ExitCodeGenerator]
|
||||
specified) upon a batch job returning an
|
||||
As discussed <<features.adoc#features-lifecycle-exit-codes,earlier>>, Spring Cloud Task
|
||||
applications support the ability to record the exit code of a task execution. However, in
|
||||
cases where you run a Spring Batch Job within a task, regardless of how the Batch Job
|
||||
Execution completes, the result of the task is always zero when using the default
|
||||
Batch/Boot behavior. Keep in mind that a task is a boot application and that the exit code
|
||||
returned from the task is the same as a boot application.
|
||||
To override this behavior and allow the task to return an exit code other than zero when a
|
||||
batch job returns an
|
||||
https://docs.spring.io/spring-batch/4.0.x/reference/html/step.html#conditionalFlow[ExitStatus]
|
||||
of "FAILED", set `spring.cloud.task.batch.failOnJobFailure` to true.
|
||||
|
||||
This functionality does utilize a new `CommandLineRunner` that replaces the one provided
|
||||
by Spring Boot. By default it is configured with the same order. However, if you'd like
|
||||
to customize what order the `CommandLineRunner` is executed in, you can set it's order via
|
||||
the `spring.cloud.task.batch.commandLineRunnerOrder` property.
|
||||
To have your task return the exit code based on the result of the batch job
|
||||
execution, you will need to write your own `CommandLineRunner`.
|
||||
of `FAILED`, set `spring.cloud.task.batch.failOnJobFailure` to `true`. Then the exit code
|
||||
can be 1 (the default) or be based on the
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html#boot-features-application-exit[specified
|
||||
`ExitCodeGenerator`])
|
||||
|
||||
This functionality uses a new `CommandLineRunner` that replaces the one provided by Spring
|
||||
Boot. By default, it is configured with the same order. However, if you want to customize
|
||||
the order in which the `CommandLineRunner` is run, you can set its order by setting the
|
||||
`spring.cloud.task.batch.commandLineRunnerOrder` property. To have your task return the
|
||||
exit code based on the result of the batch job execution, you need to write your own
|
||||
`CommandLineRunner`.
|
||||
//TODO Great place for a example showing how a custom CommandLineRunner
|
||||
|
||||
@@ -4,51 +4,55 @@
|
||||
|
||||
[[partintro]]
|
||||
--
|
||||
This section goes into more detail about Spring Cloud Task. How to use it, how to
|
||||
configure it, as well as the appropriate extension points are all covered in this section.
|
||||
This section goes into more detail about Spring Cloud Task, including how to use it, how
|
||||
to configure it, and the appropriate extension points.
|
||||
--
|
||||
|
||||
[[features-lifecycle]]
|
||||
== The lifecycle of a Spring Cloud Task
|
||||
|
||||
In most cases, the modern cloud environment is designed around the execution of processes
|
||||
that are not expected to end. If they do, they are typically restarted. While most
|
||||
platforms do have some method to execute a process that isn't restarted when it ends, the
|
||||
results of that execution are typically not maintained in a consumable way. Spring Cloud
|
||||
Task brings the ability to execute short lived processes in an environment and record the
|
||||
results. This allows for a microservices architecture around short lived processes as
|
||||
well as longer running services via the integration of tasks by messages.
|
||||
that are not expected to end. If they do end, they are typically restarted. While most
|
||||
platforms do have some way to run a process that is not restarted when it ends, the
|
||||
results of that run are typically not maintained in a consumable way. Spring Cloud
|
||||
Task offers the ability to execute short-lived processes in an environment and record the
|
||||
results. Doing so allows for a microservices architecture around short-lived processes as
|
||||
well as longer running services through the integration of tasks by messages.
|
||||
|
||||
While this functionality is useful in a cloud environment, the same issues can arise in a
|
||||
traditional deployment model as well. When executing Spring Boot applications via a
|
||||
scheduler like cron, it can be useful to be able to monitor the results of the application
|
||||
after it's completion.
|
||||
traditional deployment model as well. When running Spring Boot applications with a
|
||||
scheduler such as cron, it can be useful to be able to monitor the results of the
|
||||
application after its completion.
|
||||
|
||||
A Spring Cloud Task takes the approach that a Spring Boot application can have a start and an
|
||||
end and still be successful. Batch applications are just one example of where short lived
|
||||
processes can be helpful. Spring Cloud Task records lifecycle events of a given task.
|
||||
Spring Cloud Task takes the approach that a Spring Boot application can have a start and
|
||||
an end and still be successful. Batch applications are one example of how processes that
|
||||
are expected to end (and that are often short-lived) can be helpful.
|
||||
|
||||
The lifecycle consists of a single task execution. This is a physical execution of a
|
||||
Spring Boot application configured to be a task (annotated with the `@EnableTask`
|
||||
Spring Cloud Task records the lifecycle events of a given task. Most long-running
|
||||
processes, typified by most web applications, do not save their lifecycle events. The
|
||||
tasks at the heart of Spring Cloud Task do.
|
||||
|
||||
The lifecycle consists of a single task execution. This is a physical execution of a
|
||||
Spring Boot application configured to be a task (that is, it has the `@EnableTask`
|
||||
annotation).
|
||||
|
||||
At the beginning of a task before any `CommandLineRunner` or `ApplicationRunner`
|
||||
implementations have been executed, an entry in the `TaskRepository` is created recording
|
||||
the start event. This event is triggered via `SmartLifecycle#start` being triggered by
|
||||
Spring Framework. This indicates to the system that all beans are ready for use and is
|
||||
before the execution of any of the `CommandLineRunner` or `ApplicationRunner`
|
||||
implementations provided by Spring Boot.
|
||||
At the beginning of a task, before any `CommandLineRunner` or `ApplicationRunner`
|
||||
implementations have been run, an entry in the `TaskRepository` that records the start
|
||||
event is created. This event is triggered through `SmartLifecycle#start` being triggered
|
||||
by the Spring Framework. This indicates to the system that all beans are ready for use and
|
||||
comes before running any of the `CommandLineRunner` or `ApplicationRunner` implementations
|
||||
provided by Spring Boot.
|
||||
|
||||
NOTE: The recording of a task will only occur upon the successful bootstrapping of an
|
||||
`ApplicationContext`. If the context fails to bootstrap at all, the task's execution will
|
||||
not be recorded.
|
||||
NOTE: The recording of a task only occurs upon the successful bootstrapping of an
|
||||
`ApplicationContext`. If the context fails to bootstrap at all, the task's run is not
|
||||
recorded.
|
||||
|
||||
Upon completion of all of the `*Runner#run` calls from Spring Boot or the failure of an
|
||||
`ApplicationContext` (indicated via a `ApplicationFailedEvent`), the task execution is
|
||||
`ApplicationContext` (indicated by an `ApplicationFailedEvent`), the task execution is
|
||||
updated in the repository with the results.
|
||||
|
||||
NOTE: If the application requires the `ApplicationContext` to be closed at the
|
||||
completion of a task (all `*Runner#run` methods are called and the task
|
||||
completion of a task (all `*Runner#run` methods have been called and the task
|
||||
repository has been updated), set the property `spring.cloud.task.closecontext_enable`
|
||||
to true.
|
||||
|
||||
@@ -62,161 +66,149 @@ consists of the following information:
|
||||
|Field |Description
|
||||
|
||||
|`executionid`
|
||||
|The unique id for the task's execution.
|
||||
|The unique ID for the task's run.
|
||||
|
||||
|`exitCode`
|
||||
|The exit code generated from an `ExitCodeExceptionMapper` implementation. If there is no
|
||||
exit code generated, but an `ApplicationFailedEvent` is thrown, 1 is set. Otherwise, it's
|
||||
|The exit code generated from an `ExitCodeExceptionMapper` implementation. If there is no
|
||||
exit code generated but an `ApplicationFailedEvent` is thrown, 1 is set. Otherwise, it is
|
||||
assumed to be 0.
|
||||
|
||||
|`taskName`
|
||||
|The name for the task as determined by the configured `TaskNameResolver`.
|
||||
|The name for the task, as determined by the configured `TaskNameResolver`.
|
||||
|
||||
|`startTime`
|
||||
|The time the task was started as indicated by the `SmartLifecycle#start` call.
|
||||
|The time the task was started, as indicated by the `SmartLifecycle#start` call.
|
||||
|
||||
|`endTime`
|
||||
|The time the task was completed as indicated by the `ApplicationReadyEvent`.
|
||||
|The time the task was completed, as indicated by the `ApplicationReadyEvent`.
|
||||
|
||||
|`exitMessage`
|
||||
|Any information available at the time of exit. This can programmatically be set via a
|
||||
|Any information available at the time of exit. This can programmatically be set by a
|
||||
`TaskExecutionListener`.
|
||||
|
||||
|`errorMessage`
|
||||
|If an exception is the cause of the end of the task (as indicated via an
|
||||
`ApplicationFailedEvent`), the stack trace for that exception will be stored here.
|
||||
|If an exception is the cause of the end of the task (as indicated by an
|
||||
`ApplicationFailedEvent`), the stack trace for that exception is stored here.
|
||||
|
||||
|`arguments`
|
||||
|A `List` of the string command line arguments as they were passed into the executable boot
|
||||
application.
|
||||
|A `List` of the string command line arguments as they were passed into the executable
|
||||
boot application.
|
||||
|===
|
||||
|
||||
[[features-lifecycle-exit-codes]]
|
||||
=== Mapping Exit Codes
|
||||
|
||||
When a task completes, it will want to return an exit code to the OS. If we take a look
|
||||
at our original example, we can see that we are not controlling that aspect of our
|
||||
application. So if an exception is thrown, the JVM will return a code that may or may not
|
||||
be of any use to you in the debugging of that.
|
||||
When a task completes, it tries to return an exit code to the OS. If we take a look
|
||||
at our <<getting-started-developing-first-task,original example>>, we can see that we are
|
||||
not controlling that aspect of our application. So, if an exception is thrown, the JVM
|
||||
returns a code that may or may not be of any use to you in debugging.
|
||||
|
||||
As such, Spring Boot provides an interface, `ExitCodeExceptionMapper` that allows you to
|
||||
map uncaught exceptions to exit codes. This allows you to be able to indicate at that
|
||||
level what went wrong. Also, by mapping exit codes in this manner, Spring Cloud Task will
|
||||
record the exit code returned.
|
||||
Consequently, Spring Boot provides an interface, `ExitCodeExceptionMapper`, that lets you
|
||||
map uncaught exceptions to exit codes. Doing so lets you indicate, at the level of exit
|
||||
codes, what went wrong. Also, by mapping exit codes in this manner, Spring Cloud Task
|
||||
records the returned exit code.
|
||||
|
||||
If the task is terminated with a SIG-INT or a SIG-TERM, the exit code will be zero unless
|
||||
If the task terminates with a SIG-INT or a SIG-TERM, the exit code is zero unless
|
||||
otherwise specified within the code.
|
||||
|
||||
NOTE: While the task is running the exit code will be stored as a null in the repository.
|
||||
Once complete the appropriate exit code will be stored based on the guidelines enumerated
|
||||
above.
|
||||
NOTE: While the task is running, the exit code is stored as a null in the repository.
|
||||
Once the task completes, the appropriate exit code is stored based on the guidelines described
|
||||
earlier in this section.
|
||||
|
||||
[[features-configuration]]
|
||||
== 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
|
||||
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.
|
||||
|
||||
[[features-data-source]]
|
||||
=== 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`.
|
||||
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 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 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 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`.
|
||||
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`.
|
||||
|
||||
[[features-table-prefix]]
|
||||
=== 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.
|
||||
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>
|
||||
```
|
||||
`spring.cloud.task.tablePrefix=yourPrefix`
|
||||
|
||||
[[features-table-initialization]]
|
||||
=== 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`.
|
||||
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=<true or false>
|
||||
```
|
||||
`spring.cloud.task.initialize.enable=false`
|
||||
|
||||
It defaults to `true`.
|
||||
|
||||
[[features-generated_task_id]]
|
||||
=== Externally Generated Task Id
|
||||
=== 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.
|
||||
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.
|
||||
|
||||
The TaskExecution can be created by calling the `createTaskExecution` method on
|
||||
an implementation of the TaskRepository that references the datastore storing
|
||||
the TaskExecutions.
|
||||
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
|
||||
In order to configure your Task to use a generated `TaskExecutionId`, add the
|
||||
following property:
|
||||
|
||||
```
|
||||
spring.cloud.task.executionid=<yourtaskId>
|
||||
```
|
||||
`spring.cloud.task.executionid=yourtaskId`
|
||||
|
||||
[[features-external_task_id]]
|
||||
=== 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
|
||||
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
|
||||
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.external-execution-id=<externalTaskId>`
|
||||
|
||||
[[features-parent_task_id]]
|
||||
=== 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 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>
|
||||
```
|
||||
`spring.cloud.task.parent-execution-id=<parentExecutionTaskId>`
|
||||
|
||||
[[features-task-configurer]]
|
||||
=== 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` 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` allows the configuration of three main components:
|
||||
The `TaskConfigurer` lets you configure three main components:
|
||||
|
||||
|===
|
||||
|Component |Description |Default (provided by `DefaultTaskConfigurer`)
|
||||
@@ -226,63 +218,66 @@ The `TaskConfigurer` allows the configuration of three main components:
|
||||
|`SimpleTaskRepository`
|
||||
|
||||
|`TaskExplorer`
|
||||
|The implementation of the `TaskExplorer` (a component for read only access to the task
|
||||
|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,
|
||||
|A transaction manager to be used when running 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.
|
||||
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.
|
||||
|
||||
[[features-task-name]]
|
||||
=== 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.
|
||||
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 will use the
|
||||
By default, Spring Cloud Task provides the `SimpleTaskNameResolver`, which uses the
|
||||
following options (in order of precedence):
|
||||
|
||||
. A Spring Boot property (configured any of the ways Spring Boot allows)
|
||||
. A Spring Boot property (configured in any of the ways Spring Boot allows) called
|
||||
`spring.cloud.task.name`.
|
||||
. The application name as resolved using Spring Boot's rules (obtained via
|
||||
. The application name as resolved using Spring Boot's rules (obtained through
|
||||
`ApplicationContext#getId`).
|
||||
|
||||
[[features-task-execution-listener]]
|
||||
=== 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:
|
||||
`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 the storing the `TaskExecution` into the `TaskRepository`
|
||||
. `onTaskEnd` - prior to the updating of the `TaskExecution` entry in the `TaskRepository`
|
||||
* `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.
|
||||
* `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
|
||||
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`
|
||||
* `@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.
|
||||
* `@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:
|
||||
|
||||
[source,java]
|
||||
---
|
||||
public class MyBean {
|
||||
|
||||
@BeforeTask
|
||||
@@ -297,69 +292,71 @@ marking the final state of the task.
|
||||
public void methodC(TaskExecution taskExecution, Throwable throwable) {
|
||||
}
|
||||
}
|
||||
```
|
||||
---
|
||||
|
||||
[[features-task-execution-listener-Exceptions]]
|
||||
==== 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.
|
||||
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 will be the exit code that was reported by the https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/ExitCodeEvent.html[ExitCodeEvent]. If
|
||||
no `ExitCodeEvent` is emitted then the Exception thrown will be evaluated to see
|
||||
event handler is the exit code that was reported by the
|
||||
https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/ExitCodeEvent.html[ExitCodeEvent].
|
||||
If no `ExitCodeEvent` is emitted, the Exception thrown is evaluated to see
|
||||
if it is of type
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exit[ExitCodeGenerator]
|
||||
, if so it will return the exit code from the `ExitCodeGenerator` else one
|
||||
will be returned.
|
||||
https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-application-exit[ExitCodeGenerator].
|
||||
If so, it returns the exit code from the `ExitCodeGenerator`. Otherwise, `1`
|
||||
is returned.
|
||||
|
||||
|
||||
|
||||
[[features-task-execution-listener-exit-messages]]
|
||||
==== 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` :
|
||||
```
|
||||
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` :
|
||||
|
||||
[source,java]
|
||||
@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:
|
||||
|
||||
. onTaskEnd
|
||||
. onTaskFailed
|
||||
. onTaskStartup
|
||||
An `ExitMessage` can be set at any of the listener events (`onTaskStartup`,
|
||||
`onTaskFailed`, and `onTaskEnd`). The order of precedence for the three listeners follows:
|
||||
|
||||
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
|
||||
. `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`.
|
||||
|
||||
=== 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 <<features-task-name, 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 <<features-task-name, 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:
|
||||
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 <<features-task-name, 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
|
||||
<<features-task-name, 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:
|
||||
|
||||
[source,xml]
|
||||
---
|
||||
<dependency>
|
||||
|
||||
@@ -4,54 +4,56 @@
|
||||
|
||||
[[partintro]]
|
||||
--
|
||||
If you're just getting started with Spring Cloud Task, this is the section
|
||||
for you! Here we answer the basic "`what?`", "`how?`" and "`why?`" questions. You'll
|
||||
find a gentle introduction to Spring Cloud Task. We'll then build our first Spring Cloud
|
||||
Task application, discussing some core principles as we go.
|
||||
If you are just getting started with Spring Cloud Task, you should read this section.
|
||||
Here, we answer the basic "`what?`", "`how?`", and "`why?`" questions. We start with a
|
||||
gentle introduction to Spring Cloud Task. We then build a Spring Cloud Task application,
|
||||
discussing some core principles as we go.
|
||||
--
|
||||
|
||||
[[getting-started-introducing-spring-cloud-task]]
|
||||
== Introducing Spring Cloud Task
|
||||
|
||||
Spring Cloud Task makes it easy to create short lived microservices. We provide
|
||||
capabilities that allow short lived JVM processes to be executed on demand in a production
|
||||
Spring Cloud Task makes it easy to create short-lived microservices. It provides
|
||||
capabilities that let short lived JVM processes be executed on demand in a production
|
||||
environment.
|
||||
|
||||
[[getting-started-system-requirements]]
|
||||
== System Requirements
|
||||
|
||||
You need Java installed (Java 7 or better, we recommend Java 8) and to build you need to have Maven installed as well.
|
||||
You need to have Java installed (Java 8 or better). To build, you need to have Maven
|
||||
installed as well.
|
||||
|
||||
=== Database Requirements
|
||||
|
||||
Spring Cloud Task uses a relational database to store the results of an executed task.
|
||||
While you can begin developing a task without a database (the status of the task is logged
|
||||
as part of the task repository's updates), for production environments, you'll want to
|
||||
utilize a supported database. Below is a list of the ones currently supported:
|
||||
as part of the task repository's updates), for production environments, you want to
|
||||
use a supported database. Spring Cloud Task currently supports the following databases:
|
||||
|
||||
- DB2
|
||||
- H2
|
||||
- HSQLDB
|
||||
- MySql
|
||||
- Oracle
|
||||
- Postgres
|
||||
- SqlServer
|
||||
* DB2
|
||||
* H2
|
||||
* HSQLDB
|
||||
* MySql
|
||||
* Oracle
|
||||
* Postgres
|
||||
* SqlServer
|
||||
|
||||
[[getting-started-developing-first-task]]
|
||||
== Developing your first Spring Cloud Task application
|
||||
== Developing Your First Spring Cloud Task Application
|
||||
|
||||
A good place to start is with a simple "Hello World!" application so we'll create the
|
||||
Spring Cloud Task equivalent to highlight the features of the framework. We'll use Apache
|
||||
Maven as a build tool for this project since most IDEs have good support for it.
|
||||
A good place to start is with a simple "`Hello, World!`" application, so we create the
|
||||
Spring Cloud Task equivalent to highlight the features of the framework. Most IDEs have
|
||||
good support for Apache Maven, so we use it as the build tool for this project.
|
||||
|
||||
NOTE: The spring.io web site contains many “Getting Started” guides that use Spring Boot.
|
||||
If you’re looking to solve a specific problem; check there first. You can shortcut the
|
||||
steps below by going to start.spring.io and creating a new project. This will
|
||||
automatically generate a new project structure so that you can start coding right the way.
|
||||
Check the documentation for more details.
|
||||
NOTE: The spring.io web site contains many https://spring.io/guides[“`Getting Started`”
|
||||
guides] that use Spring Boot. If you need to solve a specific problem, check there first.
|
||||
You can shortcut the following steps by going to the
|
||||
http://start.spring.io/[Spring Initializr] and creating a new project. Doing so
|
||||
automatically generates a new project structure so that you can start coding right away.
|
||||
We recommend experimenting with the Spring Initializr to become familiar with it.
|
||||
|
||||
Before we begin, open a terminal to check that you have valid versions of Java and Maven
|
||||
installed.
|
||||
installed, as shown in the following two listings:
|
||||
|
||||
[source]
|
||||
$ java -version
|
||||
@@ -65,14 +67,15 @@ Apache Maven 3.2.3 (33f8c3e1027c3ddde99d3cdebad2656a31e8fdf4; 2014-08-11T15:58:1
|
||||
Maven home: /usr/local/Cellar/maven/3.2.3/libexec
|
||||
Java version: 1.8.0_31, vendor: Oracle Corporation
|
||||
|
||||
NOTE: This sample needs to be created in its own folder. Subsequent instructions assume
|
||||
you have created a suitable folder and that it is your "current directory".
|
||||
NOTE: This sample needs to be created in its own folder. Subsequent instructions assume
|
||||
you have created a suitable folder and that it is your "`current directory.`"
|
||||
|
||||
[[getting-started-creating-the-pom]]
|
||||
=== Creating the POM
|
||||
|
||||
We need to start by creating a Maven `pom.xml` file. The `pom.xml` is the recipe that
|
||||
will be used to build your project. Open your favorite text editor and add the following:
|
||||
We need to start by creating a Maven `pom.xml` file. The `pom.xml` file contains the
|
||||
recipe that Maven uses to build your project. To create the pom.xml file, open your
|
||||
favorite text editor and add the following:
|
||||
|
||||
[code,xml]
|
||||
----
|
||||
@@ -116,29 +119,30 @@ will be used to build your project. Open your favorite text editor and add the
|
||||
</project>
|
||||
----
|
||||
|
||||
This should give you a working build. You can test it out by running `mvn package` (you
|
||||
can ignore the "jar will be empty - no content was marked for inclusion!" warning for
|
||||
now).
|
||||
Creating a `pom.xml` file with the preceding content should give you a working build. You
|
||||
can test it by running `mvn package` (for now, you can ignore the "jar will be empty - no
|
||||
content was marked for inclusion!" warning ).
|
||||
|
||||
NOTE: At this point you could import the project into an IDE (most modern Java IDE's
|
||||
include built-in support for Maven). For simplicity we will continue to use a plain text
|
||||
NOTE: At this point, you could import the project into an IDE (most modern Java IDE's
|
||||
include built-in support for Maven). For simplicity, we continue to use a plain text
|
||||
editor for this example.
|
||||
|
||||
[[getting-started-adding-classpath-dependencies]]
|
||||
=== Adding classpath dependencies
|
||||
|
||||
A Spring Cloud Task is made up of a Spring Boot application that is expected to end. In
|
||||
our POM above, we created the shell of a Spring Boot application from a dependency
|
||||
perspective by setting our parent to use the `spring-boot-starter-parent`.
|
||||
A Spring Cloud Task is made up of a Spring Boot application that is expected to end. In
|
||||
the `pom.xml` file we showed earlier, we created the shell of a Spring Boot application by
|
||||
setting our parent to use the `spring-boot-starter-parent`.
|
||||
|
||||
Spring Boot provides a number of additional "Starter POMs". Some of which are appropriate
|
||||
for use within tasks (`spring-boot-starter-batch`, `spring-boot-starter-jdbc`, etc) and
|
||||
some may not be ('spring-boot-starter-web` is probably not going to be used in a task).
|
||||
The indicator of if a starter makes sense or not comes down to if the resulting
|
||||
application will end (batch based applications typically end, the
|
||||
`spring-boot-starter-web` dependency bootstraps a servlet container which probably wont').
|
||||
Spring Boot provides a number of additional "`Starter POMs`". Some of them are appropriate
|
||||
for use within tasks (`spring-boot-starter-batch`, `spring-boot-starter-jdbc`, and
|
||||
others), and some may not be ('spring-boot-starter-web` is probably not going to be used
|
||||
in a task). The best indicator of which starter makes sense is whether the resulting
|
||||
application should end. Batch-based applications typically end. Conversely, the
|
||||
`spring-boot-starter-web` dependency bootstraps a servlet container, which better suits
|
||||
applications that continue.
|
||||
|
||||
For this example, we'll only need to add a single additional dependency, the one for
|
||||
For this example, we need only to add a single additional dependency -- the one for
|
||||
Spring Cloud Task itself:
|
||||
|
||||
[source,xml]
|
||||
@@ -149,11 +153,12 @@ Spring Cloud Task itself:
|
||||
</dependency>
|
||||
|
||||
[[getting-started-writing-the-code]]
|
||||
=== Writing the code
|
||||
=== Writing the Code
|
||||
|
||||
To finish our application, we need to create a single Java file. Maven will compile the
|
||||
sources from `src/main/java` by default so you need to create that folder structure. Then
|
||||
add a file named `src/main/java/com/example/SampleTask.java`:
|
||||
To finish our application, we need to create a single Java file. By default, Maven
|
||||
compiles the sources from `src/main/java`, so you need to create that folder structure.
|
||||
Then you need to add a file named `src/main/java/com/example/SampleTask.java`, as shown
|
||||
in the following example:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -181,20 +186,21 @@ public class SampleTask {
|
||||
|
||||
@Override
|
||||
public void run(String... strings) throws Exception {
|
||||
System.out.println("Hello World!");
|
||||
System.out.println("Hello, World!");
|
||||
}
|
||||
}
|
||||
}
|
||||
----
|
||||
|
||||
While it may not look like much, quite a bit is going on. To read more about the Spring
|
||||
Boot specifics, take a look at their reference documentation here:
|
||||
http://docs.spring.io/spring-boot/docs/current/reference/html/[http://docs.spring.io/spring-boot/docs/current/reference/html/]
|
||||
While it may seem small, quite a bit is going on. For more about Spring
|
||||
Boot specifics, see the
|
||||
http://docs.spring.io/spring-boot/docs/current/reference/html/[Spring Boot reference documentation].
|
||||
|
||||
We'll also need to create an `application.properties` in `src/main/resources`. We'll
|
||||
configure two properties in it: the application name (which is translated to the task name)
|
||||
and we'll set the logging for spring cloud task to `DEBUG` so that we can see what's going
|
||||
on:
|
||||
We also need to create an `application.properties` file in `src/main/resources`. We need
|
||||
to configure two properties in `application.properties`: We need to set the application
|
||||
name (which is translated to the task name), and we need to set the logging for Spring
|
||||
Cloud Task to `DEBUG` so that we can see what's going on. The following example shows how
|
||||
to do both:
|
||||
|
||||
[source]
|
||||
----
|
||||
@@ -205,23 +211,23 @@ spring.application.name=helloWorld
|
||||
[[getting-started-at-task]]
|
||||
==== The @EnableTask annotation
|
||||
|
||||
The first non boot annotation in our example is the `@EnableTask` annotation. This class
|
||||
level annotation tells Spring Cloud Task to bootstrap it's functionality. This occurs by
|
||||
importing an additional configuration class, `SimpleTaskConfiguration` by default. This
|
||||
The first non-boot annotation in our example is the `@EnableTask` annotation. This
|
||||
class-level annotation tells Spring Cloud Task to bootstrap it's functionality. By
|
||||
default, it imports an additional configuration class (`SimpleTaskConfiguration`). This
|
||||
additional configuration registers the `TaskRepository` and the infrastructure for its
|
||||
use.
|
||||
|
||||
Out of the box, the `TaskRepository` will use an in memory `Map` to record the results
|
||||
of a task. Obviously this isn't a practical solution for a production environment since
|
||||
the `Map` goes away once the task ends. However, for a quick getting started
|
||||
experience we use this as a default as well as echoing to the logs what is being updated
|
||||
in that repository. Later in this documentation we'll cover how to customize the
|
||||
configuration of the pieces provided by Spring Cloud Task.
|
||||
Out of the box, the `TaskRepository` uses an in-memory `Map` to record the results
|
||||
of a task. A `Map` is not a practical solution for a production environment, since
|
||||
the `Map` goes away once the task ends. However, for a quick getting-started
|
||||
experience, we use this as a default as well as echoing to the logs what is being updated
|
||||
in that repository. In the <<features-configuration>> section (later in this
|
||||
documentation), we cover how to customize the configuration of the pieces provided by
|
||||
Spring Cloud Task.
|
||||
|
||||
When our sample application is run, Spring Boot will launch our
|
||||
`HelloWorldCommandLineRunner` outputting our "Hello World!" message to standard out. The
|
||||
`TaskLifecyceListener` will record the start of the task and the end of the task in the
|
||||
repository.
|
||||
When our sample application runs, Spring Boot launches our `HelloWorldCommandLineRunner`
|
||||
and outputs our "`Hello, World!`" message to standard out. The `TaskLifecyceListener`
|
||||
records the start of the task and the end of the task in the repository.
|
||||
|
||||
[[getting-started-main-method]]
|
||||
==== The main method
|
||||
@@ -233,25 +239,25 @@ Spring Boot documentation.
|
||||
[[getting-started-clr]]
|
||||
==== The CommandLineRunner
|
||||
|
||||
In Spring, there are many ways to bootstrap an application's logic. Spring Boot provides
|
||||
a convenient method of doing so in an organized manner via their `*Runner` interfaces
|
||||
(`CommandLineRunner` or `ApplicationRunner`). A well behaved task will bootstrap any
|
||||
logic via one of these two runners.
|
||||
Spring includes many ways to bootstrap an application's logic. Spring Boot provides
|
||||
a convenient method of doing so in an organized manner through its `*Runner` interfaces
|
||||
(`CommandLineRunner` or `ApplicationRunner`). A well behaved task can bootstrap any
|
||||
logic by using one of these two runners.
|
||||
|
||||
The lifecycle of a task is considered from before the `*Runner#run` methods are executed
|
||||
to once they are all complete. Spring Boot allows an application to use multiple
|
||||
`*Runner` implementation and Spring Cloud Task doesn't attempt to impede on this convention.
|
||||
to once they are all complete. Spring Boot lets an application use multiple
|
||||
`*Runner` implementations, as does Spring Cloud Task.
|
||||
|
||||
NOTE: Any processing bootstrapped from mechanisms other than a `CommandLineRunner` or
|
||||
`ApplicationRunner` (using `InitializingBean#afterPropertiesSet` for example) will not be
|
||||
`ApplicationRunner` (by using `InitializingBean#afterPropertiesSet` for example) is not
|
||||
recorded by Spring Cloud Task.
|
||||
|
||||
[[getting-started-running-the-example]]
|
||||
=== Running the example
|
||||
=== Running the Example
|
||||
|
||||
At this point, your application should work. Since this application is Spring Boot based,
|
||||
we can run it from the command line via the command `$ mvn spring-boot:run` from the root
|
||||
of our applicaiton:
|
||||
At this point, our application should work. Since this application is Spring Boot-based,
|
||||
we can run it from the command line by using `$ mvn spring-boot:run` from the root
|
||||
of our application, as shown (with its output) in the following example:
|
||||
|
||||
[source]
|
||||
----
|
||||
@@ -274,19 +280,19 @@ $ mvn clean spring-boot:run
|
||||
2016-01-25 11:08:10.226 INFO 12943 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a2c3676: startup date [Mon Jan 25 11:08:10 CST 2016]; root of context hierarchy
|
||||
2016-01-25 11:08:11.051 INFO 12943 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
|
||||
2016-01-25 11:08:11.065 INFO 12943 --- [ main] o.s.c.t.r.support.SimpleTaskRepository : Creating: TaskExecution{executionId=0, externalExecutionID='null', exitCode=0, taskName='application', startTime=Mon Jan 25 11:08:11 CST 2016, endTime=null, statusCode='null', exitMessage='null', arguments=[]}
|
||||
Hello World!
|
||||
Hello, World!
|
||||
2016-01-25 11:08:11.071 INFO 12943 --- [ main] com.example.SampleTask : Started SampleTask in 1.095 seconds (JVM running for 3.826)
|
||||
2016-01-25 11:08:11.220 INFO 12943 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a2c3676: startup date [Mon Jan 25 11:08:10 CST 2016]; root of context hierarchy
|
||||
2016-01-25 11:08:11.222 INFO 12943 --- [ Thread-1] o.s.c.t.r.support.SimpleTaskRepository : Updating: TaskExecution{executionId=0, externalExecutionID='null', exitCode=0, taskName='application', startTime=Mon Jan 25 11:08:11 CST 2016, endTime=Mon Jan 25 11:08:11 CST 2016, statusCode='null', exitMessage='null', arguments=[]}
|
||||
2016-01-25 11:08:11.222 INFO 12943 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
|
||||
----
|
||||
|
||||
If you notice, there are three lines of interest in the above output:
|
||||
The preceding output has three lines that of interest to us here:
|
||||
|
||||
* `SimpleTaskRepository` logged out the creation of the entry in the `TaskRepository`.
|
||||
* The execution of our `CommandLineRunner`, demonstrated by the "Hello World!" output.
|
||||
* `SimpleTaskRepository` logging the completion of the task in the `TaskRepository`.
|
||||
* `SimpleTaskRepository` logged the creation of the entry in the `TaskRepository`.
|
||||
* The execution of our `CommandLineRunner`, demonstrated by the "`Hello, World!`" output.
|
||||
* `SimpleTaskRepository` logs the completion of the task in the `TaskRepository`.
|
||||
|
||||
NOTE: A simple task application can be found in the samples module
|
||||
of the Spring Cloud Task Project
|
||||
NOTE: A simple task application can be found in the samples module of the Spring Cloud
|
||||
Task Project
|
||||
https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples/timestamp[here].
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
= Spring Cloud Task Reference Guide
|
||||
Michael Minella, Glenn Renfro
|
||||
Michael Minella, Glenn Renfro, Jay Bryant
|
||||
:doctype: book
|
||||
:toc:
|
||||
:toclevels: 4
|
||||
|
||||
@@ -4,41 +4,41 @@
|
||||
[[task-documentation-about]]
|
||||
|
||||
This section provides a brief overview of the Spring Cloud Task reference documentation.
|
||||
Think of it as a map for the rest of the document. You can read this reference guide in a
|
||||
linear fashion, or you can skip sections if something doesn't interest you.
|
||||
Think of it as a map for the rest of the document. You can read this reference guide in a
|
||||
linear fashion or you can skip sections if something does not interest you.
|
||||
|
||||
== About the documentation
|
||||
The Spring Cloud Task reference guide is available as {spring-cloud-task-docs}/html[html],
|
||||
The Spring Cloud Task reference guide is available in {spring-cloud-task-docs}/html[html],
|
||||
{spring-cloud-task-docs}/pdf/spring-cloud-task-reference.pdf[pdf]
|
||||
and {spring-cloud-task-docs}/epub/spring-cloud-task-reference.epub[epub] documents. The latest copy
|
||||
is available at {spring-cloud-task-docs-current}.
|
||||
and {spring-cloud-task-docs}/epub/spring-cloud-task-reference.epub[epub] formats. The
|
||||
latest copy is available at {spring-cloud-task-docs-current}.
|
||||
|
||||
Copies of this document may be made for your own use and for
|
||||
distribution to others, provided that you do not charge any fee for such copies and
|
||||
further provided that each copy contains this Copyright Notice, whether distributed in
|
||||
print or electronically.
|
||||
Copies of this document may be made for your own use and for distribution to others,
|
||||
provided that you do not charge any fee for such copies and further provided that each
|
||||
copy contains this Copyright Notice, whether distributed in print or electronically.
|
||||
|
||||
[[task-documentation-getting-help]]
|
||||
== Getting help
|
||||
Having trouble with Spring Cloud Task, We'd like to help!
|
||||
Having trouble with Spring Cloud Task? We would like to help!
|
||||
|
||||
* Ask a question - we monitor http://stackoverflow.com[stackoverflow.com] for questions
|
||||
tagged with http://stackoverflow.com/tags/spring-cloud-task[`spring-cloud-task`].
|
||||
* Report bugs with Spring Cloud Task at https://github.com/spring-cloud/spring-cloud-task/issues.
|
||||
* Ask a question. We monitor http://stackoverflow.com[stackoverflow.com] for questions
|
||||
tagged with http://stackoverflow.com/tags/spring-cloud-task[`spring-cloud-task`].
|
||||
* Report bugs with Spring Cloud Task at
|
||||
https://github.com/spring-cloud/spring-cloud-task/issues.
|
||||
|
||||
NOTE: All of Spring Cloud Task is open source, including the documentation! If you find problems
|
||||
with the docs; or if you just want to improve them, please {github-code}[get involved].
|
||||
NOTE: All of Spring Cloud Task is open source, including the documentation. If you find
|
||||
a problem with the docs or if you just want to improve them, please {github-code}[get
|
||||
involved].
|
||||
|
||||
[[task-documentation-first-steps]]
|
||||
== First Steps
|
||||
If you're just getting started with Spring Cloud Task, or 'Spring' in general,
|
||||
<<getting-started.adoc#getting-started, this is the place to start!>>
|
||||
|
||||
* *From scratch:*
|
||||
<<getting-started.adoc#getting-started-introducing-spring-cloud-task, Overview>> |
|
||||
<<getting-started.adoc#getting-started-system-requirements, Requirements>>
|
||||
* *Tutorial:*
|
||||
<<getting-started.adoc#getting-started-developing-first-task, First application>>
|
||||
* *Running your example:*
|
||||
<<getting-started.adoc#getting-started-running-the-example, Running your application>>
|
||||
If you are just getting started with Spring Cloud Task or with 'Spring' in general, we
|
||||
suggesting reading the <<getting-started.adoc#getting-started>> chapter.
|
||||
|
||||
To get started from scratch, read the following sections:
|
||||
* "`<<getting-started.adoc#getting-started-introducing-spring-cloud-task>>`"
|
||||
* "`<<getting-started.adoc#getting-started-system-requirements>>`"
|
||||
To follow the tutorial, read
|
||||
"`<<getting-started.adoc#getting-started-developing-first-task>>`"
|
||||
To run your example, read
|
||||
"`<<getting-started.adoc#getting-started-running-the-example>>`"
|
||||
|
||||
@@ -3,40 +3,39 @@
|
||||
|
||||
[[partintro]]
|
||||
--
|
||||
A task by itself can be useful, but it's the integration of a task into a larger ecosystem
|
||||
that allows it to be useful for more complex processing and orchestration. This section
|
||||
covers the integration options for Spring Cloud Task and Spring Cloud Stream.
|
||||
A task by itself can be useful, but integration of a task into a larger ecosystem lets it
|
||||
be useful for more complex processing and orchestration. This section
|
||||
covers the integration options for Spring Cloud Task with Spring Cloud Stream.
|
||||
--
|
||||
|
||||
[[stream-integration-launching-sink]]
|
||||
== Launching a task from a Spring Cloud Stream
|
||||
== Launching a Task from a Spring Cloud Stream
|
||||
|
||||
Allows a user to launch tasks from a stream. This is done by creating a sink that
|
||||
listens for a message that contains a `TaskLaunchRequest` as its payload. The
|
||||
TaskLaunchRequest contains:
|
||||
You can launch tasks from a stream. To do so, create a sink that listens for a message
|
||||
that contains a `TaskLaunchRequest` as its payload. The `TaskLaunchRequest` contains:
|
||||
|
||||
* uri - to the task artifact that is to be executed.
|
||||
* applicationName - the name that will be associated with the task. If no
|
||||
applicationName is set the TaskLaunchRequest will generate a task name
|
||||
comprised of the following: `Task-<UUID>`
|
||||
* commandLineArguments - a list containing the command line arguments for the
|
||||
* `uri`: To the task artifact that is to be executed.
|
||||
* `applicationName`: The name that is associated with the task. If no
|
||||
applicationName is set, the `TaskLaunchRequest` generates a task name
|
||||
comprised of the following: `Task-<UUID>`.
|
||||
* `commandLineArguments`: A list containing the command line arguments for the task.
|
||||
* `environmentProperties`: A map containing the environment variables to be used by the
|
||||
task.
|
||||
* environmentProperties - a map containing the environment variables to be used
|
||||
by the task
|
||||
* deploymentProperties - a map containing the properties that will be used by
|
||||
the deployer to deploy the task.
|
||||
* `deploymentProperties`: A map containing the properties that are used by the deployer to
|
||||
deploy the task.
|
||||
|
||||
NOTE: If the payload is of a different type then the sink will throw an exception.
|
||||
NOTE: If the payload is of a different type, the sink throws an exception.
|
||||
|
||||
For example a stream can be created that has a processor that takes in data from a
|
||||
http source and creates a `GenericMessage` that contains the `TaskLaunchRequest` and sends
|
||||
For example, a stream can be created that has a processor that takes in data from an
|
||||
HTTP source and creates a `GenericMessage` that contains the `TaskLaunchRequest` and sends
|
||||
the message to its output channel. The task sink would then receive the message from its
|
||||
input channnel and then launch the task.
|
||||
|
||||
To create a taskSink a user needs to only create a spring boot app that includes the
|
||||
following annotation `EnableTaskLauncher`. The code would look something like this:
|
||||
To create a taskSink, you need only create a Spring Boot application that includes the
|
||||
`EnableTaskLauncher` annotation, as shown in the following example:
|
||||
|
||||
```
|
||||
[source,java]
|
||||
----
|
||||
@SpringBootApplication
|
||||
@EnableTaskLauncher
|
||||
public class TaskSinkApplication {
|
||||
@@ -44,51 +43,55 @@ public class TaskSinkApplication {
|
||||
SpringApplication.run(TaskSinkApplication.class, args);
|
||||
}
|
||||
}
|
||||
```
|
||||
----
|
||||
|
||||
A sample Sink and Processor have been made available to you in the samples module
|
||||
of the Spring Cloud Task project. To install these samples into your local maven
|
||||
repository execute a maven build from the `spring-cloud-task-samples` directory with the
|
||||
property `skipInstall` set to false. For example:
|
||||
`mvn clean install`.
|
||||
The https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples[samples
|
||||
module] of the Spring Cloud Task project contains a sample Sink and Processor. To install
|
||||
these samples into your local maven repository, run a maven build from the
|
||||
`spring-cloud-task-samples` directory with the `skipInstall` property set to `false`, as
|
||||
shown in the following example:
|
||||
|
||||
NOTE: The maven.remoteRepositories.springRepo.url property will need to be set to
|
||||
the location of the remote repository from which the über-jar is located. If not
|
||||
set, then there will be no remote repository, so it will rely upon the local repository only.
|
||||
`mvn clean install`
|
||||
|
||||
NOTE: The `maven.remoteRepositories.springRepo.url` property must be set to the location
|
||||
of the remote repository in which the über-jar is located. If not set, there is no remote
|
||||
repository, so it relies upon the local repository only.
|
||||
|
||||
[[stream-integration-launching-sink-dataflow]]
|
||||
=== Spring Cloud Data Flow
|
||||
|
||||
To create a stream in Spring Cloud Data Flow first we would want to register the Task Sink
|
||||
Application we created. In the example below we are registering the Processor and Sink
|
||||
sample applications using the Spring Cloud Data Flow shell:
|
||||
To create a stream in Spring Cloud Data Flow, you must first register the Task Sink
|
||||
Application we created. In the following example, we are registering the Processor and
|
||||
Sink sample applications by using the Spring Cloud Data Flow shell:
|
||||
|
||||
```
|
||||
[source,bash]
|
||||
----
|
||||
app register --name taskSink --type sink --uri maven://io.spring.cloud:tasksink:<version>
|
||||
app register --name taskProcessor --type processor --uri maven:io.spring.cloud:taskprocessor:<version>
|
||||
```
|
||||
----
|
||||
|
||||
Creating a stream from the Spring Cloud Data Flow shell would look like this:
|
||||
The following example shows how to create a stream from the Spring Cloud Data Flow shell:
|
||||
|
||||
```
|
||||
[source,bash]
|
||||
stream create foo --definition "http --server.port=9000|taskProcessor|taskSink" --deploy
|
||||
```
|
||||
|
||||
[[stream-integration-events]]
|
||||
== Spring Cloud Task Events
|
||||
|
||||
Spring Cloud Task provides the ability to emit events via Spring Cloud Stream channel
|
||||
when the task is executed via a Spring Cloud Stream channel. A task listener is used to
|
||||
publish the `TaskExecution` on a message channel named `task-events`. This feature is
|
||||
autowired into any task that has `spring-cloud-stream` on its classpath in addition to the
|
||||
`spring-cloud-stream` and a task defined.
|
||||
Spring Cloud Task provides the ability to emit events through a Spring Cloud Stream
|
||||
channel when the task is run through a Spring Cloud Stream channel. A task listener is
|
||||
used to publish the `TaskExecution` on a message channel named `task-events`. This feature
|
||||
is autowired into any task that has `spring-cloud-stream`, `spring-cloud-stream-<binder>`,
|
||||
and a defined task on its classpath.
|
||||
|
||||
NOTE: To disable the event emitting listener, set the property
|
||||
`spring.cloud.task.events.enabled` to `false`.
|
||||
NOTE: To disable the event emitting listener, set the `spring.cloud.task.events.enabled`
|
||||
property to `false`.
|
||||
|
||||
With the appropriate classpath defined, a simple task like this:
|
||||
With the appropriate classpath defined, the following task emits the `TaskExecution` as an
|
||||
event on the `task-events` channel (at both the start and the end of the task):
|
||||
|
||||
```
|
||||
[source, java]
|
||||
----
|
||||
@SpringBootApplication
|
||||
@EnableTask
|
||||
public class TaskEventsApplication {
|
||||
@@ -111,87 +114,81 @@ public class TaskEventsApplication {
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
will emit the `TaskExecution` as an event on the `task-events` channel (both at the start
|
||||
and end of the task).
|
||||
|
||||
NOTE: Configuration of the content type may be required via
|
||||
`--spring.cloud.stream.bindings.task-events.contentType=<CONTENT_TYPE>` if the processor
|
||||
or sink downstream does not have the spring-cloud-task-core jar on its classpath.
|
||||
----
|
||||
|
||||
NOTE: A binder implementation is also required to be on the classpath.
|
||||
|
||||
NOTE: A sample task event application can be found in the samples module
|
||||
of the Spring Cloud Task Project
|
||||
of the Spring Cloud Task Project,
|
||||
https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples/task-events[here].
|
||||
|
||||
[[stream-integration-disable-task-events]]
|
||||
=== Disabling Specific Task Events
|
||||
|
||||
To task events, the `spring.cloud.task.events.enabled` property can be set to `false`.
|
||||
|
||||
To disable task events, you can set the `spring.cloud.task.events.enabled` property to
|
||||
`false`.
|
||||
|
||||
[[stream-integration-batch-events]]
|
||||
== Spring Batch Events
|
||||
|
||||
When executing a Spring Batch job via a task, Spring Cloud Task can be configured to emit
|
||||
informational messages based on the Spring Batch listeners available in Spring Batch.
|
||||
Specifically the following Spring Batch listeners are autoconfigured into each batch job and
|
||||
emit messages on the associated Spring Cloud Stream channels when run via Spring Cloud
|
||||
Task:
|
||||
When executing a Spring Batch job through a task, Spring Cloud Task can be configured to
|
||||
emit informational messages based on the Spring Batch listeners available in Spring Batch.
|
||||
Specifically, the following Spring Batch listeners are autoconfigured into each batch job
|
||||
and emit messages on the associated Spring Cloud Stream channels when run through Spring
|
||||
Cloud Task:
|
||||
|
||||
* `JobExecutionListener` - `job-execution-events`
|
||||
* `StepExecutionListener` - `step-execution-events`
|
||||
* `ChunkListener` - `chunk-events`
|
||||
* `ItemReadListener` - `item-read-events`
|
||||
* `ItemProcessListener` - `item-process-events`
|
||||
* `ItemWriteListener` - `item-write-events`
|
||||
* `SkipListener` - `skip-events`
|
||||
* `JobExecutionListener` listens for `job-execution-events`
|
||||
* `StepExecutionListener` listens for `step-execution-events`
|
||||
* `ChunkListener` listens for `chunk-events`
|
||||
* `ItemReadListener` listens for `item-read-events`
|
||||
* `ItemProcessListener` listens for `item-process-events`
|
||||
* `ItemWriteListener` listens for `item-write-events`
|
||||
* `SkipListener` listens for `skip-events`
|
||||
|
||||
The above listeners are autoconfigured into any `AbstractJob` when the appropriate
|
||||
beans exist in the context (a `Job` and a `TaskLifecycleListener`). Configuration to
|
||||
These listeners are autoconfigured into any `AbstractJob` when the appropriate
|
||||
beans (a `Job` and a `TaskLifecycleListener`) exist in the context. Configuration to
|
||||
listen to these events is handled the same way binding to any other Spring
|
||||
Cloud Stream channel is done. Our task (the one running the batch job) serves as a
|
||||
`Source`, with the listening applications serving as either a `Processor` or `Sink`.
|
||||
`Source`, with the listening applications serving as either a `Processor` or a `Sink`.
|
||||
|
||||
An example could be to have an application listening to the `job-execution-events` channel
|
||||
for the start and stop of a job. To configure the listening application, you'd configure
|
||||
the input to be `job-execution-events` as follows
|
||||
for the start and stop of a job. To configure the listening application, you would
|
||||
configure the input to be `job-execution-events` as follows:
|
||||
|
||||
```
|
||||
spring.cloud.stream.bindings.input.destination=job-execution-events
|
||||
```
|
||||
`spring.cloud.stream.bindings.input.destination=job-execution-events`
|
||||
|
||||
NOTE: A binder implementation is also required to be on the classpath.
|
||||
|
||||
NOTE: A sample batch event application can be found in the samples module
|
||||
of the Spring Cloud Task Project
|
||||
of the Spring Cloud Task Project,
|
||||
https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples/batch-events[here].
|
||||
|
||||
=== Sending Batch Events to different channels
|
||||
=== Sending Batch Events to Different Channels
|
||||
|
||||
One of the options that Spring Cloud Task offers for batch events is the ability to alter the channel to which a
|
||||
specific listener can emit its messages. To do this use the following configuration:
|
||||
`spring.cloud.stream.bindings.<the channel>.destination=<new destination>`.
|
||||
For example: If StepExecutionListener needs to emit its messages to another channel `my-step-execution-events`
|
||||
instead of the default `step-execution-events` the following configuration can be added:
|
||||
One of the options that Spring Cloud Task offers for batch events is the ability to alter
|
||||
the channel to which a specific listener can emit its messages. To do so, use the
|
||||
following configuration:
|
||||
`spring.cloud.stream.bindings.<the channel>.destination=<new destination>`. For example,
|
||||
if `StepExecutionListener` needs to emit its messages to another channel called
|
||||
`my-step-execution-events` instead of the default `step-execution-events`, you can add the
|
||||
following configuration:
|
||||
|
||||
```
|
||||
spring.cloud.stream.bindings.step-execution-events.destination=my-step-execution-events`
|
||||
```
|
||||
`spring.cloud.stream.bindings.step-execution-events.destination=my-step-execution-events`
|
||||
|
||||
=== Disabling Batch Events
|
||||
To disable the all batch event listener functionality, use the following configuration:
|
||||
To disable the listener functionality for all batch events, use the following
|
||||
configuration:
|
||||
|
||||
```
|
||||
spring.cloud.task.batch.events.enabled=false
|
||||
```
|
||||
`spring.cloud.task.batch.events.enabled=false`
|
||||
|
||||
To disable a specific batch event, use the following configuration:
|
||||
|
||||
To disable a specific batch event use the following configuration:
|
||||
`spring.cloud.task.batch.events.<batch event listener>.enabled=false`:
|
||||
|
||||
```
|
||||
The following listing shows individual listeners that you can disable:
|
||||
|
||||
[source,bash]
|
||||
----
|
||||
spring.cloud.task.batch.events.job-execution.enabled=false
|
||||
spring.cloud.task.batch.events.step-execution.enabled=false
|
||||
spring.cloud.task.batch.events.chunk.enabled=false
|
||||
@@ -199,12 +196,14 @@ spring.cloud.task.batch.events.item-read.enabled=false
|
||||
spring.cloud.task.batch.events.item-process.enabled=false
|
||||
spring.cloud.task.batch.events.item-write.enabled=false
|
||||
spring.cloud.task.batch.events.skip.enabled=false
|
||||
```
|
||||
----
|
||||
|
||||
=== Emit Order for Batch Events
|
||||
By default batch events have `Ordered.LOWEST_PRECEDENCE` , to change this value ( for example to 5 ) use the following configuration:
|
||||
By default, batch events have `Ordered.LOWEST_PRECEDENCE`. To change this value (for
|
||||
example, to 5 ), use the following configuration:
|
||||
|
||||
```
|
||||
[source,bash]
|
||||
----
|
||||
spring.cloud.task.batch.events.job-execution-order=5
|
||||
spring.cloud.task.batch.events.step-execution-order=5
|
||||
spring.cloud.task.batch.events.chunk-order=5
|
||||
@@ -212,4 +211,4 @@ spring.cloud.task.batch.events.item-read-order=5
|
||||
spring.cloud.task.batch.events.item-process-order=5
|
||||
spring.cloud.task.batch.events.item-write-order=5
|
||||
spring.cloud.task.batch.events.skip-order=5
|
||||
```
|
||||
----
|
||||
|
||||
Reference in New Issue
Block a user