31 | * {@link TaskExecutionListener#onTaskEnd(TaskExecution)}. 32 | *
33 | * 34 | *
35 | * public class MyListener {
36 | * @AfterTask
37 | * public void doSomething(TaskExecution taskExecution) {
38 | * }
39 | * }
40 | *
41 | *
42 | * @author Glenn Renfro
43 | */
44 | @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
45 | @Retention(RetentionPolicy.RUNTIME)
46 | @Documented
47 | @Reflective
48 | public @interface AfterTask {
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/spring-cloud-task-samples/multiple-datasources/src/main/java/io/spring/configuration/EmbeddedDataSourceConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.spring.configuration;
18 |
19 | import javax.sql.DataSource;
20 |
21 | import org.springframework.context.annotation.Bean;
22 | import org.springframework.context.annotation.Configuration;
23 | import org.springframework.context.annotation.Profile;
24 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
25 | import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
26 |
27 | /**
28 | * Creates two data sources that use embedded databases.
29 | *
30 | * @author Michael Minella
31 | * @author Glenn Renfro
32 | */
33 | @Configuration(proxyBeanMethods = false)
34 | @Profile("embedded")
35 | public class EmbeddedDataSourceConfiguration {
36 |
37 | @Bean
38 | public DataSource dataSource() {
39 | return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
40 | }
41 |
42 | @Bean
43 | public DataSource secondDataSource() {
44 | return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build();
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/annotation/BeforeTask.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.listener.annotation;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | import org.springframework.aot.hint.annotation.Reflective;
26 | import org.springframework.cloud.task.listener.TaskExecutionListener;
27 | import org.springframework.cloud.task.repository.TaskExecution;
28 |
29 | /**
30 | * 31 | * {@link TaskExecutionListener#onTaskStartup(TaskExecution)}. 32 | *
33 | * 34 | *
35 | * public class MyListener {
36 | * @BeforeTask
37 | * public void doSomething(TaskExecution taskExecution) {
38 | * }
39 | * }
40 | *
41 | *
42 | * @author Glenn Renfro
43 | */
44 | @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
45 | @Retention(RetentionPolicy.RUNTIME)
46 | @Documented
47 | @Reflective
48 | public @interface BeforeTask {
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/annotation/FailedTask.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.listener.annotation;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | import org.springframework.aot.hint.annotation.Reflective;
26 | import org.springframework.cloud.task.listener.TaskExecutionListener;
27 | import org.springframework.cloud.task.repository.TaskExecution;
28 |
29 | /**
30 | * 31 | * {@link TaskExecutionListener#onTaskFailed(TaskExecution, Throwable)}. 32 | *
33 | * 34 | *
35 | * public class MyListener {
36 | * @FailedTask
37 | * public void doSomething(TaskExecution taskExecution, Throwable throwable) {
38 | * }
39 | * }
40 | *
41 | *
42 | * @author Glenn Renfro
43 | */
44 | @Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
45 | @Retention(RetentionPolicy.RUNTIME)
46 | @Documented
47 | @Reflective
48 | public @interface FailedTask {
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/configuration/TaskPropertiesTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.configuration;
18 |
19 | import org.junit.jupiter.api.Test;
20 | import org.junit.jupiter.api.extension.ExtendWith;
21 |
22 | import org.springframework.beans.factory.annotation.Autowired;
23 | import org.springframework.boot.test.context.SpringBootTest;
24 | import org.springframework.test.annotation.DirtiesContext;
25 | import org.springframework.test.context.junit.jupiter.SpringExtension;
26 |
27 | import static org.assertj.core.api.Assertions.assertThat;
28 |
29 | @DirtiesContext
30 | @ExtendWith(SpringExtension.class)
31 | @SpringBootTest(classes = { SimpleTaskAutoConfiguration.class, SingleTaskConfiguration.class },
32 | properties = { "spring.cloud.task.closecontextEnabled=false", "spring.cloud.task.initialize-enabled=false" })
33 | public class TaskPropertiesTests {
34 |
35 | @Autowired
36 | TaskProperties taskProperties;
37 |
38 | @Test
39 | public void test() {
40 | assertThat(this.taskProperties.getClosecontextEnabled()).isFalse();
41 | assertThat(this.taskProperties.isInitializeEnabled()).isFalse();
42 | }
43 |
44 | }
45 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/observation/ObservationApplicationRunnerBeanPostProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.configuration.observation;
18 |
19 | import org.springframework.beans.BeansException;
20 | import org.springframework.beans.factory.BeanFactory;
21 | import org.springframework.beans.factory.config.BeanPostProcessor;
22 | import org.springframework.boot.ApplicationRunner;
23 |
24 | /**
25 | * Registers beans related to task scheduling.
26 | *
27 | * @author Marcin Grzejszczak
28 | */
29 | class ObservationApplicationRunnerBeanPostProcessor implements BeanPostProcessor {
30 |
31 | private final BeanFactory beanFactory;
32 |
33 | ObservationApplicationRunnerBeanPostProcessor(BeanFactory beanFactory) {
34 | this.beanFactory = beanFactory;
35 | }
36 |
37 | @Override
38 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
39 | if (bean instanceof ApplicationRunner applicationRunner && !(bean instanceof ObservationApplicationRunner)) {
40 | return new ObservationApplicationRunner(this.beanFactory, applicationRunner, beanName);
41 | }
42 | return bean;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/observation/ObservationCommandLineRunnerBeanPostProcessor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.configuration.observation;
18 |
19 | import org.springframework.beans.BeansException;
20 | import org.springframework.beans.factory.BeanFactory;
21 | import org.springframework.beans.factory.config.BeanPostProcessor;
22 | import org.springframework.boot.CommandLineRunner;
23 |
24 | /**
25 | * Registers beans related to task scheduling.
26 | *
27 | * @author Marcin Grzejszczak
28 | */
29 | class ObservationCommandLineRunnerBeanPostProcessor implements BeanPostProcessor {
30 |
31 | private final BeanFactory beanFactory;
32 |
33 | ObservationCommandLineRunnerBeanPostProcessor(BeanFactory beanFactory) {
34 | this.beanFactory = beanFactory;
35 | }
36 |
37 | @Override
38 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
39 | if (bean instanceof CommandLineRunner commandLineRunner && !(bean instanceof ObservationCommandLineRunner)) {
40 | return new ObservationCommandLineRunner(this.beanFactory, commandLineRunner, beanName);
41 | }
42 | return bean;
43 | }
44 |
45 | }
46 |
--------------------------------------------------------------------------------
/spring-cloud-task-samples/jpa-sample/src/main/java/io/spring/configuration/TaskRunComponent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.spring.configuration;
18 |
19 | import java.text.SimpleDateFormat;
20 | import java.util.Date;
21 |
22 | import org.apache.commons.logging.Log;
23 | import org.apache.commons.logging.LogFactory;
24 |
25 | import org.springframework.beans.factory.annotation.Autowired;
26 | import org.springframework.cloud.task.listener.annotation.BeforeTask;
27 | import org.springframework.cloud.task.repository.TaskExecution;
28 | import org.springframework.stereotype.Component;
29 |
30 | /**
31 | * Records an entry in the TASK_RUN_OUTPUT table on the BeforeTask event.
32 | *
33 | * @author Glenn Renfro
34 | * @author Pas Apicella
35 | */
36 | @Component
37 | public class TaskRunComponent {
38 |
39 | private static final Log logger = LogFactory.getLog(TaskRunComponent.class);
40 |
41 | @Autowired
42 | private TaskRunRepository taskRunRepository;
43 |
44 | @BeforeTask
45 | public void init(TaskExecution taskExecution) {
46 | String execDate = new SimpleDateFormat().format(new Date());
47 | this.taskRunRepository.save(new TaskRunOutput("Executed at " + execDate));
48 | logger.info("Executed at : " + execDate);
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/batch/listener/support/JobInstanceEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.batch.listener.support;
18 |
19 | import org.springframework.batch.core.Entity;
20 | import org.springframework.util.Assert;
21 |
22 | /**
23 | * This is a JobInstance DTO created so that a
24 | * {@link org.springframework.batch.core.job.JobInstance} can be serialized into Json
25 | * without having to add mixins to an ObjectMapper.
26 | *
27 | * @author Glenn Renfro
28 | */
29 |
30 | public class JobInstanceEvent extends Entity {
31 |
32 | private String jobName;
33 |
34 | public JobInstanceEvent() {
35 | super(-1L);
36 | }
37 |
38 | public JobInstanceEvent(Long id, String jobName) {
39 | super(id);
40 | Assert.hasLength(jobName, "jobName must have length greater than zero.");
41 | this.jobName = jobName;
42 | }
43 |
44 | /**
45 | * @return the job name. (Equivalent to getJob().getName())
46 | */
47 | public String getJobName() {
48 | return this.jobName;
49 | }
50 |
51 | public String toString() {
52 | return super.toString() + ", Job=[" + this.jobName + "]";
53 | }
54 |
55 | public long getInstanceId() {
56 | return super.getId();
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/spring-cloud-task-stream/src/main/java/org/springframework/cloud/task/batch/listener/support/ExitStatus.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.batch.listener.support;
18 |
19 | import org.springframework.util.Assert;
20 |
21 | /**
22 | * ExitStatus DTO created so that {@link org.springframework.batch.core.ExitStatus} can be
23 | * serialized into Json without. having to add mixins to an ObjectMapper
24 | *
25 | * @author Glenn Renfro
26 | */
27 | public class ExitStatus {
28 |
29 | private String exitCode;
30 |
31 | private String exitDescription;
32 |
33 | public ExitStatus() {
34 | }
35 |
36 | public ExitStatus(org.springframework.batch.core.ExitStatus exitStatus) {
37 | Assert.notNull(exitStatus, "exitStatus must not be null.");
38 |
39 | this.exitCode = exitStatus.getExitCode();
40 | this.exitDescription = exitStatus.getExitDescription();
41 | }
42 |
43 | public String getExitCode() {
44 | return this.exitCode;
45 | }
46 |
47 | public void setExitCode(String exitCode) {
48 | this.exitCode = exitCode;
49 | }
50 |
51 | public String getExitDescription() {
52 | return this.exitDescription;
53 | }
54 |
55 | public void setExitDescription(String exitDescription) {
56 | this.exitDescription = exitDescription;
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/spring-cloud-task-samples/task-observations/src/test/java/io/spring/taskobservations/TaskObservationsApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.spring.taskobservations;
18 |
19 | import org.junit.jupiter.api.Test;
20 | import org.junit.jupiter.api.extension.ExtendWith;
21 |
22 | import org.springframework.boot.test.context.SpringBootTest;
23 | import org.springframework.boot.test.system.CapturedOutput;
24 | import org.springframework.boot.test.system.OutputCaptureExtension;
25 |
26 | import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
27 |
28 | @SpringBootTest
29 | @ExtendWith(OutputCaptureExtension.class)
30 | class TaskObservationsApplicationTests {
31 |
32 | @Test
33 | void contextLoads(CapturedOutput output) {
34 | String result = output.getAll();
35 | assertThat(result).contains("spring.cloud.task(TIMER)[application='task-observations-application-58', "
36 | + "error='none', service='task-observations-application', "
37 | + "spring.cloud.task.execution.id='1', spring.cloud.task.exit.code='0', "
38 | + "spring.cloud.task.external.execution.id='unknown', spring.cloud.task.name='taskmetrics', "
39 | + "spring.cloud.task.parent.execution.id='unknown', spring.cloud.task.status='success']; "
40 | + "count=1.0, total_time=");
41 | }
42 |
43 | }
44 |
--------------------------------------------------------------------------------
/spring-cloud-task-samples/jpa-sample/src/main/java/io/spring/configuration/TaskRunOutput.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.spring.configuration;
18 |
19 | import jakarta.persistence.Entity;
20 | import jakarta.persistence.GeneratedValue;
21 | import jakarta.persistence.GenerationType;
22 | import jakarta.persistence.Id;
23 | import jakarta.persistence.Table;
24 |
25 | /**
26 | * Entity for the id and output to be written to the data store.
27 | *
28 | * @author Pas Apicella
29 | * @author Glenn Renfro
30 | */
31 | @Entity
32 | @Table(name = "TASK_RUN_OUTPUT")
33 | public class TaskRunOutput {
34 |
35 | @Id
36 | @GeneratedValue(strategy = GenerationType.AUTO)
37 | private Long id;
38 |
39 | private String output;
40 |
41 | public TaskRunOutput() {
42 | }
43 |
44 | public TaskRunOutput(String output) {
45 | this.output = output;
46 | }
47 |
48 | public Long getId() {
49 | return this.id;
50 | }
51 |
52 | public void setId(Long id) {
53 | this.id = id;
54 | }
55 |
56 | public String getOutput() {
57 | return this.output;
58 | }
59 |
60 | public void setOutput(String output) {
61 | this.output = output;
62 | }
63 |
64 | @Override
65 | public String toString() {
66 | return "TaskRunOutput{" + "id=" + this.id + ", output='" + this.output + '\'' + '}';
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/README.adoc:
--------------------------------------------------------------------------------
1 | ////
2 | DO NOT EDIT THIS FILE. IT WAS GENERATED.
3 | Manual changes to this file will be lost when it is generated again.
4 | Edit the files in the src/main/asciidoc/ directory instead.
5 | ////
6 |
7 |
8 | [[spring-cloud-task]]
9 | = Spring Cloud Task
10 |
11 | Is a project centered around the idea of processing on demand. A user is able to develop
12 | a “task” that can be deployed, executed and removed on demand, yet the result of the
13 | process persists beyond the life of the task for future reporting.
14 |
15 |
16 | [[requirements:]]
17 | == Requirements:
18 |
19 | * Java 17 or Above
20 |
21 | [[build-main-project:]]
22 | == Build Main Project:
23 |
24 | [source,shell,indent=2]
25 | ----
26 | $ ./mvnw clean install
27 | ----
28 |
29 | [[example:]]
30 | == Example:
31 |
32 | [source,java,indent=2]
33 | ----
34 | @SpringBootApplication
35 | @EnableTask
36 | public class MyApp {
37 |
38 | @Bean
39 | public MyTaskApplication myTask() {
40 | return new MyTaskApplication();
41 | }
42 |
43 | public static void main(String[] args) {
44 | SpringApplication.run(MyApp.class);
45 | }
46 |
47 | public static class MyTaskApplication implements ApplicationRunner {
48 |
49 | @Override
50 | public void run(ApplicationArguments args) throws Exception {
51 | System.out.println("Hello World");
52 | }
53 | }
54 | }
55 | ----
56 |
57 | [[code-of-conduct]]
58 | == Code of Conduct
59 | This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct]. By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
60 |
61 | [[building-the-project]]
62 | == Building the Project
63 |
64 | This project requires that you invoke the Javadoc engine from the Maven command line. You can do so by appending `javadoc:aggregate` to the rest of your Maven command.
65 | For example, to build the entire project, you could use `mvn clean install -DskipTests -P docs`.
66 |
--------------------------------------------------------------------------------
/spring-cloud-task-samples/multiple-datasources/src/test/java/io/spring/MultiDataSourcesApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package io.spring;
18 |
19 | import org.junit.jupiter.api.Test;
20 | import org.junit.jupiter.api.extension.ExtendWith;
21 |
22 | import org.springframework.boot.SpringApplication;
23 | import org.springframework.boot.test.system.CapturedOutput;
24 | import org.springframework.boot.test.system.OutputCaptureExtension;
25 |
26 | import static org.assertj.core.api.Assertions.assertThat;
27 |
28 | /**
29 | * @author Michael Minella
30 | */
31 | @ExtendWith(OutputCaptureExtension.class)
32 | public class MultiDataSourcesApplicationTests {
33 |
34 | @Test
35 | public void testTimeStampApp(CapturedOutput capturedOutput) throws Exception {
36 |
37 | SpringApplication.run(MultipleDataSourcesApplication.class, "--spring.profiles.active=embedded");
38 |
39 | String output = capturedOutput.toString();
40 |
41 | assertThat(output.contains("There are 2 DataSources within this application"))
42 | .as("Unable to find CommandLineRunner output: " + output)
43 | .isTrue();
44 | assertThat(output.contains("Creating: TaskExecution{")).as("Unable to find start task message: " + output)
45 | .isTrue();
46 | assertThat(output.contains("Updating: TaskExecution")).as("Unable to find update task message: " + output)
47 | .isTrue();
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/listener/TaskEventTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.listener;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | import org.springframework.boot.WebApplicationType;
22 | import org.springframework.boot.autoconfigure.SpringBootApplication;
23 | import org.springframework.boot.builder.SpringApplicationBuilder;
24 | import org.springframework.cloud.stream.binder.test.TestChannelBinderConfiguration;
25 | import org.springframework.cloud.task.configuration.EnableTask;
26 | import org.springframework.context.ConfigurableApplicationContext;
27 |
28 | import static org.assertj.core.api.Assertions.assertThat;
29 |
30 | /**
31 | * @author Michael Minella
32 | * @author Ilayaperumal Gopinathan
33 | * @author Glenn Renfro
34 | */
35 | public class TaskEventTests {
36 |
37 | @Test
38 | public void testDefaultConfiguration() {
39 | ConfigurableApplicationContext applicationContext = new SpringApplicationBuilder()
40 | .sources(TestChannelBinderConfiguration.getCompleteConfiguration(TaskEventsApplication.class))
41 | .web(WebApplicationType.NONE)
42 | .build()
43 | .run();
44 | assertThat(applicationContext.getBean("taskEventEmitter")).isNotNull();
45 | }
46 |
47 | @EnableTask
48 | @SpringBootApplication
49 | public static class TaskEventsApplication {
50 |
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/configuration/observation/TaskDocumentedObservation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.configuration.observation;
18 |
19 | import io.micrometer.common.docs.KeyName;
20 | import io.micrometer.observation.Observation;
21 | import io.micrometer.observation.ObservationConvention;
22 | import io.micrometer.observation.docs.ObservationDocumentation;
23 |
24 | enum TaskDocumentedObservation implements ObservationDocumentation {
25 |
26 | /**
27 | * Observation created when a task runner is executed.
28 | */
29 | TASK_RUNNER_OBSERVATION {
30 |
31 | @Override
32 | public Class extends ObservationConvention extends Observation.Context>> getDefaultConvention() {
33 | return DefaultTaskObservationConvention.class;
34 | }
35 |
36 | @Override
37 | public KeyName[] getLowCardinalityKeyNames() {
38 | return TaskRunnerTags.values();
39 | }
40 |
41 | @Override
42 | public String getPrefix() {
43 | return "spring.cloud.task";
44 | }
45 | };
46 |
47 | /**
48 | * Key names for Spring Cloud Task Command / Application runners.
49 | */
50 | enum TaskRunnerTags implements KeyName {
51 |
52 | /**
53 | * Name of the bean that was executed by Spring Cloud Task.
54 | */
55 | BEAN_NAME {
56 | @Override
57 | public String asString() {
58 | return "spring.cloud.task.runner.bean-name";
59 | }
60 | }
61 |
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/spring-cloud-starter-single-step-batch-job/src/main/java/org/springframework/cloud/task/batch/autoconfigure/RangeConverter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.batch.autoconfigure;
18 |
19 | import org.springframework.batch.infrastructure.item.file.transform.Range;
20 | import org.springframework.core.convert.converter.Converter;
21 |
22 | /**
23 | * Converter for taking properties of format {@code start-end} or {@code start} (where
24 | * start and end are both integers) and converting them into {@link Range} instances for
25 | * configuring a
26 | * {@link org.springframework.batch.infrastructure.item.file.FlatFileItemReader}.
27 | *
28 | * @author Michael Minella
29 | * @since 2.3
30 | */
31 | public class RangeConverter implements Converter30 | * Enables the {@link org.springframework.cloud.task.listener.TaskLifecycleListener} so 31 | * that the features of Spring Cloud Task will be applied. 32 | * 33 | *
34 | * @Configuration
35 | * @EnableTask
36 | * public class AppConfig {
37 | *
38 | * @Bean
39 | * public MyCommandLineRunner myCommandLineRunner() {
40 | * return new MyCommandLineRunner()
41 | * }
42 | * }
43 | *
44 | *
45 | * Note that only one of your configuration classes needs to have the
46 | * @EnableTask annotation. Once you have an
47 | * @EnableTask class in your configuration the task will have the Spring
48 | * Cloud Task features available.
49 | *
50 | * @author Glenn Renfro
51 | *
52 | */
53 | @Target(ElementType.TYPE)
54 | @Retention(RetentionPolicy.RUNTIME)
55 | @Documented
56 | @Inherited
57 | @Import(TaskLifecycleConfiguration.class)
58 | public @interface EnableTask {
59 |
60 | }
61 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/test/java/org/springframework/cloud/task/listener/TaskExceptionTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.listener;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | import static org.assertj.core.api.Assertions.assertThat;
22 |
23 | /**
24 | * @author Glenn Renfro
25 | */
26 | public class TaskExceptionTests {
27 |
28 | private static final String ERROR_MESSAGE = "ERROR MESSAGE";
29 |
30 | @Test
31 | public void testTaskException() {
32 | TaskException taskException = new TaskException(ERROR_MESSAGE);
33 | assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
34 |
35 | taskException = new TaskException(ERROR_MESSAGE, new IllegalStateException(ERROR_MESSAGE));
36 | assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
37 | assertThat(taskException.getCause()).isNotNull();
38 | assertThat(taskException.getCause().getMessage()).isEqualTo(ERROR_MESSAGE);
39 | }
40 |
41 | @Test
42 | public void testTaskExecutionException() {
43 | TaskExecutionException taskException = new TaskExecutionException(ERROR_MESSAGE);
44 | assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
45 |
46 | taskException = new TaskExecutionException(ERROR_MESSAGE, new IllegalStateException(ERROR_MESSAGE));
47 | assertThat(taskException.getMessage()).isEqualTo(ERROR_MESSAGE);
48 | assertThat(taskException.getCause()).isNotNull();
49 | assertThat(taskException.getCause().getMessage()).isEqualTo(ERROR_MESSAGE);
50 | }
51 |
52 | }
53 |
--------------------------------------------------------------------------------
/spring-cloud-task-stream/src/test/java/org/springframework/cloud/task/batch/listener/JobInstanceEventTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2016-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.batch.listener;
18 |
19 | import org.junit.jupiter.api.Test;
20 |
21 | import org.springframework.cloud.task.batch.listener.support.JobInstanceEvent;
22 |
23 | import static org.assertj.core.api.Assertions.assertThat;
24 |
25 | /**
26 | * @author Glenn Renfro
27 | */
28 | public class JobInstanceEventTests {
29 |
30 | private static final long INSTANCE_ID = 1;
31 |
32 | private static final String JOB_NAME = "FOOBAR";
33 |
34 | @Test
35 | public void testConstructor() {
36 | JobInstanceEvent jobInstanceEvent = new JobInstanceEvent(INSTANCE_ID, JOB_NAME);
37 | assertThat(jobInstanceEvent.getInstanceId()).isEqualTo(INSTANCE_ID);
38 | assertThat(jobInstanceEvent.getJobName()).isEqualTo(JOB_NAME);
39 | }
40 |
41 | @Test
42 | public void testEmptyConstructor() {
43 | JobInstanceEvent jobInstanceEvent = new JobInstanceEvent();
44 | assertThat(jobInstanceEvent.getJobName()).isNull();
45 | }
46 |
47 | @Test
48 | public void testEmptyConstructorEmptyId() {
49 | JobInstanceEvent jobInstanceEvent = new JobInstanceEvent();
50 | jobInstanceEvent.getInstanceId();
51 | }
52 |
53 | @Test
54 | public void testToString() {
55 | JobInstanceEvent jobInstanceEvent = new JobInstanceEvent(INSTANCE_ID, JOB_NAME);
56 | assertThat(jobInstanceEvent.toString()).isEqualTo("JobInstanceEvent: id=1, version=null, Job=[FOOBAR]");
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/DefaultTaskExecutionObservationConvention.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.listener;
18 |
19 | import io.micrometer.common.KeyValues;
20 |
21 | import org.springframework.cloud.task.repository.TaskExecution;
22 |
23 | /**
24 | * /** Default {@link TaskExecutionObservationConvention} implementation.
25 | *
26 | * @author Glenn Renfro
27 | * @since 3.0.0
28 | */
29 | public class DefaultTaskExecutionObservationConvention implements TaskExecutionObservationConvention {
30 |
31 | @Override
32 | public KeyValues getLowCardinalityKeyValues(TaskExecutionObservationContext context) {
33 | return getKeyValuesForTaskExecution(context);
34 | }
35 |
36 | @Override
37 | public KeyValues getHighCardinalityKeyValues(TaskExecutionObservationContext context) {
38 | return KeyValues.empty();
39 | }
40 |
41 | private KeyValues getKeyValuesForTaskExecution(TaskExecutionObservationContext context) {
42 | TaskExecution execution = context.getTaskExecution();
43 | return KeyValues.of(TaskExecutionObservation.TaskKeyValues.TASK_STATUS.asString(), context.getStatus(),
44 | TaskExecutionObservation.TaskKeyValues.TASK_EXIT_CODE.asString(),
45 | String.valueOf(execution.getExitCode()),
46 | TaskExecutionObservation.TaskKeyValues.TASK_EXECUTION_ID.asString(),
47 | String.valueOf(execution.getExecutionId()));
48 | }
49 |
50 | @Override
51 | public String getName() {
52 | return "spring.cloud.task";
53 | }
54 |
55 | }
56 |
--------------------------------------------------------------------------------
/spring-cloud-task-core/src/main/java/org/springframework/cloud/task/listener/TaskExecutionObservationContext.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022-present the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.task.listener;
18 |
19 | import java.util.function.Supplier;
20 |
21 | import io.micrometer.observation.Observation;
22 | import io.micrometer.observation.ObservationHandler;
23 |
24 | import org.springframework.cloud.task.repository.TaskExecution;
25 |
26 | /**
27 | * A mutable holder of the {@link TaskExecution} required by a {@link ObservationHandler}.
28 | *
29 | * @author Glenn Renfro
30 | * @since 3.0.0
31 | */
32 | public class TaskExecutionObservationContext extends Observation.Context
33 | implements Supplier