Skip to content

Commit ebcc53a

Browse files
committed
Include tasks with custom triggers in scheduledtasks endpoint output
Closes spring-projectsgh-15815
1 parent 1f67707 commit ebcc53a

File tree

3 files changed

+117
-8
lines changed

3 files changed

+117
-8
lines changed

spring-boot-project/spring-boot-actuator-autoconfigure/src/test/java/org/springframework/boot/actuate/autoconfigure/endpoint/web/documentation/ScheduledTasksEndpointDocumentationTests.java

+39-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2018 the original author or authors.
2+
* Copyright 2012-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@
1717
package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation;
1818

1919
import java.util.Collection;
20+
import java.util.Date;
2021
import java.util.regex.Pattern;
2122

2223
import org.junit.Test;
@@ -26,9 +27,13 @@
2627
import org.springframework.context.annotation.Configuration;
2728
import org.springframework.context.annotation.Import;
2829
import org.springframework.restdocs.payload.FieldDescriptor;
30+
import org.springframework.scheduling.Trigger;
31+
import org.springframework.scheduling.TriggerContext;
2932
import org.springframework.scheduling.annotation.EnableScheduling;
3033
import org.springframework.scheduling.annotation.Scheduled;
34+
import org.springframework.scheduling.annotation.SchedulingConfigurer;
3135
import org.springframework.scheduling.config.ScheduledTaskHolder;
36+
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
3237

3338
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
3439
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
@@ -56,12 +61,12 @@ public void scheduledTasks() throws Exception {
5661
"com.example.Processor")),
5762
responseFields(
5863
fieldWithPath("cron").description("Cron tasks, if any."),
59-
targetFieldWithPrefix("cron.[]"),
64+
targetFieldWithPrefix("cron.[]."),
6065
fieldWithPath("cron.[].expression")
6166
.description("Cron expression."),
6267
fieldWithPath("fixedDelay")
6368
.description("Fixed delay tasks, if any."),
64-
targetFieldWithPrefix("fixedDelay.[]"),
69+
targetFieldWithPrefix("fixedDelay.[]."),
6570
initialDelayWithPrefix("fixedDelay.[]."),
6671
fieldWithPath("fixedDelay.[].interval").description(
6772
"Interval, in milliseconds, between the end of the last"
@@ -71,7 +76,13 @@ public void scheduledTasks() throws Exception {
7176
targetFieldWithPrefix("fixedRate.[]."),
7277
fieldWithPath("fixedRate.[].interval").description(
7378
"Interval, in milliseconds, between the start of each execution."),
74-
initialDelayWithPrefix("fixedRate.[]."))));
79+
initialDelayWithPrefix("fixedRate.[]."),
80+
fieldWithPath("custom").description(
81+
"Tasks with custom triggers, if any."),
82+
targetFieldWithPrefix("custom.[]."),
83+
fieldWithPath("custom.[].trigger")
84+
.description("Trigger for the task."))))
85+
.andDo(MockMvcResultHandlers.print());
7586
}
7687

7788
private FieldDescriptor targetFieldWithPrefix(String prefix) {
@@ -109,6 +120,30 @@ public void retrieveIssues() {
109120

110121
}
111122

123+
@Bean
124+
public SchedulingConfigurer schedulingConfigurer() {
125+
return (registrar) -> registrar.addTriggerTask(new CustomTriggeredRunnable(),
126+
new CustomTrigger());
127+
}
128+
129+
static class CustomTrigger implements Trigger {
130+
131+
@Override
132+
public Date nextExecutionTime(TriggerContext triggerContext) {
133+
return new Date();
134+
}
135+
136+
}
137+
138+
static class CustomTriggeredRunnable implements Runnable {
139+
140+
@Override
141+
public void run() {
142+
143+
}
144+
145+
}
146+
112147
}
113148

114149
}

spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpoint.java

+33-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2018 the original author or authors.
2+
* Copyright 2012-2019 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -42,7 +42,8 @@
4242
import org.springframework.scheduling.support.ScheduledMethodRunnable;
4343

4444
/**
45-
* {@link Endpoint} to expose information about an application's scheduled tasks.
45+
* {@link Endpoint @Endpoint} to expose information about an application's scheduled
46+
* tasks.
4647
*
4748
* @author Andy Wilkinson
4849
* @since 2.0.0
@@ -78,6 +79,8 @@ public static final class ScheduledTasksReport {
7879

7980
private final List<TaskDescription> fixedRate;
8081

82+
private final List<TaskDescription> custom;
83+
8184
private ScheduledTasksReport(
8285
Map<TaskType, List<TaskDescription>> descriptionsByType) {
8386
this.cron = descriptionsByType.getOrDefault(TaskType.CRON,
@@ -86,6 +89,8 @@ private ScheduledTasksReport(
8689
Collections.emptyList());
8790
this.fixedRate = descriptionsByType.getOrDefault(TaskType.FIXED_RATE,
8891
Collections.emptyList());
92+
this.custom = descriptionsByType.getOrDefault(TaskType.CUSTOM_TRIGGER,
93+
Collections.emptyList());
8994
}
9095

9196
public List<TaskDescription> getCron() {
@@ -100,6 +105,10 @@ public List<TaskDescription> getFixedRate() {
100105
return this.fixedRate;
101106
}
102107

108+
public List<TaskDescription> getCustom() {
109+
return this.custom;
110+
}
111+
103112
}
104113

105114
/**
@@ -143,7 +152,7 @@ private static TaskDescription describeTriggerTask(TriggerTask triggerTask) {
143152
}
144153
return new FixedDelayTaskDescription(triggerTask, periodicTrigger);
145154
}
146-
return null;
155+
return new CustomTriggerTaskDescription(triggerTask);
147156
}
148157

149158
protected TaskDescription(TaskType type, Runnable runnable) {
@@ -249,6 +258,26 @@ public String getExpression() {
249258

250259
}
251260

261+
/**
262+
* A description of a {@link TriggerTask} with a custom {@link Trigger}.
263+
*
264+
* @since 2.1.3
265+
*/
266+
public static final class CustomTriggerTaskDescription extends TaskDescription {
267+
268+
private final String trigger;
269+
270+
private CustomTriggerTaskDescription(TriggerTask task) {
271+
super(TaskType.CUSTOM_TRIGGER, task.getRunnable());
272+
this.trigger = task.getTrigger().toString();
273+
}
274+
275+
public String getTrigger() {
276+
return this.trigger;
277+
}
278+
279+
}
280+
252281
/**
253282
* A description of a {@link Task Task's} {@link Runnable}.
254283
*
@@ -277,7 +306,7 @@ public String getTarget() {
277306

278307
private enum TaskType {
279308

280-
CRON, FIXED_DELAY, FIXED_RATE
309+
CRON, CUSTOM_TRIGGER, FIXED_DELAY, FIXED_RATE
281310

282311
}
283312

spring-boot-project/spring-boot-actuator/src/test/java/org/springframework/boot/actuate/scheduling/ScheduledTasksEndpointTests.java

+45
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,20 @@
1717
package org.springframework.boot.actuate.scheduling;
1818

1919
import java.util.Collection;
20+
import java.util.Date;
2021
import java.util.concurrent.TimeUnit;
2122
import java.util.function.Consumer;
2223

2324
import org.junit.Test;
2425

2526
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CronTaskDescription;
27+
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CustomTriggerTaskDescription;
2628
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedDelayTaskDescription;
2729
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedRateTaskDescription;
2830
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksReport;
2931
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
3032
import org.springframework.context.annotation.Bean;
33+
import org.springframework.scheduling.Trigger;
3134
import org.springframework.scheduling.annotation.EnableScheduling;
3235
import org.springframework.scheduling.annotation.Scheduled;
3336
import org.springframework.scheduling.annotation.SchedulingConfigurer;
@@ -53,6 +56,7 @@ public void cronScheduledMethodIsReported() {
5356
run(CronScheduledMethod.class, (tasks) -> {
5457
assertThat(tasks.getFixedDelay()).isEmpty();
5558
assertThat(tasks.getFixedRate()).isEmpty();
59+
assertThat(tasks.getCustom()).isEmpty();
5660
assertThat(tasks.getCron()).hasSize(1);
5761
CronTaskDescription description = (CronTaskDescription) tasks.getCron()
5862
.get(0);
@@ -67,6 +71,7 @@ public void cronTriggerIsReported() {
6771
run(CronTriggerTask.class, (tasks) -> {
6872
assertThat(tasks.getFixedRate()).isEmpty();
6973
assertThat(tasks.getFixedDelay()).isEmpty();
74+
assertThat(tasks.getCustom()).isEmpty();
7075
assertThat(tasks.getCron()).hasSize(1);
7176
CronTaskDescription description = (CronTaskDescription) tasks.getCron()
7277
.get(0);
@@ -81,6 +86,7 @@ public void fixedDelayScheduledMethodIsReported() {
8186
run(FixedDelayScheduledMethod.class, (tasks) -> {
8287
assertThat(tasks.getCron()).isEmpty();
8388
assertThat(tasks.getFixedRate()).isEmpty();
89+
assertThat(tasks.getCustom()).isEmpty();
8490
assertThat(tasks.getFixedDelay()).hasSize(1);
8591
FixedDelayTaskDescription description = (FixedDelayTaskDescription) tasks
8692
.getFixedDelay().get(0);
@@ -96,6 +102,7 @@ public void fixedDelayTriggerIsReported() {
96102
run(FixedDelayTriggerTask.class, (tasks) -> {
97103
assertThat(tasks.getCron()).isEmpty();
98104
assertThat(tasks.getFixedRate()).isEmpty();
105+
assertThat(tasks.getCustom()).isEmpty();
99106
assertThat(tasks.getFixedDelay()).hasSize(1);
100107
FixedDelayTaskDescription description = (FixedDelayTaskDescription) tasks
101108
.getFixedDelay().get(0);
@@ -111,6 +118,7 @@ public void fixedRateScheduledMethodIsReported() {
111118
run(FixedRateScheduledMethod.class, (tasks) -> {
112119
assertThat(tasks.getCron()).isEmpty();
113120
assertThat(tasks.getFixedDelay()).isEmpty();
121+
assertThat(tasks.getCustom()).isEmpty();
114122
assertThat(tasks.getFixedRate()).hasSize(1);
115123
FixedRateTaskDescription description = (FixedRateTaskDescription) tasks
116124
.getFixedRate().get(0);
@@ -126,6 +134,7 @@ public void fixedRateTriggerIsReported() {
126134
run(FixedRateTriggerTask.class, (tasks) -> {
127135
assertThat(tasks.getCron()).isEmpty();
128136
assertThat(tasks.getFixedDelay()).isEmpty();
137+
assertThat(tasks.getCustom()).isEmpty();
129138
assertThat(tasks.getFixedRate()).hasSize(1);
130139
FixedRateTaskDescription description = (FixedRateTaskDescription) tasks
131140
.getFixedRate().get(0);
@@ -136,6 +145,22 @@ public void fixedRateTriggerIsReported() {
136145
});
137146
}
138147

148+
@Test
149+
public void taskWithCustomTriggerIsReported() {
150+
run(CustomTriggerTask.class, (tasks) -> {
151+
assertThat(tasks.getCron()).isEmpty();
152+
assertThat(tasks.getFixedDelay()).isEmpty();
153+
assertThat(tasks.getFixedRate()).isEmpty();
154+
assertThat(tasks.getCustom()).hasSize(1);
155+
CustomTriggerTaskDescription description = (CustomTriggerTaskDescription) tasks
156+
.getCustom().get(0);
157+
assertThat(description.getRunnable().getTarget())
158+
.isEqualTo(CustomTriggerRunnable.class.getName());
159+
assertThat(description.getTrigger())
160+
.isEqualTo(CustomTriggerTask.trigger.toString());
161+
});
162+
}
163+
139164
private void run(Class<?> configuration, Consumer<ScheduledTasksReport> consumer) {
140165
this.contextRunner.withUserConfiguration(configuration).run((context) -> consumer
141166
.accept(context.getBean(ScheduledTasksEndpoint.class).scheduledTasks()));
@@ -212,6 +237,17 @@ public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
212237

213238
}
214239

240+
private static class CustomTriggerTask implements SchedulingConfigurer {
241+
242+
private static final Trigger trigger = (context) -> new Date();
243+
244+
@Override
245+
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
246+
taskRegistrar.addTriggerTask(new CustomTriggerRunnable(), trigger);
247+
}
248+
249+
}
250+
215251
private static class CronTriggerRunnable implements Runnable {
216252

217253
@Override
@@ -239,4 +275,13 @@ public void run() {
239275

240276
}
241277

278+
private static class CustomTriggerRunnable implements Runnable {
279+
280+
@Override
281+
public void run() {
282+
283+
}
284+
285+
}
286+
242287
}

0 commit comments

Comments
 (0)