mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Add Quartz actuator endpoint
See gh-10364
This commit is contained in:
parent
095ff18854
commit
9795061360
@ -86,6 +86,7 @@ dependencies {
|
||||
optional("org.mongodb:mongodb-driver-reactivestreams")
|
||||
optional("org.mongodb:mongodb-driver-sync")
|
||||
optional("org.neo4j.driver:neo4j-java-driver")
|
||||
optional("org.quartz-scheduler:quartz")
|
||||
optional("org.springframework:spring-jdbc")
|
||||
optional("org.springframework:spring-jms")
|
||||
optional("org.springframework:spring-messaging")
|
||||
|
@ -67,6 +67,7 @@ include::endpoints/loggers.adoc[leveloffset=+1]
|
||||
include::endpoints/mappings.adoc[leveloffset=+1]
|
||||
include::endpoints/metrics.adoc[leveloffset=+1]
|
||||
include::endpoints/prometheus.adoc[leveloffset=+1]
|
||||
include::endpoints/quartz.adoc[leveloffset=+1]
|
||||
include::endpoints/scheduledtasks.adoc[leveloffset=+1]
|
||||
include::endpoints/sessions.adoc[leveloffset=+1]
|
||||
include::endpoints/shutdown.adoc[leveloffset=+1]
|
||||
|
@ -0,0 +1,45 @@
|
||||
[[quartz]]
|
||||
= Quartz (`quartz`)
|
||||
|
||||
The `quartz` endpoint provides information about the scheduled jobs that are managed by
|
||||
Quartz Scheduler.
|
||||
|
||||
|
||||
|
||||
[[quartz-report]]
|
||||
== Retrieving the Quartz report
|
||||
|
||||
To retrieve the Quartz, make a `GET` request to `/application/quartz`,
|
||||
as shown in the following curl-based example:
|
||||
|
||||
include::{snippets}quartz-report/curl-request.adoc[]
|
||||
|
||||
The resulting response is similar to the following:
|
||||
|
||||
include::{snippets}quartz-report/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
[[quartz-job]]
|
||||
== Retrieving the Quartz job details
|
||||
|
||||
To retrieve the Quartz, make a `GET` request to `/application/quartz/{group}/{name}`,
|
||||
as shown in the following curl-based example:
|
||||
|
||||
include::{snippets}quartz-job/curl-request.adoc[]
|
||||
|
||||
The preceding example retrieves the job with the `group` of `groupOne` and `name` of
|
||||
`jobOne`. The resulting response is similar to the following:
|
||||
|
||||
include::{snippets}quartz-job/http-response.adoc[]
|
||||
|
||||
|
||||
|
||||
[[quartz-job-response-structure]]
|
||||
=== Response Structure
|
||||
|
||||
The response contains details of the scheduled job. The following table describes the
|
||||
structure of the response:
|
||||
|
||||
[cols="2,1,3"]
|
||||
include::{snippets}quartz-job/response-fields.adoc[]
|
@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.quartz;
|
||||
|
||||
import org.quartz.Scheduler;
|
||||
|
||||
import org.springframework.boot.actuate.autoconfigure.endpoint.condition.ConditionalOnAvailableEndpoint;
|
||||
import org.springframework.boot.actuate.quartz.QuartzEndpoint;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
/**
|
||||
* {@link EnableAutoConfiguration Auto-configuration} for {@link QuartzEndpoint}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(Scheduler.class)
|
||||
@AutoConfigureAfter(QuartzAutoConfiguration.class)
|
||||
@ConditionalOnAvailableEndpoint(endpoint = QuartzEndpoint.class)
|
||||
public class QuartzEndpointAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean(Scheduler.class)
|
||||
@ConditionalOnMissingBean
|
||||
public QuartzEndpoint quartzEndpoint(Scheduler scheduler) {
|
||||
return new QuartzEndpoint(scheduler);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Auto-configuration for actuator Quartz Scheduler concerns.
|
||||
*/
|
||||
package org.springframework.boot.actuate.autoconfigure.quartz;
|
@ -80,6 +80,7 @@ org.springframework.boot.actuate.autoconfigure.metrics.web.tomcat.TomcatMetricsA
|
||||
org.springframework.boot.actuate.autoconfigure.mongo.MongoHealthContributorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.mongo.MongoReactiveHealthContributorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.neo4j.Neo4jHealthContributorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.quartz.QuartzEndpointAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.r2dbc.ConnectionFactoryHealthContributorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.redis.RedisHealthContributorAutoConfiguration,\
|
||||
org.springframework.boot.actuate.autoconfigure.redis.RedisReactiveHealthContributorAutoConfiguration,\
|
||||
|
@ -0,0 +1,128 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.endpoint.web.documentation;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobBuilder;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SimpleScheduleBuilder;
|
||||
import org.quartz.Trigger;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.quartz.impl.matchers.GroupMatcher;
|
||||
|
||||
import org.springframework.boot.actuate.quartz.QuartzEndpoint;
|
||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.preprocessResponse;
|
||||
import static org.springframework.restdocs.operation.preprocess.Preprocessors.replacePattern;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
|
||||
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
|
||||
/**
|
||||
* Tests for generating documentation describing the {@link QuartzEndpoint}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class QuartzEndpointDocumentationTests extends MockMvcEndpointDocumentationTests {
|
||||
|
||||
private static final JobDetail jobOne = JobBuilder.newJob(Job.class).withIdentity("jobOne", "groupOne")
|
||||
.withDescription("My first job").build();
|
||||
|
||||
private static final JobDetail jobTwo = JobBuilder.newJob(Job.class).withIdentity("jobTwo", "groupOne").build();
|
||||
|
||||
private static final JobDetail jobThree = JobBuilder.newJob(Job.class).withIdentity("jobThree", "groupTwo").build();
|
||||
|
||||
private static final Trigger triggerOne = TriggerBuilder.newTrigger().forJob(jobOne).withIdentity("triggerOne")
|
||||
.withDescription("My first trigger").modifiedByCalendar("myCalendar")
|
||||
.startAt(Date.from(Instant.parse("2017-12-01T12:00:00Z")))
|
||||
.endAt(Date.from(Instant.parse("2017-12-01T12:30:00Z")))
|
||||
.withSchedule(SimpleScheduleBuilder.repeatMinutelyForever()).build();
|
||||
|
||||
private static final Trigger triggerTwo = TriggerBuilder.newTrigger().forJob(jobOne).withIdentity("triggerTwo")
|
||||
.withDescription("My second trigger").modifiedByCalendar("myCalendar")
|
||||
.startAt(Date.from(Instant.parse("2017-12-01T00:00:00Z")))
|
||||
.endAt(Date.from(Instant.parse("2017-12-10T00:00:00Z")))
|
||||
.withSchedule(SimpleScheduleBuilder.repeatHourlyForever()).build();
|
||||
|
||||
@MockBean
|
||||
private Scheduler scheduler;
|
||||
|
||||
@Test
|
||||
public void quartzReport() throws Exception {
|
||||
String groupOne = jobOne.getKey().getGroup();
|
||||
String groupTwo = jobThree.getKey().getGroup();
|
||||
given(this.scheduler.getJobGroupNames()).willReturn(Arrays.asList(groupOne, groupTwo));
|
||||
given(this.scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupOne)))
|
||||
.willReturn(new HashSet<>(Arrays.asList(jobOne.getKey(), jobTwo.getKey())));
|
||||
given(this.scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupTwo)))
|
||||
.willReturn(Collections.singleton(jobThree.getKey()));
|
||||
this.mockMvc.perform(get("/application/quartz")).andExpect(status().isOk()).andDo(document("quartz/report"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quartzJob() throws Exception {
|
||||
JobKey jobKey = jobOne.getKey();
|
||||
given(this.scheduler.getJobDetail(jobKey)).willReturn(jobOne);
|
||||
given(this.scheduler.getTriggersOfJob(jobKey)).willAnswer(invocation -> Arrays.asList(triggerOne, triggerTwo));
|
||||
this.mockMvc.perform(get("/application/quartz/groupOne/jobOne")).andExpect(status().isOk()).andDo(document(
|
||||
"quartz/job",
|
||||
preprocessResponse(replacePattern(Pattern.compile("org.quartz.Job"), "com.example.MyJob")),
|
||||
responseFields(fieldWithPath("jobGroup").description("Job group."),
|
||||
fieldWithPath("jobName").description("Job name."),
|
||||
fieldWithPath("description").description("Job description, if any."),
|
||||
fieldWithPath("className").description("Job class."),
|
||||
fieldWithPath("triggers.[].triggerGroup").description("Trigger group."),
|
||||
fieldWithPath("triggers.[].triggerName").description("Trigger name."),
|
||||
fieldWithPath("triggers.[].description").description("Trigger description, if any."),
|
||||
fieldWithPath("triggers.[].calendarName").description("Trigger's calendar name, if any."),
|
||||
fieldWithPath("triggers.[].startTime").description("Trigger's start time."),
|
||||
fieldWithPath("triggers.[].endTime").description("Trigger's end time."),
|
||||
fieldWithPath("triggers.[].nextFireTime").description("Trigger's next fire time."),
|
||||
fieldWithPath("triggers.[].previousFireTime")
|
||||
.description("Trigger's previous fire time, if any."),
|
||||
fieldWithPath("triggers.[].finalFireTime").description("Trigger's final fire time, if any."))));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(BaseDocumentationConfiguration.class)
|
||||
static class TestConfiguration {
|
||||
|
||||
@Bean
|
||||
public QuartzEndpoint endpoint(Scheduler scheduler) {
|
||||
return new QuartzEndpoint(scheduler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.autoconfigure.quartz;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.quartz.Scheduler;
|
||||
|
||||
import org.springframework.boot.actuate.quartz.QuartzEndpoint;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigurations;
|
||||
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link QuartzEndpointAutoConfiguration}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class QuartzEndpointAutoConfigurationTests {
|
||||
|
||||
private final ApplicationContextRunner contextRunner = new ApplicationContextRunner()
|
||||
.withConfiguration(AutoConfigurations.of(QuartzEndpointAutoConfiguration.class))
|
||||
.withUserConfiguration(QuartzConfiguration.class);
|
||||
|
||||
@Test
|
||||
public void runShouldHaveEndpointBean() {
|
||||
this.contextRunner.run((context) -> assertThat(context).hasSingleBean(QuartzEndpoint.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runWhenEnabledPropertyIsFalseShouldNotHaveEndpointBean() throws Exception {
|
||||
this.contextRunner.withPropertyValues("management.endpoint.quartz.enabled:false")
|
||||
.run((context) -> assertThat(context).doesNotHaveBean(QuartzEndpoint.class));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class QuartzConfiguration {
|
||||
|
||||
@Bean
|
||||
public Scheduler scheduler() {
|
||||
return mock(Scheduler.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -48,6 +48,7 @@ dependencies {
|
||||
optional("org.mongodb:mongodb-driver-reactivestreams")
|
||||
optional("org.mongodb:mongodb-driver-sync")
|
||||
optional("org.neo4j.driver:neo4j-java-driver")
|
||||
optional("org.quartz-scheduler:quartz")
|
||||
optional("org.springframework:spring-jdbc")
|
||||
optional("org.springframework:spring-messaging")
|
||||
optional("org.springframework:spring-webflux")
|
||||
|
@ -0,0 +1,201 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.quartz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.SchedulerException;
|
||||
import org.quartz.Trigger;
|
||||
import org.quartz.impl.matchers.GroupMatcher;
|
||||
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Endpoint;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.ReadOperation;
|
||||
import org.springframework.boot.actuate.endpoint.annotation.Selector;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* {@link Endpoint} to expose Quartz Scheduler info.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Endpoint(id = "quartz")
|
||||
public class QuartzEndpoint {
|
||||
|
||||
private final Scheduler scheduler;
|
||||
|
||||
public QuartzEndpoint(Scheduler scheduler) {
|
||||
Assert.notNull(scheduler, "Scheduler must not be null");
|
||||
this.scheduler = scheduler;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public Map<String, Object> quartzReport() {
|
||||
Map<String, Object> result = new LinkedHashMap<>();
|
||||
try {
|
||||
for (String groupName : this.scheduler.getJobGroupNames()) {
|
||||
List<String> jobs = this.scheduler.getJobKeys(GroupMatcher.jobGroupEquals(groupName)).stream()
|
||||
.map(JobKey::getName).collect(Collectors.toList());
|
||||
result.put(groupName, jobs);
|
||||
}
|
||||
}
|
||||
catch (SchedulerException ignored) {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ReadOperation
|
||||
public QuartzJob quartzJob(@Selector String groupName, @Selector String jobName) {
|
||||
try {
|
||||
JobKey jobKey = JobKey.jobKey(jobName, groupName);
|
||||
JobDetail jobDetail = this.scheduler.getJobDetail(jobKey);
|
||||
List<? extends Trigger> triggers = this.scheduler.getTriggersOfJob(jobKey);
|
||||
return new QuartzJob(jobDetail, triggers);
|
||||
}
|
||||
catch (SchedulerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Details of a {@link Job Quartz Job}.
|
||||
*/
|
||||
public static final class QuartzJob {
|
||||
|
||||
private final String jobGroup;
|
||||
|
||||
private final String jobName;
|
||||
|
||||
private final String description;
|
||||
|
||||
private final String className;
|
||||
|
||||
private final List<QuartzTrigger> triggers = new ArrayList<>();
|
||||
|
||||
QuartzJob(JobDetail jobDetail, List<? extends Trigger> triggers) {
|
||||
this.jobGroup = jobDetail.getKey().getGroup();
|
||||
this.jobName = jobDetail.getKey().getName();
|
||||
this.description = jobDetail.getDescription();
|
||||
this.className = jobDetail.getJobClass().getName();
|
||||
triggers.forEach(trigger -> this.triggers.add(new QuartzTrigger(trigger)));
|
||||
}
|
||||
|
||||
public String getJobGroup() {
|
||||
return this.jobGroup;
|
||||
}
|
||||
|
||||
public String getJobName() {
|
||||
return this.jobName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public String getClassName() {
|
||||
return this.className;
|
||||
}
|
||||
|
||||
public List<QuartzTrigger> getTriggers() {
|
||||
return this.triggers;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Details of a {@link Trigger Quartz Trigger}.
|
||||
*/
|
||||
public static final class QuartzTrigger {
|
||||
|
||||
private final String triggerGroup;
|
||||
|
||||
private final String triggerName;
|
||||
|
||||
private final String description;
|
||||
|
||||
private final String calendarName;
|
||||
|
||||
private final Date startTime;
|
||||
|
||||
private final Date endTime;
|
||||
|
||||
private final Date previousFireTime;
|
||||
|
||||
private final Date nextFireTime;
|
||||
|
||||
private final Date finalFireTime;
|
||||
|
||||
QuartzTrigger(Trigger trigger) {
|
||||
this.triggerGroup = trigger.getKey().getGroup();
|
||||
this.triggerName = trigger.getKey().getName();
|
||||
this.description = trigger.getDescription();
|
||||
this.calendarName = trigger.getCalendarName();
|
||||
this.startTime = trigger.getStartTime();
|
||||
this.endTime = trigger.getEndTime();
|
||||
this.previousFireTime = trigger.getPreviousFireTime();
|
||||
this.nextFireTime = trigger.getNextFireTime();
|
||||
this.finalFireTime = trigger.getFinalFireTime();
|
||||
}
|
||||
|
||||
public String getTriggerGroup() {
|
||||
return this.triggerGroup;
|
||||
}
|
||||
|
||||
public String getTriggerName() {
|
||||
return this.triggerName;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public String getCalendarName() {
|
||||
return this.calendarName;
|
||||
}
|
||||
|
||||
public Date getStartTime() {
|
||||
return this.startTime;
|
||||
}
|
||||
|
||||
public Date getEndTime() {
|
||||
return this.endTime;
|
||||
}
|
||||
|
||||
public Date getPreviousFireTime() {
|
||||
return this.previousFireTime;
|
||||
}
|
||||
|
||||
public Date getNextFireTime() {
|
||||
return this.nextFireTime;
|
||||
}
|
||||
|
||||
public Date getFinalFireTime() {
|
||||
return this.finalFireTime;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Actuator support for Quartz Scheduler.
|
||||
*/
|
||||
package org.springframework.boot.actuate.quartz;
|
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright 2012-2017 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.actuate.quartz;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobBuilder;
|
||||
import org.quartz.JobDetail;
|
||||
import org.quartz.JobKey;
|
||||
import org.quartz.Scheduler;
|
||||
import org.quartz.Trigger;
|
||||
import org.quartz.TriggerBuilder;
|
||||
import org.quartz.impl.matchers.GroupMatcher;
|
||||
|
||||
import org.springframework.boot.actuate.quartz.QuartzEndpoint.QuartzJob;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link QuartzEndpoint}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class QuartzEndpointTests {
|
||||
|
||||
private final Scheduler scheduler = mock(Scheduler.class);
|
||||
|
||||
private final QuartzEndpoint endpoint = new QuartzEndpoint(this.scheduler);
|
||||
|
||||
private final JobDetail jobDetail = JobBuilder.newJob(Job.class).withIdentity("testJob").build();
|
||||
|
||||
private final Trigger trigger = TriggerBuilder.newTrigger().forJob(this.jobDetail).withIdentity("testTrigger")
|
||||
.build();
|
||||
|
||||
@Test
|
||||
public void quartzReport() throws Exception {
|
||||
String jobGroup = this.jobDetail.getKey().getGroup();
|
||||
given(this.scheduler.getJobGroupNames()).willReturn(Collections.singletonList(jobGroup));
|
||||
given(this.scheduler.getJobKeys(GroupMatcher.jobGroupEquals(jobGroup)))
|
||||
.willReturn(Collections.singleton(this.jobDetail.getKey()));
|
||||
Map<String, Object> quartzReport = this.endpoint.quartzReport();
|
||||
assertThat(quartzReport).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void quartzJob() throws Exception {
|
||||
JobKey jobKey = this.jobDetail.getKey();
|
||||
given(this.scheduler.getJobDetail(jobKey)).willReturn(this.jobDetail);
|
||||
given(this.scheduler.getTriggersOfJob(jobKey))
|
||||
.willAnswer(invocation -> Collections.singletonList(this.trigger));
|
||||
QuartzJob quartzJob = this.endpoint.quartzJob(jobKey.getGroup(), jobKey.getName());
|
||||
assertThat(quartzJob.getJobGroup()).isEqualTo(jobKey.getGroup());
|
||||
assertThat(quartzJob.getJobName()).isEqualTo(jobKey.getName());
|
||||
assertThat(quartzJob.getClassName()).isEqualTo(this.jobDetail.getJobClass().getName());
|
||||
assertThat(quartzJob.getTriggers()).hasSize(1);
|
||||
assertThat(quartzJob.getTriggers().get(0).getTriggerGroup()).isEqualTo(this.trigger.getKey().getGroup());
|
||||
assertThat(quartzJob.getTriggers().get(0).getTriggerName()).isEqualTo(this.trigger.getKey().getName());
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user