mirror of
https://github.com/fabioformosa/quartz-manager.git
synced 2026-05-14 22:00:30 +09:00
#56 added the simpleTrigger to the API
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package it.fabioformosa.quartzmanager.aspects;
|
package it.fabioformosa.quartzmanager.aspects;
|
||||||
|
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -11,6 +12,6 @@ import org.quartz.SchedulerException;
|
|||||||
*/
|
*/
|
||||||
public interface ProgressNotifier {
|
public interface ProgressNotifier {
|
||||||
|
|
||||||
void send() throws SchedulerException;
|
void send(JobExecutionContext jobExecutionContext) throws SchedulerException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,17 +1,11 @@
|
|||||||
package it.fabioformosa.quartzmanager.aspects;
|
package it.fabioformosa.quartzmanager.aspects;
|
||||||
|
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerStatus;
|
import it.fabioformosa.quartzmanager.dto.TriggerStatus;
|
||||||
import it.fabioformosa.quartzmanager.services.SchedulerService;
|
import org.quartz.*;
|
||||||
import org.quartz.DailyTimeIntervalTrigger;
|
|
||||||
import org.quartz.SchedulerException;
|
|
||||||
import org.quartz.SimpleTrigger;
|
|
||||||
import org.quartz.Trigger;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* Notify the progress of the trigger through websocket
|
* Notify the progress of the trigger through websocket
|
||||||
@@ -29,8 +23,8 @@ public class WebSocketProgressNotifier implements ProgressNotifier {
|
|||||||
// @Resource
|
// @Resource
|
||||||
// private Scheduler scheduler;
|
// private Scheduler scheduler;
|
||||||
|
|
||||||
@Resource
|
// @Resource
|
||||||
private SchedulerService schedulerService;
|
// private LegacySchedulerService schedulerService;
|
||||||
|
|
||||||
// @Resource
|
// @Resource
|
||||||
// private TriggerMonitor triggerMonitor;
|
// private TriggerMonitor triggerMonitor;
|
||||||
@@ -42,34 +36,26 @@ public class WebSocketProgressNotifier implements ProgressNotifier {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void send() throws SchedulerException {
|
public void send(JobExecutionContext jobExecutionContext) throws SchedulerException {
|
||||||
TriggerStatus currTriggerStatus = new TriggerStatus();
|
TriggerStatus currTriggerStatus = new TriggerStatus();
|
||||||
|
|
||||||
Trigger trigger = schedulerService.getOneSimpleTrigger().get();
|
Trigger trigger = jobExecutionContext.getTrigger();
|
||||||
currTriggerStatus.setFinalFireTime(trigger.getFinalFireTime());
|
currTriggerStatus.setFinalFireTime(trigger.getFinalFireTime());
|
||||||
currTriggerStatus.setNextFireTime(trigger.getNextFireTime());
|
currTriggerStatus.setNextFireTime(trigger.getNextFireTime());
|
||||||
currTriggerStatus.setPreviousFireTime(trigger.getPreviousFireTime());
|
currTriggerStatus.setPreviousFireTime(trigger.getPreviousFireTime());
|
||||||
|
|
||||||
int timesTriggered = 0;
|
|
||||||
int repeatCount = 0;
|
|
||||||
|
|
||||||
if (trigger instanceof SimpleTrigger) {
|
if (trigger instanceof SimpleTrigger) {
|
||||||
SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
|
SimpleTrigger simpleTrigger = (SimpleTrigger) trigger;
|
||||||
timesTriggered = simpleTrigger.getTimesTriggered();
|
currTriggerStatus.setRepeatCount(simpleTrigger.getRepeatCount() + 1);
|
||||||
repeatCount = simpleTrigger.getRepeatCount();
|
currTriggerStatus.setTimesTriggered(simpleTrigger.getTimesTriggered());
|
||||||
} else if (trigger instanceof DailyTimeIntervalTrigger) {
|
} else if (trigger instanceof DailyTimeIntervalTrigger) {
|
||||||
DailyTimeIntervalTrigger dailyTrigger = (DailyTimeIntervalTrigger) trigger;
|
DailyTimeIntervalTrigger dailyTrigger = (DailyTimeIntervalTrigger) trigger;
|
||||||
timesTriggered = dailyTrigger.getTimesTriggered();
|
currTriggerStatus.setRepeatCount(dailyTrigger.getRepeatCount() + 1);
|
||||||
repeatCount = dailyTrigger.getRepeatCount();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Trigger jobTrigger = schedulerService.getOneSimpleTrigger().get();
|
JobDetail jobDetail = jobExecutionContext.getJobDetail();
|
||||||
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
|
currTriggerStatus.setJobKey(jobDetail.getKey().getName());
|
||||||
currTriggerStatus.setJobKey(jobTrigger.getJobKey().getName());
|
currTriggerStatus.setJobClass(trigger.getClass().getSimpleName());
|
||||||
currTriggerStatus.setJobClass(jobTrigger.getClass().getSimpleName());
|
|
||||||
currTriggerStatus.setTimesTriggered(timesTriggered);
|
|
||||||
currTriggerStatus.setRepeatCount(repeatCount + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
messagingTemplate.convertAndSend("/topic/progress", currTriggerStatus);
|
messagingTemplate.convertAndSend("/topic/progress", currTriggerStatus);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.controllers;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
||||||
|
public class AbstractTriggerController {
|
||||||
|
|
||||||
|
@Value("${quartz-manager.jobClass}")
|
||||||
|
protected String jobClassname;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@ import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
|||||||
import it.fabioformosa.quartzmanager.dto.SchedulerDTO;
|
import it.fabioformosa.quartzmanager.dto.SchedulerDTO;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerStatus;
|
import it.fabioformosa.quartzmanager.dto.TriggerStatus;
|
||||||
import it.fabioformosa.quartzmanager.enums.SchedulerStates;
|
import it.fabioformosa.quartzmanager.enums.SchedulerStates;
|
||||||
import it.fabioformosa.quartzmanager.services.SchedulerService;
|
import it.fabioformosa.quartzmanager.services.LegacySchedulerService;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
import org.quartz.SimpleTrigger;
|
import org.quartz.SimpleTrigger;
|
||||||
import org.quartz.impl.triggers.SimpleTriggerImpl;
|
import org.quartz.impl.triggers.SimpleTriggerImpl;
|
||||||
@@ -40,10 +40,10 @@ public class SchedulerController {
|
|||||||
|
|
||||||
private final Logger log = LoggerFactory.getLogger(SchedulerController.class);
|
private final Logger log = LoggerFactory.getLogger(SchedulerController.class);
|
||||||
|
|
||||||
private SchedulerService schedulerService;
|
private LegacySchedulerService legacySchedulerService;
|
||||||
|
|
||||||
public SchedulerController(SchedulerService schedulerService, ConversionService conversionService) {
|
public SchedulerController(LegacySchedulerService legacySchedulerService, ConversionService conversionService) {
|
||||||
this.schedulerService = schedulerService;
|
this.legacySchedulerService = legacySchedulerService;
|
||||||
this.conversionService = conversionService;
|
this.conversionService = conversionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ public class SchedulerController {
|
|||||||
})
|
})
|
||||||
public SchedulerConfigParam getConfig() throws SchedulerException {
|
public SchedulerConfigParam getConfig() throws SchedulerException {
|
||||||
log.debug("SCHEDULER - GET CONFIG params");
|
log.debug("SCHEDULER - GET CONFIG params");
|
||||||
SchedulerConfigParam schedulerConfigParam = schedulerService.getOneSimpleTrigger()
|
SchedulerConfigParam schedulerConfigParam = legacySchedulerService.getOneSimpleTrigger()
|
||||||
.map(SchedulerController::fromSimpleTriggerToSchedulerConfigParam)
|
.map(SchedulerController::fromSimpleTriggerToSchedulerConfigParam)
|
||||||
.orElse(new SchedulerConfigParam(0L, 0, 0));
|
.orElse(new SchedulerConfigParam(0L, 0, 0));
|
||||||
return schedulerConfigParam;
|
return schedulerConfigParam;
|
||||||
@@ -69,7 +69,7 @@ public class SchedulerController {
|
|||||||
public static SchedulerConfigParam fromSimpleTriggerToSchedulerConfigParam(SimpleTrigger simpleTrigger){
|
public static SchedulerConfigParam fromSimpleTriggerToSchedulerConfigParam(SimpleTrigger simpleTrigger){
|
||||||
int timesTriggered = simpleTrigger.getTimesTriggered();
|
int timesTriggered = simpleTrigger.getTimesTriggered();
|
||||||
int maxCount = simpleTrigger.getRepeatCount() + 1;
|
int maxCount = simpleTrigger.getRepeatCount() + 1;
|
||||||
long triggersPerDay = SchedulerService.fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval());
|
long triggersPerDay = LegacySchedulerService.fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval());
|
||||||
return new SchedulerConfigParam(triggersPerDay, maxCount, timesTriggered);
|
return new SchedulerConfigParam(triggersPerDay, maxCount, timesTriggered);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ public class SchedulerController {
|
|||||||
})
|
})
|
||||||
public SchedulerDTO getScheduler() {
|
public SchedulerDTO getScheduler() {
|
||||||
log.debug("SCHEDULER - GET Scheduler...");
|
log.debug("SCHEDULER - GET Scheduler...");
|
||||||
SchedulerDTO schedulerDTO = conversionService.convert(schedulerService.getScheduler(), SchedulerDTO.class);
|
SchedulerDTO schedulerDTO = conversionService.convert(legacySchedulerService.getScheduler(), SchedulerDTO.class);
|
||||||
return schedulerDTO;
|
return schedulerDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ public class SchedulerController {
|
|||||||
log.trace("SCHEDULER - GET PROGRESS INFO");
|
log.trace("SCHEDULER - GET PROGRESS INFO");
|
||||||
TriggerStatus progress = new TriggerStatus();
|
TriggerStatus progress = new TriggerStatus();
|
||||||
|
|
||||||
SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) schedulerService.getOneSimpleTrigger().get();
|
SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) legacySchedulerService.getOneSimpleTrigger().get();
|
||||||
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
|
if (jobTrigger != null && jobTrigger.getJobKey() != null) {
|
||||||
progress.setJobKey(jobTrigger.getJobKey().getName());
|
progress.setJobKey(jobTrigger.getJobKey().getName());
|
||||||
progress.setJobClass(jobTrigger.getClass().getSimpleName());
|
progress.setJobClass(jobTrigger.getClass().getSimpleName());
|
||||||
@@ -122,9 +122,9 @@ public class SchedulerController {
|
|||||||
public Map<String, String> getStatus() throws SchedulerException {
|
public Map<String, String> getStatus() throws SchedulerException {
|
||||||
log.trace("SCHEDULER - GET STATUS");
|
log.trace("SCHEDULER - GET STATUS");
|
||||||
String schedulerState = "";
|
String schedulerState = "";
|
||||||
if (schedulerService.getScheduler().isShutdown() || !schedulerService.getScheduler().isStarted())
|
if (legacySchedulerService.getScheduler().isShutdown() || !legacySchedulerService.getScheduler().isStarted())
|
||||||
schedulerState = SchedulerStates.STOPPED.toString();
|
schedulerState = SchedulerStates.STOPPED.toString();
|
||||||
else if (schedulerService.getScheduler().isStarted() && schedulerService.getScheduler().isInStandbyMode())
|
else if (legacySchedulerService.getScheduler().isStarted() && legacySchedulerService.getScheduler().isInStandbyMode())
|
||||||
schedulerState = SchedulerStates.PAUSED.toString();
|
schedulerState = SchedulerStates.PAUSED.toString();
|
||||||
else
|
else
|
||||||
schedulerState = SchedulerStates.RUNNING.toString();
|
schedulerState = SchedulerStates.RUNNING.toString();
|
||||||
@@ -139,7 +139,7 @@ public class SchedulerController {
|
|||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void pause() throws SchedulerException {
|
public void pause() throws SchedulerException {
|
||||||
log.info("SCHEDULER - PAUSE COMMAND");
|
log.info("SCHEDULER - PAUSE COMMAND");
|
||||||
schedulerService.getScheduler().standby();
|
legacySchedulerService.getScheduler().standby();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/resume")
|
@GetMapping("/resume")
|
||||||
@@ -150,7 +150,7 @@ public class SchedulerController {
|
|||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void resume() throws SchedulerException {
|
public void resume() throws SchedulerException {
|
||||||
log.info("SCHEDULER - RESUME COMMAND");
|
log.info("SCHEDULER - RESUME COMMAND");
|
||||||
schedulerService.getScheduler().start();
|
legacySchedulerService.getScheduler().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/run")
|
@GetMapping("/run")
|
||||||
@@ -161,7 +161,7 @@ public class SchedulerController {
|
|||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void run() throws SchedulerException {
|
public void run() throws SchedulerException {
|
||||||
log.info("SCHEDULER - START COMMAND");
|
log.info("SCHEDULER - START COMMAND");
|
||||||
schedulerService.getScheduler().start();
|
legacySchedulerService.getScheduler().start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/stop")
|
@GetMapping("/stop")
|
||||||
@@ -172,7 +172,7 @@ public class SchedulerController {
|
|||||||
@ResponseStatus(HttpStatus.NO_CONTENT)
|
@ResponseStatus(HttpStatus.NO_CONTENT)
|
||||||
public void stop() throws SchedulerException {
|
public void stop() throws SchedulerException {
|
||||||
log.info("SCHEDULER - STOP COMMAND");
|
log.info("SCHEDULER - STOP COMMAND");
|
||||||
schedulerService.getScheduler().shutdown(true);
|
legacySchedulerService.getScheduler().shutdown(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,91 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.controllers;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Content;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
||||||
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerCommandDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerInputDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import it.fabioformosa.quartzmanager.services.SimpleTriggerSchedulerService;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.quartz.SchedulerException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RequestMapping(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL)
|
||||||
|
@SecurityRequirement(name = "basic-auth")
|
||||||
|
@RestController
|
||||||
|
public class SimpleTriggerController extends AbstractTriggerController {
|
||||||
|
|
||||||
|
static public final String SIMPLE_TRIGGER_CONTROLLER_BASE_URL = "/quartz-manager/simple-triggers";
|
||||||
|
|
||||||
|
private SimpleTriggerSchedulerService simpleSchedulerService;
|
||||||
|
|
||||||
|
public SimpleTriggerController(SimpleTriggerSchedulerService simpleSchedulerService) {
|
||||||
|
this.simpleSchedulerService = simpleSchedulerService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{name}")
|
||||||
|
@Operation(summary = "Get a simple trigger by name")
|
||||||
|
@ApiResponses(value = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Got the trigger by its name",
|
||||||
|
content = { @Content(mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = SimpleTriggerDTO.class)) }),
|
||||||
|
@ApiResponse(responseCode = "404", description = "Trigger not found",
|
||||||
|
content = @Content)
|
||||||
|
})
|
||||||
|
public SimpleTriggerDTO getSimpleTrigger(@PathVariable String name) throws SchedulerException, TriggerNotFoundException {
|
||||||
|
return simpleSchedulerService.getSimpleTriggerByName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/{name}")
|
||||||
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
|
@Operation(summary = "Create a new simple trigger")
|
||||||
|
@ApiResponses(value = {
|
||||||
|
@ApiResponse(responseCode = "201", description = "Created a new simple trigger",
|
||||||
|
content = { @Content(mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = TriggerDTO.class)) }),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Invalid config supplied",
|
||||||
|
content = @Content)
|
||||||
|
})
|
||||||
|
public SimpleTriggerDTO postSimpleTrigger(@PathVariable String name, @Valid @RequestBody SimpleTriggerInputDTO simpleTriggerInputDTO) throws SchedulerException, ClassNotFoundException {
|
||||||
|
log.info("SIMPLE TRIGGER - CREATING a SimpleTrigger {} {}", name, simpleTriggerInputDTO);
|
||||||
|
SimpleTriggerCommandDTO simpleTriggerCommandDTO = SimpleTriggerCommandDTO.builder()
|
||||||
|
.triggerName(name)
|
||||||
|
.simpleTriggerInputDTO(simpleTriggerInputDTO)
|
||||||
|
.build();
|
||||||
|
SimpleTriggerDTO newTriggerDTO = simpleSchedulerService.scheduleSimpleTrigger(jobClassname, simpleTriggerCommandDTO);
|
||||||
|
log.info("SIMPLE TRIGGER - CREATED a SimpleTrigger {}", newTriggerDTO);
|
||||||
|
return newTriggerDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/{name}")
|
||||||
|
@Operation(summary = "Reschedule a simple trigger")
|
||||||
|
@ApiResponses(value = {
|
||||||
|
@ApiResponse(responseCode = "200", description = "Rescheduled a simple trigger",
|
||||||
|
content = { @Content(mediaType = "application/json",
|
||||||
|
schema = @Schema(implementation = TriggerDTO.class)) }),
|
||||||
|
@ApiResponse(responseCode = "400", description = "Invalid config supplied",
|
||||||
|
content = @Content)
|
||||||
|
})
|
||||||
|
public TriggerDTO rescheduleSimpleTrigger(@PathVariable String name, @Valid @RequestBody SimpleTriggerInputDTO simpleTriggerInputDTO) throws SchedulerException {
|
||||||
|
log.info("SIMPLE TRIGGER - RESCHEDULING the trigger {} {}", name, simpleTriggerInputDTO);
|
||||||
|
SimpleTriggerCommandDTO simpleTriggerCommandDTO = SimpleTriggerCommandDTO.builder()
|
||||||
|
.triggerName(name)
|
||||||
|
.simpleTriggerInputDTO(simpleTriggerInputDTO)
|
||||||
|
.build();
|
||||||
|
TriggerDTO triggerDTO = simpleSchedulerService.rescheduleSimpleTrigger(simpleTriggerCommandDTO);
|
||||||
|
log.info("SIMPLE TRIGGER - RESCHEDULED the trigger {}", triggerDTO);
|
||||||
|
return triggerDTO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,10 +8,10 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
|
|||||||
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
|
||||||
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
||||||
import it.fabioformosa.quartzmanager.services.SchedulerService;
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import it.fabioformosa.quartzmanager.services.LegacySchedulerService;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
@@ -21,24 +21,23 @@ import javax.validation.Valid;
|
|||||||
@RequestMapping(TriggerController.TRIGGER_CONTROLLER_BASE_URL)
|
@RequestMapping(TriggerController.TRIGGER_CONTROLLER_BASE_URL)
|
||||||
@SecurityRequirement(name = "basic-auth")
|
@SecurityRequirement(name = "basic-auth")
|
||||||
@RestController
|
@RestController
|
||||||
public class TriggerController {
|
public class TriggerController extends AbstractTriggerController {
|
||||||
|
|
||||||
static public final String TRIGGER_CONTROLLER_BASE_URL = "/quartz-manager/triggers";
|
static public final String TRIGGER_CONTROLLER_BASE_URL = "/quartz-manager/triggers";
|
||||||
|
static public final String SIMPLE_TRIGGER_BASE_URL = "/simple-triggers";
|
||||||
|
|
||||||
@Value("${quartz-manager.jobClass}")
|
private LegacySchedulerService schedulerService;
|
||||||
private String jobClassname;
|
|
||||||
|
|
||||||
private SchedulerService schedulerService;
|
public TriggerController(LegacySchedulerService schedulerService) {
|
||||||
|
|
||||||
public TriggerController(SchedulerService schedulerService) {
|
|
||||||
this.schedulerService = schedulerService;
|
this.schedulerService = schedulerService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/{name}")
|
@GetMapping("/{name}")
|
||||||
public TriggerDTO getTrigger(@PathVariable String name) throws SchedulerException {
|
public TriggerDTO getTrigger(@PathVariable String name) throws SchedulerException, TriggerNotFoundException {
|
||||||
return schedulerService.getTriggerByName(name);
|
return schedulerService.getLegacyTriggerByName(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
@PostMapping("/{name}")
|
@PostMapping("/{name}")
|
||||||
@ResponseStatus(HttpStatus.CREATED)
|
@ResponseStatus(HttpStatus.CREATED)
|
||||||
@Operation(summary = "Create a new trigger")
|
@Operation(summary = "Create a new trigger")
|
||||||
@@ -56,6 +55,8 @@ public class TriggerController {
|
|||||||
return newTriggerDTO;
|
return newTriggerDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@PutMapping("/{name}")
|
@PutMapping("/{name}")
|
||||||
@Operation(summary = "Reschedule the trigger")
|
@Operation(summary = "Reschedule the trigger")
|
||||||
@ApiResponses(value = {
|
@ApiResponses(value = {
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.controllers.advices;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.ExceptionResponse;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.ResourceConflictException;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import org.springframework.http.HttpStatus;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
|
||||||
|
@ControllerAdvice
|
||||||
|
public class ExceptionHandlingController {
|
||||||
|
|
||||||
|
@ExceptionHandler(ResourceConflictException.class)
|
||||||
|
public ResponseEntity<ExceptionResponse> resourceConflict(ResourceConflictException ex) {
|
||||||
|
ExceptionResponse response = new ExceptionResponse();
|
||||||
|
response.setErrorCode("Conflict");
|
||||||
|
response.setErrorMessage(ex.getMessage());
|
||||||
|
return new ResponseEntity<ExceptionResponse>(response, HttpStatus.CONFLICT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ExceptionHandler(TriggerNotFoundException.class)
|
||||||
|
@ResponseStatus(HttpStatus.NOT_FOUND)
|
||||||
|
@ResponseBody
|
||||||
|
public ExceptionResponse triggerNotFound(TriggerNotFoundException ex){
|
||||||
|
return ExceptionResponse.builder().errorCode(HttpStatus.NOT_FOUND.toString()).errorMessage(ex.getMessage()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.converters;
|
||||||
|
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerCommandDTO;
|
||||||
|
import org.quartz.SimpleScheduleBuilder;
|
||||||
|
import org.quartz.SimpleTrigger;
|
||||||
|
import org.quartz.Trigger;
|
||||||
|
import org.quartz.TriggerBuilder;
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SimpleTriggerCommandDTOToSimpleTrigger implements Converter<SimpleTriggerCommandDTO, SimpleTrigger> {
|
||||||
|
@Override
|
||||||
|
public SimpleTrigger convert(SimpleTriggerCommandDTO triggerCommandDTO) {
|
||||||
|
TriggerBuilder<Trigger> triggerTriggerBuilder = TriggerBuilder.newTrigger();
|
||||||
|
if(triggerCommandDTO.getSimpleTriggerInputDTO().getStartDate() != null)
|
||||||
|
triggerTriggerBuilder.startAt(triggerCommandDTO.getSimpleTriggerInputDTO().getStartDate());
|
||||||
|
if(triggerCommandDTO.getSimpleTriggerInputDTO().getEndDate() != null)
|
||||||
|
triggerTriggerBuilder.endAt(triggerCommandDTO.getSimpleTriggerInputDTO().getEndDate());
|
||||||
|
|
||||||
|
SimpleTrigger newSimpleTrigger = triggerTriggerBuilder.withSchedule(
|
||||||
|
SimpleScheduleBuilder.simpleSchedule()
|
||||||
|
.withIntervalInMilliseconds(triggerCommandDTO.getSimpleTriggerInputDTO().getRepeatInterval())
|
||||||
|
.withRepeatCount(triggerCommandDTO.getSimpleTriggerInputDTO().getRepeatCount())
|
||||||
|
.withMisfireHandlingInstructionNextWithRemainingCount()
|
||||||
|
)
|
||||||
|
.withIdentity(triggerCommandDTO.getTriggerName())
|
||||||
|
.build();
|
||||||
|
return newSimpleTrigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.converters;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerDTO;
|
||||||
|
import org.quartz.SimpleTrigger;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class SimpleTriggerToSimpleTriggerDTO extends TriggerToTriggerDTO<SimpleTrigger, SimpleTriggerDTO> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void convert(SimpleTrigger source, SimpleTriggerDTO target) {
|
||||||
|
super.convert(source, target);
|
||||||
|
target.setTimesTriggered(source.getTimesTriggered());
|
||||||
|
target.setRepeatCount(source.getRepeatCount());
|
||||||
|
target.setRepeatInterval(source.getRepeatInterval());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SimpleTriggerDTO createOrRetrieveTarget(SimpleTrigger source) {
|
||||||
|
return new SimpleTriggerDTO();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
package it.fabioformosa.quartzmanager.converters;
|
package it.fabioformosa.quartzmanager.converters;
|
||||||
|
|
||||||
import it.fabioformosa.metamorphosis.core.converters.AbstractBaseConverterToDTO;
|
import it.fabioformosa.metamorphosis.core.converters.AbstractBaseConverter;
|
||||||
import it.fabioformosa.quartzmanager.dto.JobKeyDTO;
|
import it.fabioformosa.quartzmanager.dto.JobKeyDTO;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO;
|
import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO;
|
||||||
@@ -10,10 +10,10 @@ import org.quartz.TriggerKey;
|
|||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class TriggerToTriggerDTO extends AbstractBaseConverterToDTO<Trigger, TriggerDTO> {
|
public class TriggerToTriggerDTO<S extends Trigger, T extends TriggerDTO> extends AbstractBaseConverter<S, T> {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void convert(Trigger source, TriggerDTO target) {
|
protected void convert(S source, T target) {
|
||||||
TriggerKey triggerKey = source.getKey();
|
TriggerKey triggerKey = source.getKey();
|
||||||
TriggerKeyDTO triggerKeyDTO = conversionService.convert(triggerKey, TriggerKeyDTO.class);
|
TriggerKeyDTO triggerKeyDTO = conversionService.convert(triggerKey, TriggerKeyDTO.class);
|
||||||
target.setTriggerKeyDTO(triggerKeyDTO);
|
target.setTriggerKeyDTO(triggerKeyDTO);
|
||||||
@@ -30,7 +30,11 @@ public class TriggerToTriggerDTO extends AbstractBaseConverterToDTO<Trigger, Tri
|
|||||||
JobKey jobKey = source.getJobKey();
|
JobKey jobKey = source.getJobKey();
|
||||||
JobKeyDTO jobKeyDTO = conversionService.convert(jobKey, JobKeyDTO.class);
|
JobKeyDTO jobKeyDTO = conversionService.convert(jobKey, JobKeyDTO.class);
|
||||||
target.setJobKeyDTO(jobKeyDTO);
|
target.setJobKeyDTO(jobKeyDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected T createOrRetrieveTarget(S source) {
|
||||||
|
return (T) new TriggerDTO();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.dto;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
@ToString
|
||||||
|
public class SimpleTriggerCommandDTO {
|
||||||
|
private String triggerName;
|
||||||
|
private SimpleTriggerInputDTO simpleTriggerInputDTO;
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.dto;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
@NoArgsConstructor @AllArgsConstructor
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true) @EqualsAndHashCode(callSuper = true)
|
||||||
|
@SuperBuilder
|
||||||
|
public class SimpleTriggerDTO extends TriggerDTO{
|
||||||
|
|
||||||
|
private int repeatCount;
|
||||||
|
private long repeatInterval;
|
||||||
|
private int timesTriggered;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.dto;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class SimpleTriggerInputDTO extends TriggerCommandDTO {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private Integer repeatCount;
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
Long repeatInterval;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.dto;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.*;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@SuperBuilder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@EqualsAndHashCode
|
||||||
|
@ToString
|
||||||
|
@Data
|
||||||
|
public class TriggerCommandDTO {
|
||||||
|
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||||
|
private Date startDate;
|
||||||
|
|
||||||
|
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
|
||||||
|
private Date endDate;
|
||||||
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package it.fabioformosa.quartzmanager.dto;
|
package it.fabioformosa.quartzmanager.dto;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Builder;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.NoArgsConstructor;
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.experimental.SuperBuilder;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@NoArgsConstructor
|
@NoArgsConstructor
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@SuperBuilder
|
||||||
public class TriggerDTO {
|
public class TriggerDTO {
|
||||||
private TriggerKeyDTO triggerKeyDTO;
|
private TriggerKeyDTO triggerKeyDTO;
|
||||||
private int priority;
|
private int priority;
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
package it.fabioformosa.quartzmanager.exceptions;
|
|
||||||
|
|
||||||
import org.springframework.http.HttpStatus;
|
|
||||||
import org.springframework.http.ResponseEntity;
|
|
||||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
|
||||||
|
|
||||||
@ControllerAdvice
|
|
||||||
public class ExceptionHandlingController {
|
|
||||||
|
|
||||||
@ExceptionHandler(ResourceConflictException.class)
|
|
||||||
public ResponseEntity<ExceptionResponse> resourceConflict(ResourceConflictException ex) {
|
|
||||||
ExceptionResponse response = new ExceptionResponse();
|
|
||||||
response.setErrorCode("Conflict");
|
|
||||||
response.setErrorMessage(ex.getMessage());
|
|
||||||
return new ResponseEntity<ExceptionResponse>(response, HttpStatus.CONFLICT);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,25 +1,15 @@
|
|||||||
package it.fabioformosa.quartzmanager.exceptions;
|
package it.fabioformosa.quartzmanager.exceptions;
|
||||||
|
|
||||||
public class ExceptionResponse {
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Builder
|
||||||
|
@Data
|
||||||
|
public class ExceptionResponse {
|
||||||
private String errorCode;
|
private String errorCode;
|
||||||
private String errorMessage;
|
private String errorMessage;
|
||||||
|
|
||||||
public ExceptionResponse() {}
|
|
||||||
|
|
||||||
public String getErrorCode() {
|
|
||||||
return errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrorCode(String errorCode) {
|
|
||||||
this.errorCode = errorCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getErrorMessage() {
|
|
||||||
return errorMessage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setErrorMessage(String errorMessage) {
|
|
||||||
this.errorMessage = errorMessage;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
package it.fabioformosa.quartzmanager.exceptions;
|
package it.fabioformosa.quartzmanager.exceptions;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter @Setter
|
||||||
public class ResourceConflictException extends RuntimeException {
|
public class ResourceConflictException extends RuntimeException {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1791564636123821405L;
|
private static final long serialVersionUID = 1791564636123821405L;
|
||||||
@@ -8,14 +12,7 @@ public class ResourceConflictException extends RuntimeException {
|
|||||||
|
|
||||||
public ResourceConflictException(Long resourceId, String message) {
|
public ResourceConflictException(Long resourceId, String message) {
|
||||||
super(message);
|
super(message);
|
||||||
setResourceId(resourceId);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getResourceId() {
|
|
||||||
return resourceId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setResourceId(Long resourceId) {
|
|
||||||
this.resourceId = resourceId;
|
this.resourceId = resourceId;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.exceptions;
|
||||||
|
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@ToString
|
||||||
|
@Getter
|
||||||
|
public class TriggerNotFoundException extends Exception {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
public TriggerNotFoundException(String name) {
|
||||||
|
super("Trigger with name " + name + " not found!");
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
package it.fabioformosa.quartzmanager.jobs;
|
package it.fabioformosa.quartzmanager.jobs;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import it.fabioformosa.quartzmanager.aspects.ProgressNotifier;
|
||||||
|
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
|
||||||
import org.quartz.Job;
|
import org.quartz.Job;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.quartz.SchedulerException;
|
import org.quartz.SchedulerException;
|
||||||
@@ -10,13 +10,12 @@ import org.slf4j.LoggerFactory;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
import org.springframework.messaging.simp.SimpMessageSendingOperations;
|
||||||
|
|
||||||
import it.fabioformosa.quartzmanager.aspects.ProgressNotifier;
|
import javax.annotation.Resource;
|
||||||
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends this class to create a job that produces LogRecord to be displayed
|
* Extends this class to create a job that produces LogRecord to be displayed
|
||||||
* into the GUI panel
|
* into the GUI panel
|
||||||
*
|
*
|
||||||
* @author Fabio.Formosa
|
* @author Fabio.Formosa
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
@@ -42,7 +41,7 @@ public abstract class AbstractLoggingJob implements Job {
|
|||||||
try {
|
try {
|
||||||
LogRecord logMsg = doIt(jobExecutionContext);
|
LogRecord logMsg = doIt(jobExecutionContext);
|
||||||
logAndSend(logMsg);
|
logAndSend(logMsg);
|
||||||
progressNotifier.send();
|
progressNotifier.send(jobExecutionContext);
|
||||||
} catch (SchedulerException e) {
|
} catch (SchedulerException e) {
|
||||||
log.error("Error updating progress " + e.getMessage());
|
log.error("Error updating progress " + e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -54,4 +53,4 @@ public abstract class AbstractLoggingJob implements Job {
|
|||||||
messagingTemplate.convertAndSend("/topic/logs", logRecord);
|
messagingTemplate.convertAndSend("/topic/logs", logRecord);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.services;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import org.quartz.Scheduler;
|
||||||
|
import org.quartz.SchedulerException;
|
||||||
|
import org.quartz.Trigger;
|
||||||
|
import org.quartz.TriggerKey;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
|
||||||
|
public class AbstractSchedulerService {
|
||||||
|
|
||||||
|
protected Scheduler scheduler;
|
||||||
|
protected ConversionService conversionService;
|
||||||
|
|
||||||
|
public AbstractSchedulerService(Scheduler scheduler, ConversionService conversionService) {
|
||||||
|
this.scheduler = scheduler;
|
||||||
|
this.conversionService = conversionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Trigger getTriggerByName(String name) throws SchedulerException, TriggerNotFoundException {
|
||||||
|
Trigger trigger = scheduler.getTrigger(new TriggerKey(name));
|
||||||
|
if(trigger == null)
|
||||||
|
throw new TriggerNotFoundException(name);
|
||||||
|
return trigger;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -3,6 +3,7 @@ package it.fabioformosa.quartzmanager.services;
|
|||||||
import it.fabioformosa.quartzmanager.common.utils.Try;
|
import it.fabioformosa.quartzmanager.common.utils.Try;
|
||||||
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
import org.quartz.*;
|
import org.quartz.*;
|
||||||
import org.quartz.impl.matchers.GroupMatcher;
|
import org.quartz.impl.matchers.GroupMatcher;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
@@ -10,26 +11,24 @@ import org.springframework.stereotype.Service;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
|
import static org.quartz.TriggerBuilder.newTrigger;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class SchedulerService {
|
public class LegacySchedulerService extends AbstractSchedulerService {
|
||||||
|
|
||||||
public static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24;
|
public static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24;
|
||||||
public static final int SEC_IN_A_DAY = 60 * 60 * 24;
|
public static final int SEC_IN_A_DAY = 60 * 60 * 24;
|
||||||
|
|
||||||
private Scheduler scheduler;
|
public LegacySchedulerService(Scheduler scheduler, ConversionService conversionService) {
|
||||||
private ConversionService conversionService;
|
super(scheduler, conversionService);
|
||||||
|
|
||||||
public SchedulerService(Scheduler scheduler, ConversionService conversionService) {
|
|
||||||
this.scheduler = scheduler;
|
|
||||||
this.conversionService = conversionService;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int fromTriggerPerDayToMillsInterval(long triggerPerDay) {
|
public static int fromTriggerPerDayToMillsInterval(long triggerPerDay) {
|
||||||
return (int) Math.ceil(Long.valueOf(SchedulerService.MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value
|
return (int) Math.ceil(Long.valueOf(LegacySchedulerService.MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int fromTriggerPerDayToSecInterval(long triggerPerDay) {
|
public static int fromTriggerPerDayToSecInterval(long triggerPerDay) {
|
||||||
return (int) Math.ceil(Long.valueOf(SchedulerService.SEC_IN_A_DAY) / triggerPerDay);
|
return (int) Math.ceil(Long.valueOf(LegacySchedulerService.SEC_IN_A_DAY) / triggerPerDay);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
|
public static long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) {
|
||||||
@@ -59,10 +58,12 @@ public class SchedulerService {
|
|||||||
.findFirst();
|
.findFirst();
|
||||||
}
|
}
|
||||||
|
|
||||||
public TriggerDTO getTriggerByName(String name) throws SchedulerException {
|
public TriggerDTO getLegacyTriggerByName(String name) throws SchedulerException, TriggerNotFoundException {
|
||||||
Trigger trigger = scheduler.getTrigger(new TriggerKey(name));
|
Trigger trigger = getTriggerByName(name);
|
||||||
return conversionService.convert(trigger, TriggerDTO.class);
|
return conversionService.convert(trigger, TriggerDTO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TriggerDTO scheduleNewTrigger(String name, String jobClassname, SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException {
|
public TriggerDTO scheduleNewTrigger(String name, String jobClassname, SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException {
|
||||||
Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobClassname);
|
Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobClassname);
|
||||||
@@ -71,9 +72,9 @@ public class SchedulerService {
|
|||||||
.storeDurably(false)
|
.storeDurably(false)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
|
int intervalInMills = LegacySchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
|
||||||
|
|
||||||
Trigger newTrigger = TriggerBuilder.newTrigger()
|
Trigger newTrigger = newTrigger()
|
||||||
.withSchedule(
|
.withSchedule(
|
||||||
SimpleScheduleBuilder.simpleSchedule()
|
SimpleScheduleBuilder.simpleSchedule()
|
||||||
.withIntervalInMilliseconds(intervalInMills)
|
.withIntervalInMilliseconds(intervalInMills)
|
||||||
@@ -88,14 +89,16 @@ public class SchedulerService {
|
|||||||
return conversionService.convert(newTrigger, TriggerDTO.class);
|
return conversionService.convert(newTrigger, TriggerDTO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public TriggerDTO rescheduleTrigger(String name, SchedulerConfigParam config) throws SchedulerException {
|
public TriggerDTO rescheduleTrigger(String name, SchedulerConfigParam config) throws SchedulerException {
|
||||||
int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
|
int intervalInMills = LegacySchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay());
|
||||||
|
|
||||||
Optional<TriggerKey> optionalTriggerKey = getTriggerByKey(name);
|
Optional<TriggerKey> optionalTriggerKey = getTriggerByKey(name);
|
||||||
TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name));
|
TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name));
|
||||||
Trigger trigger = scheduler.getTrigger(triggerKey);
|
Trigger trigger = scheduler.getTrigger(triggerKey);
|
||||||
|
|
||||||
Trigger newTrigger = TriggerBuilder.newTrigger()
|
Trigger newTrigger = newTrigger()
|
||||||
.withSchedule(
|
.withSchedule(
|
||||||
SimpleScheduleBuilder.simpleSchedule()
|
SimpleScheduleBuilder.simpleSchedule()
|
||||||
.withIntervalInMilliseconds(intervalInMills)
|
.withIntervalInMilliseconds(intervalInMills)
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.services;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerCommandDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import org.quartz.*;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class SimpleTriggerSchedulerService extends AbstractSchedulerService {
|
||||||
|
|
||||||
|
public SimpleTriggerSchedulerService(Scheduler scheduler, ConversionService conversionService) {
|
||||||
|
super(scheduler, conversionService);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleTriggerDTO getSimpleTriggerByName(String name) throws SchedulerException, TriggerNotFoundException {
|
||||||
|
Trigger trigger = getTriggerByName(name);
|
||||||
|
return conversionService.convert(trigger, SimpleTriggerDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public SimpleTriggerDTO scheduleSimpleTrigger(String jobClassname, SimpleTriggerCommandDTO triggerCommandDTO) throws SchedulerException, ClassNotFoundException {
|
||||||
|
Class<? extends Job> jobClass = (Class<? extends Job>) Class.forName(jobClassname);
|
||||||
|
JobDetail jobDetail = JobBuilder.newJob()
|
||||||
|
.ofType(jobClass)
|
||||||
|
.storeDurably(false)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
SimpleTrigger newSimpleTrigger = conversionService.convert(triggerCommandDTO, SimpleTrigger.class);
|
||||||
|
scheduler.scheduleJob(jobDetail, newSimpleTrigger);
|
||||||
|
|
||||||
|
return conversionService.convert(newSimpleTrigger, SimpleTriggerDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TriggerDTO rescheduleSimpleTrigger(SimpleTriggerCommandDTO triggerCommandDTO) throws SchedulerException {
|
||||||
|
//Optional<TriggerKey> optionalTriggerKey = getTriggerByKey(name);
|
||||||
|
// TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name));
|
||||||
|
|
||||||
|
SimpleTrigger newSimpleTrigger = conversionService.convert(triggerCommandDTO, SimpleTrigger.class);
|
||||||
|
|
||||||
|
TriggerKey triggerKey = TriggerKey.triggerKey(triggerCommandDTO.getTriggerName());
|
||||||
|
scheduler.rescheduleJob(triggerKey, newSimpleTrigger);
|
||||||
|
|
||||||
|
return conversionService.convert(newSimpleTrigger, SimpleTriggerDTO.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.controllers;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.QuartManagerApplicationTests;
|
||||||
|
import it.fabioformosa.quartzmanager.controllers.utils.InvalidSimpleTriggerCommandDTOProvider;
|
||||||
|
import it.fabioformosa.quartzmanager.controllers.utils.TestUtils;
|
||||||
|
import it.fabioformosa.quartzmanager.controllers.utils.TriggerUtils;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerCommandDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerInputDTO;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import it.fabioformosa.quartzmanager.services.SimpleTriggerSchedulerService;
|
||||||
|
import org.junit.jupiter.api.AfterEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
|
import org.junit.jupiter.params.provider.ArgumentsSource;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.test.context.ContextConfiguration;
|
||||||
|
import org.springframework.test.web.servlet.MockMvc;
|
||||||
|
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
|
||||||
|
|
||||||
|
@ContextConfiguration(classes = {QuartManagerApplicationTests.class})
|
||||||
|
@WebMvcTest(controllers = SimpleTriggerController.class, properties = {
|
||||||
|
"quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.SampleJob"
|
||||||
|
})
|
||||||
|
class SimpleTriggerControllerTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private SimpleTriggerSchedulerService simpleTriggerSchedulerService;
|
||||||
|
|
||||||
|
@AfterEach
|
||||||
|
void cleanUp(){
|
||||||
|
Mockito.reset(simpleTriggerSchedulerService);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void whenGetIsCalled_thenASimpleTriggerIsReturned() throws Exception {
|
||||||
|
SimpleTriggerDTO expectedSimpleTriggerDTO = TriggerUtils.getSimpleTriggerInstance("mytrigger");
|
||||||
|
Mockito.when(simpleTriggerSchedulerService.getSimpleTriggerByName("mytrigger")).thenReturn(expectedSimpleTriggerDTO);
|
||||||
|
|
||||||
|
mockMvc.perform(get(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(MockMvcResultMatchers.content().json(TestUtils.toJson(expectedSimpleTriggerDTO)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenAnExistingTrigger_whenGetIsCalled_then404IsReturned() throws Exception {
|
||||||
|
Mockito.when(simpleTriggerSchedulerService.getSimpleTriggerByName("not_existing_trigger_name")).thenThrow(new TriggerNotFoundException("not_existing_trigger_name"));
|
||||||
|
|
||||||
|
mockMvc.perform(get(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/not_existing_trigger_name")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isNotFound());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenASimpleTriggerCommandDTO_whenPosted_thenANewSimpleTriggerIsCreated() throws Exception {
|
||||||
|
SimpleTriggerInputDTO simpleTriggerInputDTO = buildSimpleTriggerCommandDTO();
|
||||||
|
SimpleTriggerDTO expectedSimpleTriggerDTO = TriggerUtils.getSimpleTriggerInstance("mytrigger", simpleTriggerInputDTO);
|
||||||
|
Mockito.when(simpleTriggerSchedulerService.scheduleSimpleTrigger(any(), any())).thenReturn(expectedSimpleTriggerDTO);
|
||||||
|
mockMvc.perform(
|
||||||
|
post(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(TestUtils.toJson(simpleTriggerInputDTO))
|
||||||
|
)
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isCreated())
|
||||||
|
.andExpect(MockMvcResultMatchers.content().json(TestUtils.toJson(expectedSimpleTriggerDTO)))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SimpleTriggerInputDTO buildSimpleTriggerCommandDTO() {
|
||||||
|
return SimpleTriggerInputDTO.builder()
|
||||||
|
.startDate(new Date())
|
||||||
|
.repeatCount(20)
|
||||||
|
.repeatInterval(20000L)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ArgumentsSource(InvalidSimpleTriggerCommandDTOProvider.class)
|
||||||
|
void givenAnInvalidSimpleTriggerCommandDTO_whenPostedANewTrigger_thenAnErrorIsReturned(SimpleTriggerInputDTO invalidSimpleTriggerComandDTO) throws Exception {
|
||||||
|
mockMvc.perform(post(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(TestUtils.toJson(invalidSimpleTriggerComandDTO)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().is4xxClientError());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenATriggerName_whenPutSimpleTriggerCommandDTO_thenTheSimpleTriggerIsRescheduled() throws Exception {
|
||||||
|
SimpleTriggerInputDTO simpleTriggerInputDTO = buildSimpleTriggerCommandDTO();
|
||||||
|
SimpleTriggerDTO expectedSimpleTriggerDTO = TriggerUtils.getSimpleTriggerInstance("mytrigger", simpleTriggerInputDTO);
|
||||||
|
SimpleTriggerCommandDTO simpleTriggerCommandDTO = SimpleTriggerCommandDTO.builder()
|
||||||
|
.triggerName("mytrigger")
|
||||||
|
.simpleTriggerInputDTO(simpleTriggerInputDTO)
|
||||||
|
.build();
|
||||||
|
Mockito.when(simpleTriggerSchedulerService.rescheduleSimpleTrigger(simpleTriggerCommandDTO)).thenReturn(expectedSimpleTriggerDTO);
|
||||||
|
|
||||||
|
mockMvc.perform(put(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(TestUtils.toJson(simpleTriggerInputDTO)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
.andExpect(MockMvcResultMatchers.content().json(TestUtils.toJson(expectedSimpleTriggerDTO)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ParameterizedTest
|
||||||
|
@ArgumentsSource(InvalidSimpleTriggerCommandDTOProvider.class)
|
||||||
|
void givenAnInvalidSimpleTriggerCommandDTO_whenATriggerIsRescheduled_thenAnErrorIsReturned(SimpleTriggerInputDTO invalidSimpleTriggerCommandTO) throws Exception {
|
||||||
|
mockMvc.perform(put(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
||||||
|
.contentType(MediaType.APPLICATION_JSON)
|
||||||
|
.content(TestUtils.toJson(invalidSimpleTriggerCommandTO)))
|
||||||
|
.andExpect(MockMvcResultMatchers.status().is4xxClientError());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -6,7 +6,7 @@ import it.fabioformosa.quartzmanager.controllers.utils.TestUtils;
|
|||||||
import it.fabioformosa.quartzmanager.controllers.utils.TriggerUtils;
|
import it.fabioformosa.quartzmanager.controllers.utils.TriggerUtils;
|
||||||
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
||||||
import it.fabioformosa.quartzmanager.services.SchedulerService;
|
import it.fabioformosa.quartzmanager.services.LegacySchedulerService;
|
||||||
import org.junit.jupiter.api.AfterEach;
|
import org.junit.jupiter.api.AfterEach;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.params.ParameterizedTest;
|
import org.junit.jupiter.params.ParameterizedTest;
|
||||||
@@ -25,7 +25,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder
|
|||||||
|
|
||||||
@ContextConfiguration(classes = {QuartManagerApplicationTests.class})
|
@ContextConfiguration(classes = {QuartManagerApplicationTests.class})
|
||||||
@WebMvcTest(controllers = TriggerController.class, properties = {
|
@WebMvcTest(controllers = TriggerController.class, properties = {
|
||||||
"quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob"
|
"quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.SampleJob"
|
||||||
})
|
})
|
||||||
class TriggerControllerTest {
|
class TriggerControllerTest {
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ class TriggerControllerTest {
|
|||||||
private MockMvc mockMvc;
|
private MockMvc mockMvc;
|
||||||
|
|
||||||
@MockBean
|
@MockBean
|
||||||
private SchedulerService schedulerService;
|
private LegacySchedulerService schedulerService;
|
||||||
|
|
||||||
@AfterEach
|
@AfterEach
|
||||||
void cleanUp(){
|
void cleanUp(){
|
||||||
@@ -67,7 +67,7 @@ class TriggerControllerTest {
|
|||||||
@Test
|
@Test
|
||||||
void whenGetIsCalled_thenATriggerIsReturned() throws Exception {
|
void whenGetIsCalled_thenATriggerIsReturned() throws Exception {
|
||||||
TriggerDTO expectedTriggerDTO = TriggerUtils.getTriggerInstance("mytrigger");
|
TriggerDTO expectedTriggerDTO = TriggerUtils.getTriggerInstance("mytrigger");
|
||||||
Mockito.when(schedulerService.getTriggerByName("mytrigger")).thenReturn(expectedTriggerDTO);
|
Mockito.when(schedulerService.getLegacyTriggerByName("mytrigger")).thenReturn(expectedTriggerDTO);
|
||||||
|
|
||||||
mockMvc.perform(get(TriggerController.TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
mockMvc.perform(get(TriggerController.TRIGGER_CONTROLLER_BASE_URL + "/mytrigger")
|
||||||
.contentType(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk())
|
.contentType(MediaType.APPLICATION_JSON)).andExpect(MockMvcResultMatchers.status().isOk())
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.controllers.utils;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.dto.SimpleTriggerInputDTO;
|
||||||
|
import org.junit.jupiter.api.extension.ExtensionContext;
|
||||||
|
import org.junit.jupiter.params.provider.Arguments;
|
||||||
|
import org.junit.jupiter.params.provider.ArgumentsProvider;
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
public class InvalidSimpleTriggerCommandDTOProvider implements ArgumentsProvider {
|
||||||
|
@Override
|
||||||
|
public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) throws Exception {
|
||||||
|
return Stream.of(
|
||||||
|
Arguments.of(SimpleTriggerInputDTO.builder().build()),
|
||||||
|
Arguments.of(SimpleTriggerInputDTO.builder().repeatCount(1).build()),
|
||||||
|
Arguments.of(SimpleTriggerInputDTO.builder().repeatInterval(1L).build())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
package it.fabioformosa.quartzmanager.controllers.utils;
|
package it.fabioformosa.quartzmanager.controllers.utils;
|
||||||
|
|
||||||
import it.fabioformosa.quartzmanager.common.utils.DateUtils;
|
import it.fabioformosa.quartzmanager.common.utils.DateUtils;
|
||||||
import it.fabioformosa.quartzmanager.dto.JobKeyDTO;
|
import it.fabioformosa.quartzmanager.dto.*;
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerDTO;
|
|
||||||
import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO;
|
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
@@ -30,4 +28,50 @@ public class TriggerUtils {
|
|||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public SimpleTriggerDTO getSimpleTriggerInstance(String triggerName, SimpleTriggerInputDTO simpleTriggerInputDTO){
|
||||||
|
return SimpleTriggerDTO.builder()
|
||||||
|
.description("simple trigger")
|
||||||
|
.repeatCount(simpleTriggerInputDTO.getRepeatCount())
|
||||||
|
.repeatInterval(simpleTriggerInputDTO.getRepeatInterval())
|
||||||
|
.endTime(DateUtils.getHoursFromNow(2L))
|
||||||
|
.finalFireTime(DateUtils.getHoursFromNow(2L))
|
||||||
|
.jobKeyDTO(JobKeyDTO.builder()
|
||||||
|
.group("defaultJobGroup")
|
||||||
|
.name("sampleJob")
|
||||||
|
.build())
|
||||||
|
.mayFireAgain(true)
|
||||||
|
.triggerKeyDTO(TriggerKeyDTO.builder()
|
||||||
|
.group("defaultTriggerGroup")
|
||||||
|
.name(triggerName)
|
||||||
|
.build())
|
||||||
|
.misfireInstruction(1)
|
||||||
|
.nextFireTime(DateUtils.getHoursFromNow(1L))
|
||||||
|
.priority(1)
|
||||||
|
.startTime(DateUtils.fromLocaleDateTimeToDate(LocalDateTime.now()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
static public SimpleTriggerDTO getSimpleTriggerInstance(String triggerName){
|
||||||
|
return SimpleTriggerDTO.builder()
|
||||||
|
.description("simple trigger")
|
||||||
|
.repeatCount(2)
|
||||||
|
.repeatInterval(1000L)
|
||||||
|
.endTime(DateUtils.getHoursFromNow(2L))
|
||||||
|
.finalFireTime(DateUtils.getHoursFromNow(2L))
|
||||||
|
.jobKeyDTO(JobKeyDTO.builder()
|
||||||
|
.group("defaultJobGroup")
|
||||||
|
.name("sampleJob")
|
||||||
|
.build())
|
||||||
|
.mayFireAgain(true)
|
||||||
|
.triggerKeyDTO(TriggerKeyDTO.builder()
|
||||||
|
.group("defaultTriggerGroup")
|
||||||
|
.name(triggerName)
|
||||||
|
.build())
|
||||||
|
.misfireInstruction(1)
|
||||||
|
.nextFireTime(DateUtils.getHoursFromNow(1L))
|
||||||
|
.priority(1)
|
||||||
|
.startTime(DateUtils.fromLocaleDateTimeToDate(LocalDateTime.now()))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.jobs;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord;
|
||||||
|
import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType;
|
||||||
|
import org.quartz.JobExecutionContext;
|
||||||
|
|
||||||
|
public class SampleJob extends AbstractLoggingJob {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LogRecord doIt(JobExecutionContext jobExecutionContext) {
|
||||||
|
return new LogRecord(LogType.INFO, "Hello!");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,81 @@
|
|||||||
|
package it.fabioformosa.quartzmanager.services;
|
||||||
|
|
||||||
|
import it.fabioformosa.quartzmanager.common.utils.DateUtils;
|
||||||
|
import it.fabioformosa.quartzmanager.dto.*;
|
||||||
|
import it.fabioformosa.quartzmanager.exceptions.TriggerNotFoundException;
|
||||||
|
import org.assertj.core.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.quartz.Scheduler;
|
||||||
|
import org.quartz.SchedulerException;
|
||||||
|
import org.quartz.SimpleTrigger;
|
||||||
|
import org.springframework.core.convert.ConversionService;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.MockitoAnnotations.openMocks;
|
||||||
|
|
||||||
|
class SimpleTriggerSchedulerServiceTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private SimpleTriggerSchedulerService simpleSchedulerService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Scheduler scheduler;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private ConversionService conversionService;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
void setUp() {
|
||||||
|
openMocks(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenANotExistingTrigger_whenGetSimplerTriggerByNameIsCalled_thenThrowException() throws SchedulerException {
|
||||||
|
String not_existing_trigger = "not_existing_trigger";
|
||||||
|
Mockito.when(scheduler.getTrigger(any())).thenReturn(null);
|
||||||
|
|
||||||
|
Throwable throwable = Assertions.catchThrowable(() -> simpleSchedulerService.getSimpleTriggerByName(not_existing_trigger));
|
||||||
|
Assertions.assertThat(throwable).isInstanceOf(TriggerNotFoundException.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void givenASimpleTriggerCommandDTO_whenASimpleTriggerIsScheduled_thenATriggerDTOIsReturned() throws SchedulerException, ClassNotFoundException {
|
||||||
|
SimpleTriggerInputDTO triggerInputDTO = SimpleTriggerInputDTO.builder()
|
||||||
|
.startDate(new Date())
|
||||||
|
.repeatInterval(5000L).repeatCount(5)
|
||||||
|
.endDate(DateUtils.getHoursFromNow(1))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
String simpleTriggerName = "simpleTrigger";
|
||||||
|
|
||||||
|
SimpleTriggerDTO expectedTriggerDTO = SimpleTriggerDTO.builder()
|
||||||
|
.startTime(triggerInputDTO.getStartDate())
|
||||||
|
.repeatInterval(1000)
|
||||||
|
.repeatCount(10)
|
||||||
|
.mayFireAgain(true)
|
||||||
|
.finalFireTime(triggerInputDTO.getEndDate())
|
||||||
|
.jobKeyDTO(JobKeyDTO.builder().name("MyJob").build())
|
||||||
|
.misfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_FIRE_NOW)
|
||||||
|
.triggerKeyDTO(TriggerKeyDTO.builder().name(simpleTriggerName).build())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Mockito.when(scheduler.scheduleJob(any(), any())).thenReturn(new Date());
|
||||||
|
Mockito.when(conversionService.convert(any(), eq(SimpleTriggerDTO.class))).thenReturn(expectedTriggerDTO);
|
||||||
|
|
||||||
|
SimpleTriggerCommandDTO simpleTriggerCommandDTO = SimpleTriggerCommandDTO.builder()
|
||||||
|
.triggerName(simpleTriggerName)
|
||||||
|
.simpleTriggerInputDTO(triggerInputDTO)
|
||||||
|
.build();
|
||||||
|
SimpleTriggerDTO simpleTrigger = simpleSchedulerService.scheduleSimpleTrigger("it.fabioformosa.quartzmanager.jobs.SampleJob", simpleTriggerCommandDTO);
|
||||||
|
|
||||||
|
Assertions.assertThat(simpleTrigger).isEqualTo(expectedTriggerDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
name: Phil
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
app:
|
||||||
|
name: quartz-manager
|
||||||
|
|
||||||
|
quartz:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
job:
|
||||||
|
frequency: 4000
|
||||||
|
repeatCount: 19
|
||||||
|
|
||||||
|
logging:
|
||||||
|
level:
|
||||||
|
org.springframework.boot.autoconfigure.security: INFO
|
||||||
|
it.fabioformosa: DEBUG
|
||||||
|
org.quartz: INFO
|
||||||
|
|
||||||
|
quartz-manager:
|
||||||
|
jobClass: it.fabioformosa.quartzmanager.jobs.SampleJob
|
||||||
Reference in New Issue
Block a user