Include tasks with custom triggers in scheduledtasks endpoint output

Closes gh-15815
pull/15889/head
Andy Wilkinson 6 years ago
parent 1f67707509
commit ebcc53a9b7

@ -1,5 +1,5 @@
/*
* Copyright 2012-2018 the original author or authors.
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -17,6 +17,7 @@
package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation;
import java.util.Collection;
import java.util.Date;
import java.util.regex.Pattern;
import org.junit.Test;
@ -26,9 +27,13 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.TriggerContext;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskHolder;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
@ -56,12 +61,12 @@ public class ScheduledTasksEndpointDocumentationTests
"com.example.Processor")),
responseFields(
fieldWithPath("cron").description("Cron tasks, if any."),
targetFieldWithPrefix("cron.[]"),
targetFieldWithPrefix("cron.[]."),
fieldWithPath("cron.[].expression")
.description("Cron expression."),
fieldWithPath("fixedDelay")
.description("Fixed delay tasks, if any."),
targetFieldWithPrefix("fixedDelay.[]"),
targetFieldWithPrefix("fixedDelay.[]."),
initialDelayWithPrefix("fixedDelay.[]."),
fieldWithPath("fixedDelay.[].interval").description(
"Interval, in milliseconds, between the end of the last"
@ -71,7 +76,13 @@ public class ScheduledTasksEndpointDocumentationTests
targetFieldWithPrefix("fixedRate.[]."),
fieldWithPath("fixedRate.[].interval").description(
"Interval, in milliseconds, between the start of each execution."),
initialDelayWithPrefix("fixedRate.[]."))));
initialDelayWithPrefix("fixedRate.[]."),
fieldWithPath("custom").description(
"Tasks with custom triggers, if any."),
targetFieldWithPrefix("custom.[]."),
fieldWithPath("custom.[].trigger")
.description("Trigger for the task."))))
.andDo(MockMvcResultHandlers.print());
}
private FieldDescriptor targetFieldWithPrefix(String prefix) {
@ -109,6 +120,30 @@ public class ScheduledTasksEndpointDocumentationTests
}
@Bean
public SchedulingConfigurer schedulingConfigurer() {
return (registrar) -> registrar.addTriggerTask(new CustomTriggeredRunnable(),
new CustomTrigger());
}
static class CustomTrigger implements Trigger {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
return new Date();
}
}
static class CustomTriggeredRunnable implements Runnable {
@Override
public void run() {
}
}
}
}

@ -1,5 +1,5 @@
/*
* Copyright 2012-2018 the original author or authors.
* Copyright 2012-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -42,7 +42,8 @@ import org.springframework.scheduling.support.PeriodicTrigger;
import org.springframework.scheduling.support.ScheduledMethodRunnable;
/**
* {@link Endpoint} to expose information about an application's scheduled tasks.
* {@link Endpoint @Endpoint} to expose information about an application's scheduled
* tasks.
*
* @author Andy Wilkinson
* @since 2.0.0
@ -78,6 +79,8 @@ public class ScheduledTasksEndpoint {
private final List<TaskDescription> fixedRate;
private final List<TaskDescription> custom;
private ScheduledTasksReport(
Map<TaskType, List<TaskDescription>> descriptionsByType) {
this.cron = descriptionsByType.getOrDefault(TaskType.CRON,
@ -86,6 +89,8 @@ public class ScheduledTasksEndpoint {
Collections.emptyList());
this.fixedRate = descriptionsByType.getOrDefault(TaskType.FIXED_RATE,
Collections.emptyList());
this.custom = descriptionsByType.getOrDefault(TaskType.CUSTOM_TRIGGER,
Collections.emptyList());
}
public List<TaskDescription> getCron() {
@ -100,6 +105,10 @@ public class ScheduledTasksEndpoint {
return this.fixedRate;
}
public List<TaskDescription> getCustom() {
return this.custom;
}
}
/**
@ -143,7 +152,7 @@ public class ScheduledTasksEndpoint {
}
return new FixedDelayTaskDescription(triggerTask, periodicTrigger);
}
return null;
return new CustomTriggerTaskDescription(triggerTask);
}
protected TaskDescription(TaskType type, Runnable runnable) {
@ -249,6 +258,26 @@ public class ScheduledTasksEndpoint {
}
/**
* A description of a {@link TriggerTask} with a custom {@link Trigger}.
*
* @since 2.1.3
*/
public static final class CustomTriggerTaskDescription extends TaskDescription {
private final String trigger;
private CustomTriggerTaskDescription(TriggerTask task) {
super(TaskType.CUSTOM_TRIGGER, task.getRunnable());
this.trigger = task.getTrigger().toString();
}
public String getTrigger() {
return this.trigger;
}
}
/**
* A description of a {@link Task Task's} {@link Runnable}.
*
@ -277,7 +306,7 @@ public class ScheduledTasksEndpoint {
private enum TaskType {
CRON, FIXED_DELAY, FIXED_RATE
CRON, CUSTOM_TRIGGER, FIXED_DELAY, FIXED_RATE
}

@ -17,17 +17,20 @@
package org.springframework.boot.actuate.scheduling;
import java.util.Collection;
import java.util.Date;
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import org.junit.Test;
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CronTaskDescription;
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.CustomTriggerTaskDescription;
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedDelayTaskDescription;
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.FixedRateTaskDescription;
import org.springframework.boot.actuate.scheduling.ScheduledTasksEndpoint.ScheduledTasksReport;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.Trigger;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
@ -53,6 +56,7 @@ public class ScheduledTasksEndpointTests {
run(CronScheduledMethod.class, (tasks) -> {
assertThat(tasks.getFixedDelay()).isEmpty();
assertThat(tasks.getFixedRate()).isEmpty();
assertThat(tasks.getCustom()).isEmpty();
assertThat(tasks.getCron()).hasSize(1);
CronTaskDescription description = (CronTaskDescription) tasks.getCron()
.get(0);
@ -67,6 +71,7 @@ public class ScheduledTasksEndpointTests {
run(CronTriggerTask.class, (tasks) -> {
assertThat(tasks.getFixedRate()).isEmpty();
assertThat(tasks.getFixedDelay()).isEmpty();
assertThat(tasks.getCustom()).isEmpty();
assertThat(tasks.getCron()).hasSize(1);
CronTaskDescription description = (CronTaskDescription) tasks.getCron()
.get(0);
@ -81,6 +86,7 @@ public class ScheduledTasksEndpointTests {
run(FixedDelayScheduledMethod.class, (tasks) -> {
assertThat(tasks.getCron()).isEmpty();
assertThat(tasks.getFixedRate()).isEmpty();
assertThat(tasks.getCustom()).isEmpty();
assertThat(tasks.getFixedDelay()).hasSize(1);
FixedDelayTaskDescription description = (FixedDelayTaskDescription) tasks
.getFixedDelay().get(0);
@ -96,6 +102,7 @@ public class ScheduledTasksEndpointTests {
run(FixedDelayTriggerTask.class, (tasks) -> {
assertThat(tasks.getCron()).isEmpty();
assertThat(tasks.getFixedRate()).isEmpty();
assertThat(tasks.getCustom()).isEmpty();
assertThat(tasks.getFixedDelay()).hasSize(1);
FixedDelayTaskDescription description = (FixedDelayTaskDescription) tasks
.getFixedDelay().get(0);
@ -111,6 +118,7 @@ public class ScheduledTasksEndpointTests {
run(FixedRateScheduledMethod.class, (tasks) -> {
assertThat(tasks.getCron()).isEmpty();
assertThat(tasks.getFixedDelay()).isEmpty();
assertThat(tasks.getCustom()).isEmpty();
assertThat(tasks.getFixedRate()).hasSize(1);
FixedRateTaskDescription description = (FixedRateTaskDescription) tasks
.getFixedRate().get(0);
@ -126,6 +134,7 @@ public class ScheduledTasksEndpointTests {
run(FixedRateTriggerTask.class, (tasks) -> {
assertThat(tasks.getCron()).isEmpty();
assertThat(tasks.getFixedDelay()).isEmpty();
assertThat(tasks.getCustom()).isEmpty();
assertThat(tasks.getFixedRate()).hasSize(1);
FixedRateTaskDescription description = (FixedRateTaskDescription) tasks
.getFixedRate().get(0);
@ -136,6 +145,22 @@ public class ScheduledTasksEndpointTests {
});
}
@Test
public void taskWithCustomTriggerIsReported() {
run(CustomTriggerTask.class, (tasks) -> {
assertThat(tasks.getCron()).isEmpty();
assertThat(tasks.getFixedDelay()).isEmpty();
assertThat(tasks.getFixedRate()).isEmpty();
assertThat(tasks.getCustom()).hasSize(1);
CustomTriggerTaskDescription description = (CustomTriggerTaskDescription) tasks
.getCustom().get(0);
assertThat(description.getRunnable().getTarget())
.isEqualTo(CustomTriggerRunnable.class.getName());
assertThat(description.getTrigger())
.isEqualTo(CustomTriggerTask.trigger.toString());
});
}
private void run(Class<?> configuration, Consumer<ScheduledTasksReport> consumer) {
this.contextRunner.withUserConfiguration(configuration).run((context) -> consumer
.accept(context.getBean(ScheduledTasksEndpoint.class).scheduledTasks()));
@ -212,6 +237,17 @@ public class ScheduledTasksEndpointTests {
}
private static class CustomTriggerTask implements SchedulingConfigurer {
private static final Trigger trigger = (context) -> new Date();
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.addTriggerTask(new CustomTriggerRunnable(), trigger);
}
}
private static class CronTriggerRunnable implements Runnable {
@Override
@ -239,4 +275,13 @@ public class ScheduledTasksEndpointTests {
}
private static class CustomTriggerRunnable implements Runnable {
@Override
public void run() {
}
}
}

Loading…
Cancel
Save