From d9f9ee96afbb54626b82d87bafbc371d4191b386 Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Tue, 13 Sep 2022 23:38:31 +0200 Subject: [PATCH] #52 added the jobClass selection --- quartz-manager-frontend/src/app/app.module.ts | 4 ++ .../simple-trigger-config.component.html | 9 ++-- .../simple-trigger-config.component.spec.ts | 3 +- .../simple-trigger-config.component.ts | 13 ++++- .../src/app/model/simple-trigger.command.ts | 1 + .../src/app/services/config.service.ts | 54 ++++++++++--------- .../src/app/services/index.ts | 2 + .../src/app/services/job.service.ts | 18 +++++++ .../src/app/services/scheduler.service.ts | 9 ++-- .../quartz-manager-starter-api/pom.xml | 5 ++ .../AbstractTriggerController.java | 6 +-- .../controllers/JobController.java | 13 +++-- .../controllers/SimpleTriggerController.java | 2 +- .../controllers/TriggerController.java | 35 ++++++------ .../quartzmanager/dto/TriggerCommandDTO.java | 4 ++ .../quartzmanager/services/JobService.java | 43 +++++++++++++++ .../SimpleTriggerSchedulerService.java | 4 +- .../SimpleTriggerControllerTest.java | 5 +- .../controllers/TriggerControllerTest.java | 18 +------ .../services/JobServiceTest.java | 45 ++++++++++++++++ .../SimpleTriggerSchedulerServiceTest.java | 3 +- .../samplepackage/SampleExtraJob.java | 15 ++++++ .../quartzmanager/jobs/myjobs/SampleJob.java | 2 +- .../src/main/resources/application.yml | 1 + 24 files changed, 226 insertions(+), 88 deletions(-) create mode 100644 quartz-manager-frontend/src/app/services/job.service.ts create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/JobService.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/JobServiceTest.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/samplepackage/SampleExtraJob.java diff --git a/quartz-manager-frontend/src/app/app.module.ts b/quartz-manager-frontend/src/app/app.module.ts index 081bb21..939bdf1 100644 --- a/quartz-manager-frontend/src/app/app.module.ts +++ b/quartz-manager-frontend/src/app/app.module.ts @@ -18,6 +18,7 @@ import {MatIconModule} from '@angular/material/icon'; import {MatButtonModule} from '@angular/material/button'; import {MatCardModule} from '@angular/material/card'; import {MatDatepickerModule} from '@angular/material/datepicker'; +import {MatSelectModule} from '@angular/material/select'; import {MatListModule} from '@angular/material/list'; import {MatSidenavModule} from '@angular/material/sidenav'; @@ -50,6 +51,7 @@ import { AuthService, UserService, SchedulerService, + JobService, ConfigService, ProgressWebsocketService, LogsWebsocketService, @@ -138,6 +140,7 @@ export function jwtOptionsFactory(apiService: ApiService) { MatChipsModule, MatIconModule, MatInputModule, + MatSelectModule, MatToolbarModule, MatCardModule, MatListModule, @@ -164,6 +167,7 @@ export function jwtOptionsFactory(apiService: ApiService) { GuestGuard, AdminGuard, SchedulerService, + JobService, TriggerService, ProgressWebsocketService, LogsWebsocketService, diff --git a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html index 734f7eb..63d7fb1 100644 --- a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html +++ b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.html @@ -20,10 +20,11 @@
Job Class - + + + {{job}} + +
diff --git a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts index e44882b..cce311a 100644 --- a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts +++ b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.spec.ts @@ -18,6 +18,7 @@ import {Trigger} from '../../model/trigger.model'; import {JobDetail} from '../../model/jobDetail.model'; import {SimpleTriggerForm} from '../../model/simple-trigger.form'; import {SimpleTrigger} from '../../model/simple-trigger.model'; +import JobService from '../../services/job.service'; describe('SimpleTriggerConfig', () => { @@ -33,7 +34,7 @@ describe('SimpleTriggerConfig', () => { MatNativeDateModule, MatCardModule, MatIconModule, HttpClientTestingModule, RouterTestingModule], declarations: [SimpleTriggerConfigComponent], - providers: [SchedulerService, ApiService, ConfigService], + providers: [SchedulerService, ApiService, ConfigService, JobService], schemas: [NO_ERRORS_SCHEMA] }).compileComponents(); diff --git a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts index 1af359e..b304226 100644 --- a/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts +++ b/quartz-manager-frontend/src/app/components/simple-trigger-config/simple-trigger-config.component.ts @@ -1,5 +1,5 @@ import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; -import {SchedulerService} from '../../services'; +import {JobService, SchedulerService} from '../../services'; import {Scheduler} from '../../model/scheduler.model'; import {SimpleTriggerCommand} from '../../model/simple-trigger.command'; import {SimpleTrigger} from '../../model/simple-trigger.model'; @@ -27,16 +27,24 @@ export class SimpleTriggerConfigComponent implements OnInit { private selectedTriggerKey: TriggerKey; + private jobs: Array; + enabledTriggerForm = false; @Output() onNewTrigger = new EventEmitter(); constructor( - private schedulerService: SchedulerService + private schedulerService: SchedulerService, + private jobService: JobService ) { } ngOnInit() { + this.fetchJobs(); + } + + private fetchJobs() { + this.jobService.fetchJobs().subscribe(jobs => this.jobs = jobs); } openTriggerForm() { @@ -109,6 +117,7 @@ export class SimpleTriggerConfigComponent implements OnInit { private _fromFormToCommand = (simpleTriggerForm: SimpleTriggerForm): SimpleTriggerCommand => { const simpleTriggerCommand = new SimpleTriggerCommand(); simpleTriggerCommand.triggerName = simpleTriggerForm.triggerName; + simpleTriggerCommand.jobClass = simpleTriggerForm.jobClass; simpleTriggerCommand.repeatCount = simpleTriggerForm.repeatCount; simpleTriggerCommand.repeatInterval = simpleTriggerForm.repeatInterval; simpleTriggerCommand.startDate = simpleTriggerForm.startDate?.toDate(); diff --git a/quartz-manager-frontend/src/app/model/simple-trigger.command.ts b/quartz-manager-frontend/src/app/model/simple-trigger.command.ts index f6dc70b..03f1231 100644 --- a/quartz-manager-frontend/src/app/model/simple-trigger.command.ts +++ b/quartz-manager-frontend/src/app/model/simple-trigger.command.ts @@ -1,5 +1,6 @@ export class SimpleTriggerCommand { triggerName: string; + jobClass: string; startDate: Date; endDate: Date; repeatCount: number; diff --git a/quartz-manager-frontend/src/app/services/config.service.ts b/quartz-manager-frontend/src/app/services/config.service.ts index 9294bec..9a2d7e4 100644 --- a/quartz-manager-frontend/src/app/services/config.service.ts +++ b/quartz-manager-frontend/src/app/services/config.service.ts @@ -1,24 +1,28 @@ -import { Injectable } from '@angular/core'; -import { environment } from '../../environments/environment'; +import {Injectable} from '@angular/core'; +import {environment} from '../../environments/environment'; const WEBJAR_PATH = '/quartz-manager-ui/'; -export function getHtmlBaseUrl(){ - const baseUrl = getBaseUrl() || '/'; - return environment.production ? getBaseUrl() + WEBJAR_PATH: '/'; - } +export const CONTEXT_PATH = '/quartz-manager'; -export function getBaseUrl(){ - if(environment.production){ - let contextPath: string = window.location.pathname.split('/')[1] || ''; - if(contextPath && ('/' + contextPath + '/') === WEBJAR_PATH) - return ''; - if(contextPath) - contextPath = '/' + contextPath; - return contextPath; - } - return ''; +export function getHtmlBaseUrl() { + const baseUrl = getBaseUrl() || '/'; + return environment.production ? getBaseUrl() + WEBJAR_PATH : '/'; +} + +export function getBaseUrl() { + if (environment.production) { + let contextPath: string = window.location.pathname.split('/')[1] || ''; + if (contextPath && ('/' + contextPath + '/') === WEBJAR_PATH) { + return ''; + } + if (contextPath) { + contextPath = '/' + contextPath; + } + return contextPath; + } + return ''; } @Injectable() @@ -45,35 +49,35 @@ export class ConfigService { private _signup_url = this._api_url + '/signup'; get reset_credentials_url(): string { - return this._reset_credentials_url; + return this._reset_credentials_url; } get refresh_token_url(): string { - return this._refresh_token_url; + return this._refresh_token_url; } get whoami_url(): string { - return this._whoami_url; + return this._whoami_url; } get users_url(): string { - return this._users_url; + return this._users_url; } get login_url(): string { - return this._login_url; + return this._login_url; } get logout_url(): string { - return this._logout_url; + return this._logout_url; } get change_password_url(): string { - return this._change_password_url; + return this._change_password_url; } - get signup_url():string { - return this._signup_url; + get signup_url(): string { + return this._signup_url; } } diff --git a/quartz-manager-frontend/src/app/services/index.ts b/quartz-manager-frontend/src/app/services/index.ts index 1352120..a3e5802 100644 --- a/quartz-manager-frontend/src/app/services/index.ts +++ b/quartz-manager-frontend/src/app/services/index.ts @@ -7,4 +7,6 @@ export * from './websocket.service'; export * from './progress.websocket.service'; export * from './logs.websocket.service'; export * from './trigger.service' +export * from './job.service' + diff --git a/quartz-manager-frontend/src/app/services/job.service.ts b/quartz-manager-frontend/src/app/services/job.service.ts new file mode 100644 index 0000000..c5cbccc --- /dev/null +++ b/quartz-manager-frontend/src/app/services/job.service.ts @@ -0,0 +1,18 @@ +import {Injectable} from '@angular/core'; +import {ApiService} from './api.service'; +import {CONTEXT_PATH, getBaseUrl} from './config.service'; +import {Observable} from 'rxjs'; + +@Injectable() +export class JobService { + + constructor( + private apiService: ApiService + ) { + } + + fetchJobs = (): Observable => { + return this.apiService.get(getBaseUrl() + `${CONTEXT_PATH}/jobs`) + } + +} diff --git a/quartz-manager-frontend/src/app/services/scheduler.service.ts b/quartz-manager-frontend/src/app/services/scheduler.service.ts index 3f7642c..e675862 100644 --- a/quartz-manager-frontend/src/app/services/scheduler.service.ts +++ b/quartz-manager-frontend/src/app/services/scheduler.service.ts @@ -1,18 +1,15 @@ -import { Injectable } from '@angular/core'; -import { getBaseUrl } from '.'; -import { ApiService } from './api.service'; +import {Injectable} from '@angular/core'; +import {CONTEXT_PATH, getBaseUrl} from '.'; +import {ApiService} from './api.service'; import {Trigger} from '../model/trigger.model'; import {Observable} from 'rxjs'; import {SimpleTriggerCommand} from '../model/simple-trigger.command'; -import {SchedulerConfig} from '../model/schedulerConfig.model'; import {Scheduler} from '../model/scheduler.model'; -const CONTEXT_PATH = '/quartz-manager'; @Injectable() export class SchedulerService { - constructor( private apiService: ApiService ) { } diff --git a/quartz-manager-parent/quartz-manager-starter-api/pom.xml b/quartz-manager-parent/quartz-manager-starter-api/pom.xml index 4b0b6ab..62ba738 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/pom.xml +++ b/quartz-manager-parent/quartz-manager-starter-api/pom.xml @@ -97,6 +97,11 @@ javax.el 3.0.0 + + org.reflections + reflections + 0.10.2 + diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/AbstractTriggerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/AbstractTriggerController.java index ba76182..3c6a786 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/AbstractTriggerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/AbstractTriggerController.java @@ -1,10 +1,8 @@ package it.fabioformosa.quartzmanager.controllers; -import org.springframework.beans.factory.annotation.Value; - public class AbstractTriggerController { - @Value("${quartz-manager.jobClass}") - protected String jobClassname; +// @Value("${quartz-manager.jobClass}") +// protected String jobClassname; } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/JobController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/JobController.java index 5a37549..5361818 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/JobController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/JobController.java @@ -1,21 +1,26 @@ package it.fabioformosa.quartzmanager.controllers; +import it.fabioformosa.quartzmanager.services.JobService; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; -import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @RequestMapping("/quartz-manager/jobs") @RestController public class JobController extends AbstractTriggerController { + private JobService jobService; + + public JobController(JobService jobService) { + this.jobService = jobService; + } + @GetMapping public List listJobs(){ - List jobClasses = new ArrayList(); - jobClasses.add(jobClassname); - return jobClasses; + return jobService.getJobClasses().stream().map(Class::getName).collect(Collectors.toList()); } } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerController.java index e8c5909..f1b0177 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerController.java @@ -62,7 +62,7 @@ public class SimpleTriggerController extends AbstractTriggerController { .triggerName(name) .simpleTriggerInputDTO(simpleTriggerInputDTO) .build(); - SimpleTriggerDTO newTriggerDTO = simpleSchedulerService.scheduleSimpleTrigger(jobClassname, simpleTriggerCommandDTO); + SimpleTriggerDTO newTriggerDTO = simpleSchedulerService.scheduleSimpleTrigger(simpleTriggerCommandDTO); log.info("SIMPLE TRIGGER - CREATED a SimpleTrigger {}", newTriggerDTO); return newTriggerDTO; } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/TriggerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/TriggerController.java index 1982df7..58e95a9 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/TriggerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/TriggerController.java @@ -13,7 +13,6 @@ import it.fabioformosa.quartzmanager.services.LegacySchedulerService; import it.fabioformosa.quartzmanager.services.TriggerService; import lombok.extern.slf4j.Slf4j; import org.quartz.SchedulerException; -import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; import javax.validation.Valid; @@ -46,23 +45,23 @@ public class TriggerController extends AbstractTriggerController { return schedulerService.getLegacyTriggerByName(name); } - @Deprecated - @PostMapping("/{name}") - @ResponseStatus(HttpStatus.CREATED) - @Operation(summary = "Create a new trigger") - @ApiResponses(value = { - @ApiResponse(responseCode = "201", description = "Created the new trigger", - content = { @Content(mediaType = "application/json", - schema = @Schema(implementation = TriggerDTO.class)) }), - @ApiResponse(responseCode = "400", description = "Invalid config supplied", - content = @Content) - }) - public TriggerDTO postTrigger(@PathVariable String name, @Valid @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { - log.info("TRIGGER - CREATING a trigger {} {}", name, config); - TriggerDTO newTriggerDTO = schedulerService.scheduleNewTrigger(name, jobClassname, config); - log.info("TRIGGER - CREATED a trigger {}", newTriggerDTO); - return newTriggerDTO; - } +// @Deprecated +// @PostMapping("/{name}") +// @ResponseStatus(HttpStatus.CREATED) +// @Operation(summary = "Create a new trigger") +// @ApiResponses(value = { +// @ApiResponse(responseCode = "201", description = "Created the new trigger", +// content = { @Content(mediaType = "application/json", +// schema = @Schema(implementation = TriggerDTO.class)) }), +// @ApiResponse(responseCode = "400", description = "Invalid config supplied", +// content = @Content) +// }) +// public TriggerDTO postTrigger(@PathVariable String name, @Valid @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { +// log.info("TRIGGER - CREATING a trigger {} {}", name, config); +// TriggerDTO newTriggerDTO = schedulerService.scheduleNewTrigger(name, config); +// log.info("TRIGGER - CREATED a trigger {}", newTriggerDTO); +// return newTriggerDTO; +// } @PutMapping("/{name}") @Operation(summary = "Reschedule the trigger") diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerCommandDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerCommandDTO.java index da58424..eb32405 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerCommandDTO.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerCommandDTO.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.annotation.JsonFormat; import lombok.*; import lombok.experimental.SuperBuilder; +import javax.validation.constraints.NotNull; import java.util.Date; @SuperBuilder @@ -14,6 +15,9 @@ import java.util.Date; @Data public class TriggerCommandDTO { + @NotNull + private String jobClass; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'") private Date startDate; diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/JobService.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/JobService.java new file mode 100644 index 0000000..6769018 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/JobService.java @@ -0,0 +1,43 @@ +package it.fabioformosa.quartzmanager.services; + +import it.fabioformosa.quartzmanager.jobs.AbstractLoggingJob; +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; +import org.reflections.Reflections; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; + +import javax.annotation.PostConstruct; +import java.util.*; +import java.util.stream.Collectors; + +@Service +public class JobService { + + @Getter + private List> jobClasses = new ArrayList<>(); + + private List jobClassPackages = new ArrayList<>(); + + public JobService(@Value("${quartz-manager.jobClassPackages}") String jobClassPackages) { + List splitPackages = Arrays.stream(Optional.of(jobClassPackages).map(str -> str.split(",")).get()) + .map(String::trim) + .filter(StringUtils::isNotBlank) + .collect(Collectors.toList()); + if (splitPackages.size() > 0) + this.jobClassPackages.addAll(splitPackages); + } + + @PostConstruct + public void initJobClassList() { + List> foundJobClasses = jobClassPackages.stream().flatMap(jobClassPackage -> findJobClassesInPackage(jobClassPackage).stream()).collect(Collectors.toList()); + if (foundJobClasses.size() > 0) + this.jobClasses.addAll(foundJobClasses); + } + + private static Set> findJobClassesInPackage(String packageStr) { + Reflections reflections = new Reflections(packageStr); + return reflections.getSubTypesOf(AbstractLoggingJob.class); + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerService.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerService.java index 95ec237..158f811 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerService.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerService.java @@ -20,8 +20,8 @@ public class SimpleTriggerSchedulerService extends AbstractSchedulerService { return conversionService.convert(trigger, SimpleTriggerDTO.class); } - public SimpleTriggerDTO scheduleSimpleTrigger(String jobClassname, SimpleTriggerCommandDTO triggerCommandDTO) throws SchedulerException, ClassNotFoundException { - Class jobClass = (Class) Class.forName(jobClassname); + public SimpleTriggerDTO scheduleSimpleTrigger(SimpleTriggerCommandDTO triggerCommandDTO) throws SchedulerException, ClassNotFoundException { + Class jobClass = (Class) Class.forName(triggerCommandDTO.getSimpleTriggerInputDTO().getJobClass()); JobDetail jobDetail = JobBuilder.newJob() .ofType(jobClass) .storeDurably(false) diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerControllerTest.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerControllerTest.java index b0e9a54..fa72c6b 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerControllerTest.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/SimpleTriggerControllerTest.java @@ -29,7 +29,7 @@ import static org.springframework.test.web.servlet.request.MockMvcRequestBuilder @ContextConfiguration(classes = {QuartManagerApplicationTests.class}) @WebMvcTest(controllers = SimpleTriggerController.class, properties = { - "quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.SampleJob" + "quartz-manager.jobClassPackages=it.fabioformosa.quartzmanager.jobs" }) class SimpleTriggerControllerTest { @@ -66,7 +66,7 @@ class SimpleTriggerControllerTest { void givenASimpleTriggerCommandDTO_whenPosted_thenANewSimpleTriggerIsCreated() throws Exception { SimpleTriggerInputDTO simpleTriggerInputDTO = buildSimpleTriggerCommandDTO(); SimpleTriggerDTO expectedSimpleTriggerDTO = TriggerUtils.getSimpleTriggerInstance("mytrigger", simpleTriggerInputDTO); - Mockito.when(simpleTriggerSchedulerService.scheduleSimpleTrigger(any(), any())).thenReturn(expectedSimpleTriggerDTO); + Mockito.when(simpleTriggerSchedulerService.scheduleSimpleTrigger(any())).thenReturn(expectedSimpleTriggerDTO); mockMvc.perform( post(SimpleTriggerController.SIMPLE_TRIGGER_CONTROLLER_BASE_URL + "/mytrigger") .contentType(MediaType.APPLICATION_JSON) @@ -79,6 +79,7 @@ class SimpleTriggerControllerTest { private SimpleTriggerInputDTO buildSimpleTriggerCommandDTO() { return SimpleTriggerInputDTO.builder() + .jobClass("it.fabioformosa.quartzmanager.jobs.SampleJob") .startDate(new Date()) .repeatCount(20) .repeatInterval(20000L) diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java index 6f741ba..783a32d 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java @@ -20,12 +20,11 @@ import org.springframework.test.context.ContextConfiguration; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.result.MockMvcResultMatchers; -import static org.mockito.ArgumentMatchers.any; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; @ContextConfiguration(classes = {QuartManagerApplicationTests.class}) @WebMvcTest(controllers = TriggerController.class, properties = { - "quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.SampleJob" + "quartz-manager.jobClassPackages=it.fabioformosa.quartzmanager.jobs" }) class TriggerControllerTest { @@ -40,21 +39,6 @@ class TriggerControllerTest { Mockito.reset(schedulerService); } - @Test - void givenASchedulerConfigParam_whenPosted_thenANewTriggerIsCreated() throws Exception { - SchedulerConfigParam configParamToPost = buildSimpleSchedulerConfigParam(); - TriggerDTO expectedTriggerDTO = TriggerUtils.getTriggerInstance("mytrigger"); - Mockito.when(schedulerService.scheduleNewTrigger(any(), any(), any())).thenReturn(expectedTriggerDTO); - mockMvc.perform( - post(TriggerController.TRIGGER_CONTROLLER_BASE_URL + "/mytrigger") - .contentType(MediaType.APPLICATION_JSON) - .content(TestUtils.toJson(configParamToPost)) - ) - .andExpect(MockMvcResultMatchers.status().isCreated()) - .andExpect(MockMvcResultMatchers.content().json(TestUtils.toJson(expectedTriggerDTO))) - ; - } - @ParameterizedTest @ArgumentsSource(InvalidSchedulerConfigParamProvider.class) void givenAnInvalidSchedulerConfigParam_whenRequestedANewTrigger_thenAnErrorIsReturned(SchedulerConfigParam invalidSchedulerConfigParam) throws Exception { diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/JobServiceTest.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/JobServiceTest.java new file mode 100644 index 0000000..daf9c20 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/JobServiceTest.java @@ -0,0 +1,45 @@ +package it.fabioformosa.quartzmanager.services; + +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + + +class JobServiceTest { + + @Test + void givenTwoJobClassesInTwoPackages_whenTheJobServiceIsCalled_shouldReturnTwoJobClasses(){ + JobService jobService = new JobService("it.fabioformosa.quartzmanager.jobs, it.fabioformosa.samplepackage"); + jobService.initJobClassList(); + Assertions.assertThat(jobService).isNotNull(); + Assertions.assertThat(jobService.getJobClasses().size()).isEqualTo(2); + } + + @ParameterizedTest + @ValueSource(strings = { + "it.fabioformosa.quartzmanager.jobs", + "it.fabioformosa.quartzmanager.jobs,", + ",it.fabioformosa.quartzmanager.jobs" + }) + void givenOnePackage_whenTheJobServiceIsCalled_shouldReturnOneJobClasses(String packageStr){ + JobService jobService = new JobService(packageStr); + jobService.initJobClassList(); + Assertions.assertThat(jobService).isNotNull(); + Assertions.assertThat(jobService.getJobClasses().size()).isEqualTo(1); + } + + @ParameterizedTest + @ValueSource(strings = { + "", + ",", + ", " + }) + void givenNoPackages_whenTheJobServiceIsCalled_shouldReturnNoJobClasses(String packageStr){ + JobService jobService = new JobService(packageStr); + jobService.initJobClassList(); + Assertions.assertThat(jobService).isNotNull(); + Assertions.assertThat(jobService.getJobClasses()).isEmpty(); + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerServiceTest.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerServiceTest.java index ecf8bb9..332854a 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerServiceTest.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/services/SimpleTriggerSchedulerServiceTest.java @@ -48,6 +48,7 @@ class SimpleTriggerSchedulerServiceTest { @Test void givenASimpleTriggerCommandDTO_whenASimpleTriggerIsScheduled_thenATriggerDTOIsReturned() throws SchedulerException, ClassNotFoundException { SimpleTriggerInputDTO triggerInputDTO = SimpleTriggerInputDTO.builder() + .jobClass("it.fabioformosa.quartzmanager.jobs.SampleJob") .startDate(new Date()) .repeatInterval(5000L).repeatCount(5) .endDate(DateUtils.getHoursFromNow(1)) @@ -73,7 +74,7 @@ class SimpleTriggerSchedulerServiceTest { .triggerName(simpleTriggerName) .simpleTriggerInputDTO(triggerInputDTO) .build(); - SimpleTriggerDTO simpleTrigger = simpleSchedulerService.scheduleSimpleTrigger("it.fabioformosa.quartzmanager.jobs.SampleJob", simpleTriggerCommandDTO); + SimpleTriggerDTO simpleTrigger = simpleSchedulerService.scheduleSimpleTrigger(simpleTriggerCommandDTO); Assertions.assertThat(simpleTrigger).isEqualTo(expectedTriggerDTO); } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/samplepackage/SampleExtraJob.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/samplepackage/SampleExtraJob.java new file mode 100644 index 0000000..41283bd --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/samplepackage/SampleExtraJob.java @@ -0,0 +1,15 @@ +package it.fabioformosa.samplepackage; + +import it.fabioformosa.quartzmanager.jobs.AbstractLoggingJob; +import it.fabioformosa.quartzmanager.jobs.entities.LogRecord; +import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType; +import org.quartz.JobExecutionContext; + +public class SampleExtraJob extends AbstractLoggingJob { + + @Override + public LogRecord doIt(JobExecutionContext jobExecutionContext) { + return new LogRecord(LogType.INFO, "Hello!"); + } + +} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java index 7c13981..b4606aa 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/java/it/fabioformosa/quartzmanager/jobs/myjobs/SampleJob.java @@ -10,7 +10,7 @@ import it.fabioformosa.quartzmanager.jobs.entities.LogRecord.LogType; public class SampleJob extends AbstractLoggingJob { @Override public LogRecord doIt(JobExecutionContext jobExecutionContext) { - return new LogRecord(LogType.INFO, "Hello!"); + return new LogRecord(LogType.INFO, "Hello World!"); } } diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/application.yml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/application.yml index 66b3ad5..722ad7e 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/application.yml +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/application.yml @@ -52,6 +52,7 @@ quartz-manager: enabled: true cookie: AUTH-TOKEN jobClass: it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob + jobClassPackages: it.fabioformosa.quartzmanager.jobs accounts: in-memory: enabled: true