219 lines
11 KiB
Plaintext
Executable File
219 lines
11 KiB
Plaintext
Executable File
|
|
[[getting-started]]
|
|
= Getting started
|
|
|
|
[[partintro]]
|
|
--
|
|
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. 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 to have Java installed (Java 17 or better).
|
|
|
|
[[database-requirements]]
|
|
=== 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 want to
|
|
use a supported database. Spring Cloud Task currently supports the following databases:
|
|
|
|
* DB2
|
|
* H2
|
|
* HSQLDB
|
|
* MySql
|
|
* Oracle
|
|
* Postgres
|
|
* SqlServer
|
|
|
|
[[getting-started-developing-first-task]]
|
|
== Developing Your First Spring Cloud Task Application
|
|
|
|
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 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
|
|
https://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.
|
|
|
|
[[getting-started-creating-project]]
|
|
=== Creating the Spring Task Project using Spring Initializr
|
|
Now we can create and test an application that prints `Hello, World!` to the console.
|
|
|
|
To do so:
|
|
|
|
. Visit the link:https://start.spring.io/[Spring Initialzr] site.
|
|
.. Create a new Maven project with a *Group* name of `io.spring.demo` and an *Artifact* name of `helloworld`.
|
|
.. In the Dependencies text box, type `task` and then select the `Task` dependency with the `Spring Cloud` label.
|
|
.. In the Dependencies text box, type `h2` and then select the `H2` dependency with the `SQL` label.
|
|
.. Click the *Generate Project* button
|
|
. Unzip the helloworld.zip file and import the project into your favorite IDE.
|
|
|
|
[[getting-started-writing-the-code]]
|
|
=== Writing the Code
|
|
|
|
To finish our application, we need to update the generated `HelloworldApplication` with the following contents so that it launches a Task.
|
|
[source,java]
|
|
----
|
|
package io.spring.demo.helloworld;
|
|
|
|
import org.springframework.boot.ApplicationArguments;
|
|
import org.springframework.boot.ApplicationRunner;
|
|
import org.springframework.boot.CommandLineRunner;
|
|
import org.springframework.boot.SpringApplication;
|
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
|
import org.springframework.cloud.task.configuration.EnableTask;
|
|
import org.springframework.context.annotation.Bean;
|
|
|
|
@SpringBootApplication
|
|
@EnableTask
|
|
public class HelloworldApplication {
|
|
|
|
@Bean
|
|
public ApplicationRunner applicationRunner() {
|
|
return new HelloWorldApplicationRunner();
|
|
}
|
|
|
|
public static void main(String[] args) {
|
|
SpringApplication.run(HelloworldApplication.class, args);
|
|
}
|
|
|
|
public static class HelloWorldApplicationRunner implements ApplicationRunner {
|
|
|
|
@Override
|
|
public void run(ApplicationArguments args) throws Exception {
|
|
System.out.println("Hello, World!");
|
|
|
|
}
|
|
}
|
|
}
|
|
----
|
|
|
|
While it may seem small, quite a bit is going on. For more about Spring
|
|
Boot specifics, see the
|
|
https://docs.spring.io/spring-boot/docs/current/reference/html/[Spring Boot reference documentation].
|
|
|
|
Now we can open the `application.properties` file in `src/main/resources`.
|
|
We need to configure two properties in `application.properties`:
|
|
|
|
* `application.name`: To set the application name (which is translated to the task name)
|
|
* `logging.level`: To set the logging for Spring Cloud Task to `DEBUG` in order to
|
|
get a view of what is going on.
|
|
|
|
The following example shows how to do both:
|
|
|
|
|
|
[source]
|
|
----
|
|
logging.level.org.springframework.cloud.task=DEBUG
|
|
spring.application.name=helloWorld
|
|
----
|
|
|
|
[[getting-started-at-task]]
|
|
==== Task Auto Configuration
|
|
|
|
When including Spring Cloud Task Starter dependency, Task auto configures all beans to bootstrap it's functionality.
|
|
Part of this configuration registers the `TaskRepository` and the infrastructure for its use.
|
|
|
|
In our demo, the `TaskRepository` uses an embedded H2 database to record the results
|
|
of a task. This H2 embedded database is not a practical solution for a production environment, since
|
|
the H2 DB goes away once the task ends. However, for a quick getting-started
|
|
experience, we can use this in our example as well as echoing to the logs what is being updated
|
|
in that repository. In the xref:features.adoc#features-configuration[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 runs, Spring Boot launches our `HelloWorldApplicationRunner`
|
|
and outputs our "`Hello, World!`" message to standard out. The `TaskLifecycleListener`
|
|
records the start of the task and the end of the task in the repository.
|
|
|
|
[[getting-started-main-method]]
|
|
==== The main method
|
|
|
|
The main method serves as the entry point to any java application. Our main method
|
|
delegates to Spring Boot's https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-spring-application.html[SpringApplication] class.
|
|
|
|
[[getting-started-clr]]
|
|
==== The ApplicationRunner
|
|
|
|
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 lets an application use multiple
|
|
`*Runner` implementations, as does Spring Cloud Task.
|
|
|
|
NOTE: Any processing bootstrapped from mechanisms other than a `CommandLineRunner` or
|
|
`ApplicationRunner` (by using `InitializingBean#afterPropertiesSet` for example) is not
|
|
recorded by Spring Cloud Task.
|
|
|
|
[[getting-started-running-the-example]]
|
|
=== Running the Example
|
|
|
|
At this point, our application should work. Since this application is Spring Boot-based,
|
|
we can run it from the command line by using `$ ./mvnw spring-boot:run` from the root
|
|
of our application, as shown (with its output) in the following example:
|
|
|
|
[source]
|
|
----
|
|
$ mvn clean spring-boot:run
|
|
....... . . .
|
|
....... . . . (Maven log output here)
|
|
....... . . .
|
|
|
|
. ____ _ __ _ _
|
|
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
|
|
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
|
|
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
|
|
' |____| .__|_| |_|_| |_\__, | / / / /
|
|
=========|_|==============|___/=/_/_/_/
|
|
:: Spring Boot :: (v3.3.0)
|
|
|
|
2024-01-04T10:07:01.102-06:00 INFO 18248 --- [helloWorld] [ main] i.s.d.helloworld.HelloworldApplication : Starting HelloworldApplication using Java 21.0.1 with PID 18248 (/Users/dashaun/fun/dashaun/spring-cloud-task/helloworld/target/classes started by dashaun in /Users/dashaun/fun/dashaun/spring-cloud-task/helloworld)
|
|
2024-01-04T10:07:01.103-06:00 INFO 18248 --- [helloWorld] [ main] i.s.d.helloworld.HelloworldApplication : No active profile set, falling back to 1 default profile: "default"
|
|
2024-01-04T10:07:01.526-06:00 INFO 18248 --- [helloWorld] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
|
|
2024-01-04T10:07:01.626-06:00 INFO 18248 --- [helloWorld] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:3ad913f8-59ce-4785-bf8e-d6335dff6856 user=SA
|
|
2024-01-04T10:07:01.627-06:00 INFO 18248 --- [helloWorld] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
|
|
2024-01-04T10:07:01.633-06:00 DEBUG 18248 --- [helloWorld] [ main] o.s.c.t.c.SimpleTaskAutoConfiguration : Using org.springframework.cloud.task.configuration.DefaultTaskConfigurer TaskConfigurer
|
|
2024-01-04T10:07:01.633-06:00 DEBUG 18248 --- [helloWorld] [ main] o.s.c.t.c.DefaultTaskConfigurer : No EntityManager was found, using DataSourceTransactionManager
|
|
2024-01-04T10:07:01.639-06:00 DEBUG 18248 --- [helloWorld] [ main] o.s.c.t.r.s.TaskRepositoryInitializer : Initializing task schema for h2 database
|
|
2024-01-04T10:07:01.772-06:00 DEBUG 18248 --- [helloWorld] [ main] o.s.c.t.r.support.SimpleTaskRepository : Creating: TaskExecution{executionId=0, parentExecutionId=null, exitCode=null, taskName='helloWorld', startTime=2024-01-04T10:07:01.757268, endTime=null, exitMessage='null', externalExecutionId='null', errorMessage='null', arguments=[]}
|
|
2024-01-04T10:07:01.785-06:00 INFO 18248 --- [helloWorld] [ main] i.s.d.helloworld.HelloworldApplication : Started HelloworldApplication in 0.853 seconds (process running for 1.029)
|
|
Hello, World!
|
|
2024-01-04T10:07:01.794-06:00 DEBUG 18248 --- [helloWorld] [ main] o.s.c.t.r.support.SimpleTaskRepository : Updating: TaskExecution with executionId=1 with the following {exitCode=0, endTime=2024-01-04T10:07:01.787112, exitMessage='null', errorMessage='null'}
|
|
2024-01-04T10:07:01.799-06:00 INFO 18248 --- [helloWorld] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
|
|
2024-01-04T10:07:01.806-06:00 INFO 18248 --- [helloWorld] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
|
|
|
|
....... . . .
|
|
....... . . . (Maven log output here)
|
|
....... . . .
|
|
----
|
|
|
|
The preceding output has three lines that are of interest to us here:
|
|
|
|
* `SimpleTaskRepository` logged the creation of the entry in the `TaskRepository`.
|
|
* The execution of our `ApplicationRunner`, 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
|
|
https://github.com/spring-cloud/spring-cloud-task/tree/master/spring-cloud-task-samples/timestamp[here].
|