-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add demo of job scheduling using quartz
The GreetingController is extended, so it now allows a POST which schedules a job to run at a set frequency. The job just logs the Greeting to the console Quartz is a framework which allows Jobs to be scheduled to run asynchronously, at a fixed frequency or point in time. This is useful if you want to allow the API user to schedule a task to be performed at a set point in the future The job schedule is persisted in a postgres database, so they will live beyond the lifespan of an application run. I.e. the application can be restarted, and the running jobs will restart. The database schema is created using Flyway Jira: n/a
- Loading branch information
Robin Wilkins
committed
Oct 21, 2020
1 parent
08c2b1b
commit f88bc8a
Showing
7 changed files
with
338 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
79 changes: 64 additions & 15 deletions
79
src/main/java/com/wilkins/showcase/controllers/GreetingController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,82 @@ | ||
package com.wilkins.showcase.controllers; | ||
|
||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.springframework.web.bind.annotation.GetMapping; | ||
import org.springframework.web.bind.annotation.RequestParam; | ||
import org.springframework.web.bind.annotation.RestController; | ||
import org.quartz.*; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.*; | ||
|
||
import static org.springframework.util.StringUtils.isEmpty; | ||
import java.sql.Timestamp; | ||
import java.time.LocalDateTime; | ||
import java.time.ZoneId; | ||
import java.util.Date; | ||
import java.util.UUID; | ||
|
||
import static org.quartz.TriggerBuilder.newTrigger; | ||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE; | ||
import static org.springframework.http.ResponseEntity.noContent; | ||
import static org.springframework.http.ResponseEntity.notFound; | ||
|
||
@Slf4j | ||
@RestController | ||
@RequestMapping(path = "/greeting", produces = APPLICATION_JSON_VALUE) | ||
@RequiredArgsConstructor | ||
public class GreetingController { | ||
|
||
@GetMapping("/greeting") | ||
public Greeting getGreeting(@RequestParam(name = "salutation", required = false) String salutationParam, | ||
@RequestParam(name = "name", required = false) String nameParam) { | ||
private static final String JOB_GROUP = "greeting-jobs"; | ||
private final Scheduler scheduler; | ||
|
||
log.info("A greeting was requested"); | ||
@GetMapping | ||
public Greeting getGreeting(@RequestParam(name = "salutation", required = false, defaultValue = "hello") String salutationParam, | ||
@RequestParam(name = "name", required = false, defaultValue = "world") String nameParam) { | ||
|
||
Greeting greeting = Greeting.of("hello", "world"); | ||
log.info("A greeting was requested"); | ||
|
||
if (!isEmpty(salutationParam)) { | ||
greeting = greeting.withSalutation(salutationParam); | ||
} | ||
if (!isEmpty(nameParam)) { | ||
greeting = greeting.withName(nameParam); | ||
} | ||
var greeting = Greeting.of(salutationParam, nameParam); | ||
|
||
log.info("Greeting returned: {}", greeting); | ||
|
||
return greeting; | ||
} | ||
|
||
@PostMapping | ||
public String postGreeting(@RequestParam(name = "salutation", required = false, defaultValue = "hello") String salutationParam, | ||
@RequestParam(name = "name", required = false, defaultValue = "world") String nameParam, | ||
@RequestParam(name = "durationMins", required = false, defaultValue = "2") String durationMins) throws SchedulerException { | ||
var jobDataMap = new JobDataMap(); | ||
jobDataMap.put("salutation", salutationParam); | ||
jobDataMap.put("name", nameParam); | ||
jobDataMap.put("greeting", Greeting.of(salutationParam, nameParam)); | ||
var id = UUID.randomUUID().toString(); | ||
var jobDetail = JobBuilder.newJob() | ||
.ofType(GreetingJob.class) | ||
.withIdentity(id, JOB_GROUP) | ||
.withDescription("Send Greeting Job") | ||
.usingJobData(jobDataMap) | ||
.requestRecovery() | ||
// .storeDurably() | ||
.build(); | ||
Date now = new Date(); | ||
Date startAt = Timestamp.valueOf(LocalDateTime.from( | ||
now.toInstant() | ||
.atZone(ZoneId.systemDefault()) | ||
.toLocalDateTime()) | ||
.plusMinutes(1)); | ||
var trigger = newTrigger() | ||
.forJob(jobDetail) | ||
.withIdentity(jobDetail.getKey().getName(), "greeting-triggers") | ||
.withDescription("Send Greeting Trigger") | ||
.startAt(startAt) | ||
.withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0)) | ||
.build(); | ||
log.info("scheduling job"); | ||
scheduler.scheduleJob(jobDetail, trigger); | ||
return id; | ||
} | ||
|
||
@DeleteMapping("/{id}") | ||
public ResponseEntity<?> deleteGreeting(@PathVariable String id) throws SchedulerException { | ||
log.info("deleting job: {}", id); | ||
return scheduler.deleteJob(new JobKey(id, JOB_GROUP)) ? noContent().build() : notFound().build(); | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/main/java/com/wilkins/showcase/controllers/GreetingJob.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.wilkins.showcase.controllers; | ||
|
||
import com.wilkins.showcase.services.Greeter; | ||
import lombok.RequiredArgsConstructor; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.quartz.Job; | ||
import org.quartz.JobDataMap; | ||
import org.quartz.JobExecutionContext; | ||
|
||
@Slf4j | ||
@RequiredArgsConstructor | ||
public class GreetingJob implements Job { | ||
|
||
private final Greeter greeter; | ||
|
||
@Override | ||
public void execute(JobExecutionContext context) { | ||
JobDataMap jobDataMap = context.getMergedJobDataMap(); | ||
log.info("******** {}, {} *************", context.getJobDetail().getKey().getName(), | ||
greeter.greet((Greeting) jobDataMap.get("greeting"))); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
package com.wilkins.showcase.services; | ||
|
||
import com.wilkins.showcase.controllers.Greeting; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class Greeter { | ||
|
||
public String greet(Greeting greeting) { | ||
return greeting.getSalutation() + " " + greeting.getName(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
spring: | ||
quartz: | ||
job-store-type: jdbc | ||
properties.org.quartz.threadPool.threadCount: 5 | ||
properties: | ||
org: | ||
quartz: | ||
jobStore: | ||
driverDelegateClass: "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate" | ||
wait-for-jobs-to-complete-on-shutdown: true | ||
jdbc: | ||
initialize-schema: never | ||
|
||
datasource: | ||
url: "jdbc:postgresql://localhost:5432/postgres?currentSchema=showcase" | ||
username: "postgres" | ||
password: "Passw0rd" |
Oops, something went wrong.