From 0a718e897b477830b45bc2860607c8b2daac2f45 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sat, 27 Feb 2021 17:11:53 +0100 Subject: [PATCH 01/17] #35 fixes config retrieve --- .../quartzmanager/controllers/SchedulerController.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java index 1c054515..2bf81f92 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java @@ -65,12 +65,12 @@ private int fromTriggerPerDayToSecInterval(long triggerPerDay) { } @GetMapping("/config") - public SchedulerConfigParam getConfig() { + public SchedulerConfigParam getConfig() throws SchedulerException { log.debug("SCHEDULER - GET CONFIG params"); - SimpleTrigger simpleTrigger = (SimpleTrigger) triggerMonitor.getTrigger(); - int maxCount = simpleTrigger.getRepeatCount() + 1; - long triggersPerDay = fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval()); + SimpleTrigger jobTrigger = (SimpleTrigger) scheduler.getTrigger(triggerMonitor.getTrigger().getKey()); + int maxCount = jobTrigger.getRepeatCount() + 1; + long triggersPerDay = fromMillsIntervalToTriggerPerDay(jobTrigger.getRepeatInterval()); return new SchedulerConfigParam(triggersPerDay, maxCount); } From 6170e8f1aef73038d7df239bb079ca24e59717d9 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Fri, 5 Mar 2021 00:57:53 +0100 Subject: [PATCH 02/17] #38 changed misfire instruction --- .../quartzmanager/configuration/SchedulerConfig.java | 4 +++- .../controllers/SchedulerController.java | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java index cf906d56..bbbb69e4 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java @@ -30,6 +30,8 @@ @ConditionalOnProperty(name = "quartz.enabled") public class SchedulerConfig { + private static final int DEFAULT_MISFIRE_INSTRUCTION = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT; + private static JobDetailFactoryBean createJobDetail(Class jobClass) { JobDetailFactoryBean factoryBean = new JobDetailFactoryBean(); factoryBean.setJobClass(jobClass); @@ -45,7 +47,7 @@ private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long factoryBean.setRepeatInterval(pollFrequencyMs); factoryBean.setRepeatCount(repeatCount); factoryBean - .setMisfireInstruction(SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_EXISTING_COUNT);// in case of misfire, ignore all missed triggers and continue + .setMisfireInstruction(DEFAULT_MISFIRE_INSTRUCTION);// in case of misfire, ignore all missed triggers and continue return factoryBean; } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java index 2bf81f92..89427e67 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java @@ -122,8 +122,15 @@ public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) TriggerBuilder triggerBuilder = trigger.getTriggerBuilder(); int intervalInMills = fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); - Trigger newTrigger = triggerBuilder.withSchedule(SimpleScheduleBuilder.simpleSchedule() - .withIntervalInMilliseconds(intervalInMills).withRepeatCount(config.getMaxCount() - 1)).build(); + + Trigger newTrigger = triggerBuilder + .withSchedule( + SimpleScheduleBuilder.simpleSchedule() + .withIntervalInMilliseconds(intervalInMills) + .withRepeatCount(config.getMaxCount() - 1) + .withMisfireHandlingInstructionNextWithRemainingCount() + ) + .build(); scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger); triggerMonitor.setTrigger(newTrigger); From 03f45346a75ffad4efb9ec937fead849ede8190f Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Fri, 5 Mar 2021 00:59:02 +0100 Subject: [PATCH 03/17] #38 changed misfire instruction --- .../scheduler-config/scheduler-config.component.html | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html index 84fe4e72..b231607e 100644 --- a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html +++ b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html @@ -16,12 +16,11 @@
Misfire Policy
-
RESCHEDULE NEXT WITH EXISTING COUNT
+
RESCHEDULE NEXT WITH REMAINING COUNT
- In case of misfire event, the trigger is re-scheduled to the next scheduled time after 'now' with the repeat count left unchanged (missed events are definitively lost). + In case of misfire event, the trigger is re-scheduled to the next scheduled time after 'now' with the repeat count set to what it would be, if it had not missed any firings.
- Warning: This policy could cause the trigger to go directly to the complete state if the end-time of the trigger has arrived, - so this misfire instruction doesn't guarantee that the repeat counter reaches your max value, but it guarantees that the end-time doesn't go over the expected final fire time. + Warning: This policy could cause the Trigger to go directly to the 'COMPLETE' state if all fire-times where missed.
From 10df1116bda8f1d1d5965d181cbb21465d5f0045 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sat, 24 Jul 2021 19:44:24 +0200 Subject: [PATCH 04/17] #14 added a new module for persistence --- quartz-manager-parent/pom.xml | 12 + .../quartz-manager-common/pom.xml | 17 ++ .../properties/QuartzModuleProperties.java | 12 + .../quartz-manager-starter-api/pom.xml | 4 + .../configuration/SchedulerConfig.java | 11 +- .../pom.xml | 47 ++++ .../persistence/PersistenceConfig.java | 69 ++++++ .../main/resources/META-INF/spring.factories | 2 + .../liquibase-changelog-master.xml | 10 + ...V202102190034_quartz_tables_postgresql.sql | 218 ++++++++++++++++++ ...manager-application-persistence.properties | 20 ++ .../resources/quartz-persistence.properties | 10 + .../quartz-manager-web-showcase/pom.xml | 16 ++ .../src/main/resources/application.yml | 19 ++ .../db/liquibase-changelog-master.xml | 10 + .../V202102190034_quartz_tables.sql | 218 ++++++++++++++++++ .../src/main/resources/logback.xml | 2 +- .../src/main/resources/quartz.properties | 12 +- 18 files changed, 706 insertions(+), 3 deletions(-) create mode 100644 quartz-manager-parent/quartz-manager-common/pom.xml create mode 100644 quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/pom.xml create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/META-INF/spring.factories create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/liquibase-changelog-master.xml create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/migrations/V202102190034_quartz_tables_postgresql.sql create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties create mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml create mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql diff --git a/quartz-manager-parent/pom.xml b/quartz-manager-parent/pom.xml index 71013e5e..f6f20658 100644 --- a/quartz-manager-parent/pom.xml +++ b/quartz-manager-parent/pom.xml @@ -44,10 +44,17 @@ quartz-manager-starter-ui quartz-manager-starter-security quartz-manager-web-showcase + quartz-manager-starter-persistence + quartz-manager-common + + it.fabioformosa.quartz-manager + quartz-manager-common + 3.0.2-SNAPSHOT + it.fabioformosa.quartz-manager quartz-manager-starter-api @@ -58,6 +65,11 @@ quartz-manager-starter-security 3.0.2-SNAPSHOT + + it.fabioformosa.quartz-manager + quartz-manager-starter-persistence + 3.0.2-SNAPSHOT + it.fabioformosa.quartz-manager quartz-manager-starter-ui diff --git a/quartz-manager-parent/quartz-manager-common/pom.xml b/quartz-manager-parent/quartz-manager-common/pom.xml new file mode 100644 index 00000000..cb1510df --- /dev/null +++ b/quartz-manager-parent/quartz-manager-common/pom.xml @@ -0,0 +1,17 @@ + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 3.0.2-SNAPSHOT + + quartz-manager-common + + + + org.projectlombok + lombok + provided + + + \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java new file mode 100644 index 00000000..9140b82a --- /dev/null +++ b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java @@ -0,0 +1,12 @@ +package it.fabioformosa.quartzmanager.common.properties; + +import java.util.Properties; + +import lombok.Data; + +@Data +public class QuartzModuleProperties{ + + private Properties properties; + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/pom.xml b/quartz-manager-parent/quartz-manager-starter-api/pom.xml index a6af23e0..70d57b2e 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/pom.xml +++ b/quartz-manager-parent/quartz-manager-starter-api/pom.xml @@ -22,6 +22,10 @@ + + it.fabioformosa.quartz-manager + quartz-manager-common + org.springframework.boot diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java index bbbb69e4..3ce95d08 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java @@ -8,6 +8,7 @@ import org.quartz.SimpleTrigger; import org.quartz.Trigger; import org.quartz.spi.JobFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.PropertiesFactoryBean; @@ -21,6 +22,7 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; +import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; import it.fabioformosa.quartzmanager.scheduler.AutowiringSpringBeanJobFactory; import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor; import it.fabioformosa.quartzmanager.scheduler.TriggerMonitorImpl; @@ -54,6 +56,9 @@ private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long @Value("${quartz-manager.jobClass}") private String jobClassname; + @Autowired(required = false) + private QuartzModuleProperties quartzModuleProperties; + @Bean(name = "triggerMonitor") public TriggerMonitor createTriggerMonitor(@Qualifier("jobTrigger") Trigger trigger) { TriggerMonitor triggerMonitor = new TriggerMonitorImpl(); @@ -94,7 +99,11 @@ public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, @Qualifier("jobTrigger") Trigger sampleJobTrigger) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setJobFactory(jobFactory); - factory.setQuartzProperties(quartzProperties()); + Properties mergedProperties = new Properties(); + mergedProperties.putAll(quartzProperties()); + if(quartzModuleProperties != null) + mergedProperties.putAll(quartzModuleProperties.getProperties()); + factory.setQuartzProperties(mergedProperties); factory.setTriggers(sampleJobTrigger); factory.setAutoStartup(false); return factory; diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml b/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml new file mode 100644 index 00000000..4b25241e --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml @@ -0,0 +1,47 @@ + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 3.0.2-SNAPSHOT + + + quartz-manager-starter-persistence + + Quartz Manager Starter Security + Persist quartz jobs into a database + + https://github.com/fabioformosa/quartz-manager + + ${basedir}/../.. + UTF-8 + UTF-8 + 1.8 + + + + + it.fabioformosa.quartz-manager + quartz-manager-common + + + org.liquibase + liquibase-core + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.projectlombok + lombok + provided + + + + \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java new file mode 100644 index 00000000..86901838 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java @@ -0,0 +1,69 @@ +package it.fabioformosa.quartzmanager.persistence; + +import javax.sql.DataSource; + +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.PropertySource; + +import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; +import liquibase.integration.spring.SpringLiquibase; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +@Configuration +@PropertySource("classpath:quartz-manager-application-persistence.properties") +public class PersistenceConfig { + + @Data + public class PersistenceDatasourceProps { + private String url; + private String changeLog; + private String contexts; + private String user; + private String password; + } + + // @Data + // public class QuartzModuleProperties{ + // private Properties properties; + // } + + @Bean + public SpringLiquibase liquibase(PersistenceDatasourceProps persistenceDatasourceProps, DataSource quartzManagerDatasource) { + SpringLiquibase liquibase = new SpringLiquibase(); + liquibase.setContexts(persistenceDatasourceProps.getContexts()); + liquibase.setChangeLog(persistenceDatasourceProps.getChangeLog()); + liquibase.setDataSource(quartzManagerDatasource); + liquibase.setDropFirst(false); + return liquibase; + } + + @Bean + @ConfigurationProperties(prefix = "spring.liquibase") + public PersistenceDatasourceProps persistenceDatasourceProps() { + return new PersistenceDatasourceProps(); + } + + @Bean("quartzPersistenceProperties") + @ConfigurationProperties(prefix = "spring.quartz") + public QuartzModuleProperties persistenceQuartzProps() { + return new QuartzModuleProperties(); + } + + @Primary + @Bean + public DataSource quartzManagerDatasource(PersistenceDatasourceProps persistenceDatasourceProps) { + return DataSourceBuilder.create() + .url(persistenceDatasourceProps.getUrl()) + .driverClassName("org.postgresql.Driver") + .username(persistenceDatasourceProps.getUser()) + .password(persistenceDatasourceProps.getPassword()) + .build(); + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/META-INF/spring.factories b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/META-INF/spring.factories new file mode 100644 index 00000000..772bc91d --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/META-INF/spring.factories @@ -0,0 +1,2 @@ +org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ +it.fabioformosa.quartzmanager.persistence.PersistenceConfig \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/liquibase-changelog-master.xml b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/liquibase-changelog-master.xml new file mode 100644 index 00000000..ad7fc84b --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/liquibase-changelog-master.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/migrations/V202102190034_quartz_tables_postgresql.sql b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/migrations/V202102190034_quartz_tables_postgresql.sql new file mode 100644 index 00000000..1fc97540 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/db/quartz-scheduler/migrations/V202102190034_quartz_tables_postgresql.sql @@ -0,0 +1,218 @@ +--liquibase formatted sql + +/* https://github.com/quartz-scheduler/quartz/blob/master/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore/tables_postgres.sql */ + +--changeset V202102190034_01 (dbms:postgresql) +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +--changeset V202102190034_02 (dbms:postgresql) +CREATE TABLE QRTZ_JOB_DETAILS +( + SCHED_NAME VARCHAR(120) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + JOB_CLASS_NAME VARCHAR(250) NOT NULL, + IS_DURABLE BOOL NOT NULL, + IS_NONCONCURRENT BOOL NOT NULL, + IS_UPDATE_DATA BOOL NOT NULL, + REQUESTS_RECOVERY BOOL NOT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) +); + +--changeset V202102190034_03 (dbms:postgresql) +CREATE TABLE QRTZ_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + NEXT_FIRE_TIME BIGINT NULL, + PREV_FIRE_TIME BIGINT NULL, + PRIORITY INTEGER NULL, + TRIGGER_STATE VARCHAR(16) NOT NULL, + TRIGGER_TYPE VARCHAR(8) NOT NULL, + START_TIME BIGINT NOT NULL, + END_TIME BIGINT NULL, + CALENDAR_NAME VARCHAR(200) NULL, + MISFIRE_INSTR SMALLINT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP) +); + +--changeset V202102190034_04 (dbms:postgresql) +CREATE TABLE QRTZ_SIMPLE_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + REPEAT_COUNT BIGINT NOT NULL, + REPEAT_INTERVAL BIGINT NOT NULL, + TIMES_TRIGGERED BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_05 (dbms:postgresql) +CREATE TABLE QRTZ_CRON_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + CRON_EXPRESSION VARCHAR(120) NOT NULL, + TIME_ZONE_ID VARCHAR(80), + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_06 (dbms:postgresql) +CREATE TABLE QRTZ_SIMPROP_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13, 4) NULL, + DEC_PROP_2 NUMERIC(13, 4) NULL, + BOOL_PROP_1 BOOL NULL, + BOOL_PROP_2 BOOL NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_07 (dbms:postgresql) +CREATE TABLE QRTZ_BLOB_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + BLOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_08 (dbms:postgresql) +CREATE TABLE QRTZ_CALENDARS +( + SCHED_NAME VARCHAR(120) NOT NULL, + CALENDAR_NAME VARCHAR(200) NOT NULL, + CALENDAR BYTEA NOT NULL, + PRIMARY KEY (SCHED_NAME, CALENDAR_NAME) +); + +--changeset V202102190034_09 (dbms:postgresql) +CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_10 (dbms:postgresql) +CREATE TABLE QRTZ_FIRED_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + ENTRY_ID VARCHAR(95) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + FIRED_TIME BIGINT NOT NULL, + SCHED_TIME BIGINT NOT NULL, + PRIORITY INTEGER NOT NULL, + STATE VARCHAR(16) NOT NULL, + JOB_NAME VARCHAR(200) NULL, + JOB_GROUP VARCHAR(200) NULL, + IS_NONCONCURRENT BOOL NULL, + REQUESTS_RECOVERY BOOL NULL, + PRIMARY KEY (SCHED_NAME, ENTRY_ID) +); + +--changeset V202102190034_11 (dbms:postgresql) +CREATE TABLE QRTZ_SCHEDULER_STATE +( + SCHED_NAME VARCHAR(120) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + LAST_CHECKIN_TIME BIGINT NOT NULL, + CHECKIN_INTERVAL BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME, INSTANCE_NAME) +); + +--changeset V202102190034_12 (dbms:postgresql) +CREATE TABLE QRTZ_LOCKS +( + SCHED_NAME VARCHAR(120) NOT NULL, + LOCK_NAME VARCHAR(40) NOT NULL, + PRIMARY KEY (SCHED_NAME, LOCK_NAME) +); + +--changeset V202102190034_13 (dbms:postgresql) +CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY + ON QRTZ_JOB_DETAILS (SCHED_NAME, REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_J_GRP + ON QRTZ_JOB_DETAILS (SCHED_NAME, JOB_GROUP); + +CREATE INDEX IDX_QRTZ_T_J + ON QRTZ_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_JG + ON QRTZ_TRIGGERS (SCHED_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_C + ON QRTZ_TRIGGERS (SCHED_NAME, CALENDAR_NAME); +CREATE INDEX IDX_QRTZ_T_G + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_T_STATE + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_STATE + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_G_STATE + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME + ON QRTZ_TRIGGERS (SCHED_NAME, NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE, NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE + ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE + ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP + ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_GROUP, TRIGGER_STATE); + +CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME); +CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_FT_J_G + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_JG + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_T_G + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_FT_TG + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_GROUP); + + +COMMIT; diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties new file mode 100644 index 00000000..9edbfcfb --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties @@ -0,0 +1,20 @@ +spring.liquibase.url=jdbc:postgresql://localhost:5432/quartzmanager +spring.liquibase.change-log=classpath:db/quartz-scheduler/liquibase-changelog-master.xml +spring.liquibase.contexts=default +spring.liquibase.user=quartzmanager +spring.liquibase.password=quartzmanager +spring.quartz.job-store-type=jdbc +spring.quartz.initialize-schema=never +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.driver=org.postgresql.Driver +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.URL=jdbc:postgresql://localhost:5432/quartzmanager +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.user=quartzmanager +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.password=quartzmanager +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.maxConnections=5 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +spring.quartz.properties.org.quartz.jobStore.dataSource=quartzDataSource +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.provider=hikaricp +spring.quartz.properties.org.quartz.jobStore.misfireThreshold=1000 +# org.quartz.jobStore.isClustered=true +# org.quartz.scheduler.instanceId=AUTO \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties new file mode 100644 index 00000000..3e68aac0 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties @@ -0,0 +1,10 @@ +org.quartz.dataSource.quartzDataSource.driver = org.postgresql.Driver +org.quartz.dataSource.quartzDataSource.URL = jdbc:postgresql://localhost:5432/quartzmanager +org.quartz.dataSource.quartzDataSource.user quartzmanager +org.quartz.dataSource.quartzDataSource.password = quartzmanager +org.quartz.dataSource.quartzDataSource.maxConnections = 5 +org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX +org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +org.quartz.jobStore.dataSource = quartzDataSource +org.quartz.dataSource.quartzDataSource.provider=hikaricp +org.quartz.jobStore.misfireThreshold=1000 \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml index c3477584..e4787b0b 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -35,6 +35,10 @@ it.fabioformosa.quartz-manager quartz-manager-starter-security + + it.fabioformosa.quartz-manager + quartz-manager-starter-persistence + @@ -110,6 +114,18 @@ org.apache.commons commons-lang3 + + + + org.liquibase + liquibase-core + + + + org.postgresql + postgresql + + 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 c2115fa6..5d2e4abe 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 @@ -12,6 +12,24 @@ spring: cache: false mode: LEGACYHTML5 jpa.open-in-view: false +# liquibase: +# change-log: "classpath:db/liquibase-changelog-master.xml" +# contexts: default +# user: quartzmanager +# password: quartzmanager +# datasource: +# url: "jdbc:postgresql://localhost:5432/quartzmanager" +# username: quartzmanager +# password: quartzmanager + +# quartz: +# job-store-type: jdbc +# initialize-schema: never +# properties: +# org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate + +# org.quartz.jobStore.isClustered: true +# org.quartz.scheduler.instanceId=AUTO quartz: enabled: true @@ -26,6 +44,7 @@ logging: org.springframework.security: INFO org.springframework.boot.autoconfigure.security: INFO it.fabioformosa: DEBUG + org.quartz: DEBUG quartz-manager: security: diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml new file mode 100644 index 00000000..ad7fc84b --- /dev/null +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml @@ -0,0 +1,10 @@ + + + + + + diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql new file mode 100644 index 00000000..1fc97540 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql @@ -0,0 +1,218 @@ +--liquibase formatted sql + +/* https://github.com/quartz-scheduler/quartz/blob/master/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore/tables_postgres.sql */ + +--changeset V202102190034_01 (dbms:postgresql) +DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; +DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; +DROP TABLE IF EXISTS QRTZ_LOCKS; +DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_TRIGGERS; +DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; +DROP TABLE IF EXISTS QRTZ_CALENDARS; + +--changeset V202102190034_02 (dbms:postgresql) +CREATE TABLE QRTZ_JOB_DETAILS +( + SCHED_NAME VARCHAR(120) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + JOB_CLASS_NAME VARCHAR(250) NOT NULL, + IS_DURABLE BOOL NOT NULL, + IS_NONCONCURRENT BOOL NOT NULL, + IS_UPDATE_DATA BOOL NOT NULL, + REQUESTS_RECOVERY BOOL NOT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) +); + +--changeset V202102190034_03 (dbms:postgresql) +CREATE TABLE QRTZ_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + JOB_NAME VARCHAR(200) NOT NULL, + JOB_GROUP VARCHAR(200) NOT NULL, + DESCRIPTION VARCHAR(250) NULL, + NEXT_FIRE_TIME BIGINT NULL, + PREV_FIRE_TIME BIGINT NULL, + PRIORITY INTEGER NULL, + TRIGGER_STATE VARCHAR(16) NOT NULL, + TRIGGER_TYPE VARCHAR(8) NOT NULL, + START_TIME BIGINT NOT NULL, + END_TIME BIGINT NULL, + CALENDAR_NAME VARCHAR(200) NULL, + MISFIRE_INSTR SMALLINT NULL, + JOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) + REFERENCES QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP) +); + +--changeset V202102190034_04 (dbms:postgresql) +CREATE TABLE QRTZ_SIMPLE_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + REPEAT_COUNT BIGINT NOT NULL, + REPEAT_INTERVAL BIGINT NOT NULL, + TIMES_TRIGGERED BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_05 (dbms:postgresql) +CREATE TABLE QRTZ_CRON_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + CRON_EXPRESSION VARCHAR(120) NOT NULL, + TIME_ZONE_ID VARCHAR(80), + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_06 (dbms:postgresql) +CREATE TABLE QRTZ_SIMPROP_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + STR_PROP_1 VARCHAR(512) NULL, + STR_PROP_2 VARCHAR(512) NULL, + STR_PROP_3 VARCHAR(512) NULL, + INT_PROP_1 INT NULL, + INT_PROP_2 INT NULL, + LONG_PROP_1 BIGINT NULL, + LONG_PROP_2 BIGINT NULL, + DEC_PROP_1 NUMERIC(13, 4) NULL, + DEC_PROP_2 NUMERIC(13, 4) NULL, + BOOL_PROP_1 BOOL NULL, + BOOL_PROP_2 BOOL NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_07 (dbms:postgresql) +CREATE TABLE QRTZ_BLOB_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + BLOB_DATA BYTEA NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), + FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) + REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_08 (dbms:postgresql) +CREATE TABLE QRTZ_CALENDARS +( + SCHED_NAME VARCHAR(120) NOT NULL, + CALENDAR_NAME VARCHAR(200) NOT NULL, + CALENDAR BYTEA NOT NULL, + PRIMARY KEY (SCHED_NAME, CALENDAR_NAME) +); + +--changeset V202102190034_09 (dbms:postgresql) +CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS +( + SCHED_NAME VARCHAR(120) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP) +); + +--changeset V202102190034_10 (dbms:postgresql) +CREATE TABLE QRTZ_FIRED_TRIGGERS +( + SCHED_NAME VARCHAR(120) NOT NULL, + ENTRY_ID VARCHAR(95) NOT NULL, + TRIGGER_NAME VARCHAR(200) NOT NULL, + TRIGGER_GROUP VARCHAR(200) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + FIRED_TIME BIGINT NOT NULL, + SCHED_TIME BIGINT NOT NULL, + PRIORITY INTEGER NOT NULL, + STATE VARCHAR(16) NOT NULL, + JOB_NAME VARCHAR(200) NULL, + JOB_GROUP VARCHAR(200) NULL, + IS_NONCONCURRENT BOOL NULL, + REQUESTS_RECOVERY BOOL NULL, + PRIMARY KEY (SCHED_NAME, ENTRY_ID) +); + +--changeset V202102190034_11 (dbms:postgresql) +CREATE TABLE QRTZ_SCHEDULER_STATE +( + SCHED_NAME VARCHAR(120) NOT NULL, + INSTANCE_NAME VARCHAR(200) NOT NULL, + LAST_CHECKIN_TIME BIGINT NOT NULL, + CHECKIN_INTERVAL BIGINT NOT NULL, + PRIMARY KEY (SCHED_NAME, INSTANCE_NAME) +); + +--changeset V202102190034_12 (dbms:postgresql) +CREATE TABLE QRTZ_LOCKS +( + SCHED_NAME VARCHAR(120) NOT NULL, + LOCK_NAME VARCHAR(40) NOT NULL, + PRIMARY KEY (SCHED_NAME, LOCK_NAME) +); + +--changeset V202102190034_13 (dbms:postgresql) +CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY + ON QRTZ_JOB_DETAILS (SCHED_NAME, REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_J_GRP + ON QRTZ_JOB_DETAILS (SCHED_NAME, JOB_GROUP); + +CREATE INDEX IDX_QRTZ_T_J + ON QRTZ_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_JG + ON QRTZ_TRIGGERS (SCHED_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_T_C + ON QRTZ_TRIGGERS (SCHED_NAME, CALENDAR_NAME); +CREATE INDEX IDX_QRTZ_T_G + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_T_STATE + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_STATE + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_N_G_STATE + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME + ON QRTZ_TRIGGERS (SCHED_NAME, NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST + ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE, NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE + ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE + ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_STATE); +CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP + ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_GROUP, TRIGGER_STATE); + +CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME); +CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY); +CREATE INDEX IDX_QRTZ_FT_J_G + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_JG + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_GROUP); +CREATE INDEX IDX_QRTZ_FT_T_G + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP); +CREATE INDEX IDX_QRTZ_FT_TG + ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_GROUP); + + +COMMIT; diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml index 90577b11..413c274b 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml @@ -19,7 +19,7 @@ - + diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties index bf7cc50d..44b1da16 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties @@ -1,3 +1,13 @@ org.quartz.scheduler.instanceName=example org.quartz.scheduler.instanceId=AUTO -org.quartz.threadPool.threadCount=1 \ No newline at end of file +org.quartz.threadPool.threadCount=1 +#org.quartz.dataSource.quartzDataSource.driver = org.postgresql.Driver +#org.quartz.dataSource.quartzDataSource.URL = jdbc:postgresql://localhost:5432/quartzmanager +#org.quartz.dataSource.quartzDataSource.user quartzmanager +#org.quartz.dataSource.quartzDataSource.password = quartzmanager +#org.quartz.dataSource.quartzDataSource.maxConnections = 5 +#org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX +#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +#org.quartz.jobStore.dataSource = quartzDataSource +#org.quartz.dataSource.quartzDataSource.provider=hikaricp +#org.quartz.jobStore.misfireThreshold=1000 \ No newline at end of file From e50a48bd4c71b550643964a84c3e75bbb2b12414 Mon Sep 17 00:00:00 2001 From: "fabio.formosa" Date: Sun, 17 Oct 2021 13:15:54 +0200 Subject: [PATCH 05/17] Changed API and frontend to handle stored triggers and jobs --- quartz-manager-frontend/angular.json | 6 +- .../scheduler-config.component.html | 39 ++- .../scheduler-config.component.ts | 37 ++- .../src/app/model/scheduler.model.ts | 13 + .../src/app/model/schedulerConfig.model.ts | 16 +- .../src/app/model/triggerKey.model.ts | 9 + .../src/app/services/scheduler.service.ts | 14 +- .../app/views/manager/manager.component.html | 10 +- .../quartzmanager/common/utils/Try.java | 54 ++++ .../quartz-manager-starter-api/pom.xml | 263 +++++++++--------- .../aspects/WebSocketProgressNotifier.java | 21 +- .../configuration/ConversionConfig.java | 9 + .../configuration/SchedulerConfig.java | 46 ++- .../controllers/SchedulerController.java | 245 ++++++++-------- .../controllers/TriggerController.java | 72 +++++ .../converters/JobKeyToJobKeyDTO.java | 15 + .../converters/SchedulerToSchedulerDTO.java | 21 ++ .../converters/TriggerKeyToTriggerKeyDTO.java | 16 ++ .../converters/TriggerToTriggerDTO.java | 36 +++ .../quartzmanager/dto/JobKeyDTO.java | 22 ++ .../dto/SchedulerConfigParam.java | 42 +-- .../quartzmanager/dto/SchedulerDTO.java | 35 +++ .../quartzmanager/dto/TriggerDTO.java | 23 ++ .../quartzmanager/dto/TriggerKeyDTO.java | 22 ++ .../services/SchedulerService.java | 60 ++++ .../persistence/PersistenceConfig.java | 130 ++++----- .../src/main/resources/logback.xml | 5 +- 27 files changed, 857 insertions(+), 424 deletions(-) create mode 100644 quartz-manager-frontend/src/app/model/scheduler.model.ts create mode 100644 quartz-manager-frontend/src/app/model/triggerKey.model.ts create mode 100644 quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/Try.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/ConversionConfig.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/TriggerController.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/JobKeyToJobKeyDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/SchedulerToSchedulerDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerKeyToTriggerKeyDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerToTriggerDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java diff --git a/quartz-manager-frontend/angular.json b/quartz-manager-frontend/angular.json index 7ebabad4..481e9c6e 100644 --- a/quartz-manager-frontend/angular.json +++ b/quartz-manager-frontend/angular.json @@ -108,11 +108,11 @@ "defaultProject": "angular-spring-starter", "schematics": { "@schematics/angular:component": { - "prefix": "app", + "prefix": "qrzmng", "style": "css" }, "@schematics/angular:directive": { - "prefix": "app" + "prefix": "qrzmng" } } -} \ No newline at end of file +} diff --git a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html index b231607e..630519be 100644 --- a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html +++ b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html @@ -2,35 +2,56 @@ SCHEDULER CONFIG - + + + + + + + +
- - + + - + - +
Misfire Policy
RESCHEDULE NEXT WITH REMAINING COUNT
- In case of misfire event, the trigger is re-scheduled to the next scheduled time after 'now' with the repeat count set to what it would be, if it had not missed any firings. + In case of misfire event, the trigger is re-scheduled to the next scheduled time after 'now' with the repeat count set to what it would be, if it had not missed any firings.
- Warning: This policy could cause the Trigger to go directly to the 'COMPLETE' state if all fire-times where missed. + Warning: This policy could cause the Trigger to go directly to the 'COMPLETE' state if all fire-times where missed.
- +
+
diff --git a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts index 417cbe30..ea5cd31e 100644 --- a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts +++ b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts @@ -1,40 +1,65 @@ import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'; import { SchedulerService } from '../../services'; import { SchedulerConfig } from '../../model/schedulerConfig.model' +import {Scheduler} from '../../model/scheduler.model'; @Component({ - selector: 'scheduler-config', + selector: 'qrzmng-scheduler-config', templateUrl: './scheduler-config.component.html', styleUrls: ['./scheduler-config.component.scss'] }) export class SchedulerConfigComponent implements OnInit { + config: SchedulerConfig = new SchedulerConfig() + configBackup: SchedulerConfig = new SchedulerConfig() + scheduler: Scheduler; + + triggerLoading = true; + enabledTriggerForm = false; + private fetchedTriggers = false; + private triggerInProgress = false; + constructor( private schedulerService: SchedulerService ) { } - config : SchedulerConfig = new SchedulerConfig() - configBackup : SchedulerConfig = new SchedulerConfig() - ngOnInit() { - this.retrieveConfig() + this.triggerLoading = true; + this._getScheduler(); + this.retrieveConfig(); } retrieveConfig = () => { this.schedulerService.getConfig() .subscribe(res => { - this.config = new SchedulerConfig(res.triggerPerDay, res.maxCount) + this.config = new SchedulerConfig(res.triggerPerDay, res.maxCount, res.timesTriggered) this.configBackup = res + this.triggerLoading = false; + this.triggerInProgress = res.timesTriggered < res.maxCount; }) } + private _getScheduler() { + this.schedulerService.getScheduler() + .subscribe( res => { + this.scheduler = res; + this.fetchedTriggers = this.scheduler.triggerKeys.length > 0 + }) + } + + shouldShowTriggerConfig = (): boolean => this.fetchedTriggers && this.triggerInProgress; + submitConfig = () => { this.schedulerService.updateConfig(this.config) .subscribe(res => { this.configBackup = this.config; + this.enabledTriggerForm = false; + this.fetchedTriggers = true; + this.triggerInProgress = true; }, error => { this.config = this.configBackup; }); }; + enableTriggerForm = () => this.enabledTriggerForm = true; } diff --git a/quartz-manager-frontend/src/app/model/scheduler.model.ts b/quartz-manager-frontend/src/app/model/scheduler.model.ts new file mode 100644 index 00000000..adad75f8 --- /dev/null +++ b/quartz-manager-frontend/src/app/model/scheduler.model.ts @@ -0,0 +1,13 @@ +import {TriggerKey} from './triggerKey.model'; + +export class Scheduler { + name: string; + instanceId: string; + triggerKeys: TriggerKey[]; + + constructor(name: string, instanceId: string, triggerKeys: TriggerKey[]) { + this.name = name; + this.instanceId = instanceId; + this.triggerKeys = triggerKeys; + } +} diff --git a/quartz-manager-frontend/src/app/model/schedulerConfig.model.ts b/quartz-manager-frontend/src/app/model/schedulerConfig.model.ts index 591ad68e..35601cb9 100644 --- a/quartz-manager-frontend/src/app/model/schedulerConfig.model.ts +++ b/quartz-manager-frontend/src/app/model/schedulerConfig.model.ts @@ -1,11 +1,13 @@ export class SchedulerConfig { - triggerPerDay : number = 0 - maxCount : number = 0 + triggerPerDay = 0; + maxCount = 0; + timesTriggered = 0; - constructor(triggerPerDay = 0, maxCount = 0) { - this.triggerPerDay = triggerPerDay - this.maxCount = maxCount + constructor(triggerPerDay = 0, maxCount = 0, timesTriggered = 0) { + this.triggerPerDay = triggerPerDay; + this.maxCount = maxCount; + this.timesTriggered = timesTriggered; } - - } \ No newline at end of file + + } diff --git a/quartz-manager-frontend/src/app/model/triggerKey.model.ts b/quartz-manager-frontend/src/app/model/triggerKey.model.ts new file mode 100644 index 00000000..5c3e156a --- /dev/null +++ b/quartz-manager-frontend/src/app/model/triggerKey.model.ts @@ -0,0 +1,9 @@ +export class TriggerKey { + name: string; + group: string; + + constructor(name: string, group: string) { + this.name = name; + this.group = group; + } +} diff --git a/quartz-manager-frontend/src/app/services/scheduler.service.ts b/quartz-manager-frontend/src/app/services/scheduler.service.ts index a4b4251e..930df9f8 100644 --- a/quartz-manager-frontend/src/app/services/scheduler.service.ts +++ b/quartz-manager-frontend/src/app/services/scheduler.service.ts @@ -12,20 +12,24 @@ export class SchedulerService { startScheduler = () => { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/run') } - + stopScheduler = () => { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/stop') } - + pauseScheduler = () => { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/pause') } - + resumeScheduler = () => { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/resume') } getStatus = () => { + return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/status') + } + + getScheduler = () => { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler') } @@ -34,6 +38,8 @@ export class SchedulerService { } updateConfig = (config: Object) => { - return this.apiService.post(getBaseUrl() + '/quartz-manager/scheduler/config', config) + return this.apiService.post(getBaseUrl() + '/quartz-manager/triggers/mytrigger', config) } + + } diff --git a/quartz-manager-frontend/src/app/views/manager/manager.component.html b/quartz-manager-frontend/src/app/views/manager/manager.component.html index 4375ae42..ac239e1a 100644 --- a/quartz-manager-frontend/src/app/views/manager/manager.component.html +++ b/quartz-manager-frontend/src/app/views/manager/manager.component.html @@ -4,16 +4,16 @@

- +
- - + +

-
- + + diff --git a/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/Try.java b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/Try.java new file mode 100644 index 00000000..67145d85 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/Try.java @@ -0,0 +1,54 @@ +package it.fabioformosa.quartzmanager.common.utils; + +import java.util.function.Function; + +public class Try { + + private final Throwable failure; + private final R success; + + public Try(Throwable failure, R success) { + this.failure = failure; + this.success = success; + } + + public R getSuccess() { + return success; + } + + public static Try success(R r){ + return new Try<>(null, r); + } + + public static Try failure(Throwable e){ + return new Try<>(e, null); + } + + public static Function> with(CheckedFunction checkedFunction){ + return t -> { + try { + return Try.success(checkedFunction.apply(t)); + } catch (java.lang.Exception e) { + return Try.failure(e); + } + }; + } + + public static Function sneakyThrow(CheckedFunction checkedFunction){ + return t -> Try.with(checkedFunction).apply(t).getSuccess(); + } + + public boolean isSuccess(){ + return this.failure == null; + } + + public boolean isFailure(){ + return this.failure != null; + } + + @FunctionalInterface + public static interface CheckedFunction { + R apply(T t) throws java.lang.Exception; + } +} + diff --git a/quartz-manager-parent/quartz-manager-starter-api/pom.xml b/quartz-manager-parent/quartz-manager-starter-api/pom.xml index 70d57b2e..512eee22 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/pom.xml +++ b/quartz-manager-parent/quartz-manager-starter-api/pom.xml @@ -1,128 +1,135 @@ - - - 4.0.0 - - it.fabioformosa.quartz-manager - quartz-manager-parent - 3.0.2-SNAPSHOT - - - quartz-manager-starter-api - - Quartz Manager Starter API - REST API layer for your scheduler and triggered jobs, to be included in your spring webapp - - https://github.com/fabioformosa/quartz-manager - - ${basedir}/../.. - UTF-8 - UTF-8 - 2.9.2 - 1.8 - - - - - it.fabioformosa.quartz-manager - quartz-manager-common - - - - org.springframework.boot - spring-boot-starter - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-devtools - - - org.springframework.boot - spring-boot-starter-websocket - - - org.springframework.security - spring-security-core - - - org.springframework.boot - spring-boot-starter-test - test - - - - - com.fasterxml.jackson.core - jackson-annotations - - - com.h2database - h2 - runtime - - - org.projectlombok - lombok - provided - - - org.apache.commons - commons-lang3 - - - - - org.quartz-scheduler - quartz - - - org.apache.commons - commons-io - 1.3.2 - - - - - io.projectreactor - reactor-core - - - io.projectreactor - reactor-net - 2.0.8.RELEASE - - - io.projectreactor.spring - reactor-spring-context - 2.0.7.RELEASE - - - io.netty - netty-all - - - org.springframework.boot - spring-boot-starter-aop - - - org.yaml - snakeyaml - - - - - io.springfox - springfox-swagger2 - ${springfox.version} - - - io.springfox - springfox-swagger-ui - ${springfox.version} - - - - + + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 3.0.2-SNAPSHOT + + + quartz-manager-starter-api + + Quartz Manager Starter API + REST API layer for your scheduler and triggered jobs, to be included in your spring webapp + + https://github.com/fabioformosa/quartz-manager + + ${basedir}/../.. + UTF-8 + UTF-8 + 2.9.2 + 1.8 + + + + + it.fabioformosa.quartz-manager + quartz-manager-common + + + + + org.springframework.boot + spring-boot-starter + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-starter-websocket + + + org.springframework.security + spring-security-core + + + org.springframework.boot + spring-boot-starter-test + test + + + + + com.fasterxml.jackson.core + jackson-annotations + + + com.h2database + h2 + runtime + + + org.projectlombok + lombok + provided + + + org.apache.commons + commons-lang3 + + + it.fabioformosa + metamorphosis-core + 3.0.0 + + + + + + org.quartz-scheduler + quartz + + + org.apache.commons + commons-io + 1.3.2 + + + + + io.projectreactor + reactor-core + + + io.projectreactor + reactor-net + 2.0.8.RELEASE + + + io.projectreactor.spring + reactor-spring-context + 2.0.7.RELEASE + + + io.netty + netty-all + + + org.springframework.boot + spring-boot-starter-aop + + + org.yaml + snakeyaml + + + + + io.springfox + springfox-swagger2 + ${springfox.version} + + + io.springfox + springfox-swagger-ui + ${springfox.version} + + + + diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/aspects/WebSocketProgressNotifier.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/aspects/WebSocketProgressNotifier.java index 74e550b3..b0ac383e 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/aspects/WebSocketProgressNotifier.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/aspects/WebSocketProgressNotifier.java @@ -1,9 +1,8 @@ package it.fabioformosa.quartzmanager.aspects; -import javax.annotation.Resource; - +import it.fabioformosa.quartzmanager.dto.TriggerStatus; +import it.fabioformosa.quartzmanager.services.SchedulerService; import org.quartz.DailyTimeIntervalTrigger; -import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.SimpleTrigger; import org.quartz.Trigger; @@ -11,8 +10,7 @@ import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.stereotype.Component; -import it.fabioformosa.quartzmanager.dto.TriggerStatus; -import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor; +import javax.annotation.Resource; /** * @@ -28,11 +26,14 @@ public class WebSocketProgressNotifier implements ProgressNotifier { @Autowired private SimpMessageSendingOperations messagingTemplate; - @Resource - private Scheduler scheduler; +// @Resource +// private Scheduler scheduler; @Resource - private TriggerMonitor triggerMonitor; + private SchedulerService schedulerService; + +// @Resource +// private TriggerMonitor triggerMonitor; //@AfterReturning("execution(* logAndSend(..))") // @Override @@ -44,7 +45,7 @@ public class WebSocketProgressNotifier implements ProgressNotifier { public void send() throws SchedulerException { TriggerStatus currTriggerStatus = new TriggerStatus(); - Trigger trigger = scheduler.getTrigger(triggerMonitor.getTrigger().getKey()); + Trigger trigger = schedulerService.getOneSimpleTrigger().get(); currTriggerStatus.setFinalFireTime(trigger.getFinalFireTime()); currTriggerStatus.setNextFireTime(trigger.getNextFireTime()); currTriggerStatus.setPreviousFireTime(trigger.getPreviousFireTime()); @@ -62,7 +63,7 @@ public void send() throws SchedulerException { repeatCount = dailyTrigger.getRepeatCount(); } - Trigger jobTrigger = triggerMonitor.getTrigger(); + Trigger jobTrigger = schedulerService.getOneSimpleTrigger().get(); if (jobTrigger != null && jobTrigger.getJobKey() != null) { currTriggerStatus.setJobKey(jobTrigger.getJobKey().getName()); currTriggerStatus.setJobClass(jobTrigger.getClass().getSimpleName()); diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/ConversionConfig.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/ConversionConfig.java new file mode 100644 index 00000000..964a723b --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/ConversionConfig.java @@ -0,0 +1,9 @@ +package it.fabioformosa.quartzmanager.configuration; + +import it.fabioformosa.metamorphosis.core.EnableMetamorphosisConversions; +import org.springframework.context.annotation.Configuration; + +@Configuration +@EnableMetamorphosisConversions(basePackages = { "it.fabioformosa.quartzmanager" }) +public class ConversionConfig { +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java index 3ce95d08..7701a35a 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java @@ -1,15 +1,12 @@ package it.fabioformosa.quartzmanager.configuration; -import java.io.IOException; -import java.util.Properties; - +import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; +import it.fabioformosa.quartzmanager.scheduler.AutowiringSpringBeanJobFactory; import org.quartz.Job; import org.quartz.JobDetail; import org.quartz.SimpleTrigger; -import org.quartz.Trigger; import org.quartz.spi.JobFactory; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.config.PropertiesFactoryBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; @@ -22,10 +19,8 @@ import org.springframework.scheduling.quartz.SchedulerFactoryBean; import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; -import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; -import it.fabioformosa.quartzmanager.scheduler.AutowiringSpringBeanJobFactory; -import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor; -import it.fabioformosa.quartzmanager.scheduler.TriggerMonitorImpl; +import java.io.IOException; +import java.util.Properties; @ComponentScan(basePackages = {"it.fabioformosa.quartzmanager.controllers"}) @Configuration @@ -59,12 +54,14 @@ private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long @Autowired(required = false) private QuartzModuleProperties quartzModuleProperties; - @Bean(name = "triggerMonitor") - public TriggerMonitor createTriggerMonitor(@Qualifier("jobTrigger") Trigger trigger) { - TriggerMonitor triggerMonitor = new TriggerMonitorImpl(); - triggerMonitor.setTrigger(trigger); - return triggerMonitor; - } + + // REMOVEME +// @Bean(name = "triggerMonitor") +// public TriggerMonitor createTriggerMonitor(@Qualifier("jobTrigger") Trigger trigger) { +// TriggerMonitor triggerMonitor = new TriggerMonitorImpl(); +// triggerMonitor.setTrigger(trigger); +// return triggerMonitor; +// } @Bean @SuppressWarnings("unchecked") @@ -88,15 +85,16 @@ public Properties quartzProperties() throws IOException { return propertiesFactoryBean.getObject(); } - @Bean(name = "jobTrigger") - public SimpleTriggerFactoryBean sampleJobTrigger(@Qualifier("jobDetail") JobDetail jobDetail, - @Value("${job.frequency}") long frequency, @Value("${job.repeatCount}") int repeatCount) { - return createTrigger(jobDetail, frequency, repeatCount); - } +// @Bean(name = "jobTrigger") +// public SimpleTriggerFactoryBean sampleJobTrigger(@Qualifier("jobDetail") JobDetail jobDetail, +// @Value("${job.frequency}") long frequency, @Value("${job.repeatCount}") int repeatCount) { +// return createTrigger(jobDetail, frequency, repeatCount); +// } @Bean(name = "scheduler") - public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, - @Qualifier("jobTrigger") Trigger sampleJobTrigger) throws IOException { + public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException { +// public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, +// @Qualifier("jobTrigger") Trigger sampleJobTrigger) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setJobFactory(jobFactory); Properties mergedProperties = new Properties(); @@ -104,8 +102,8 @@ public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, if(quartzModuleProperties != null) mergedProperties.putAll(quartzModuleProperties.getProperties()); factory.setQuartzProperties(mergedProperties); - factory.setTriggers(sampleJobTrigger); + //factory.setTriggers(sampleJobTrigger); factory.setAutoStartup(false); return factory; } -} \ No newline at end of file +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java index 89427e67..ca554ba5 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java @@ -1,161 +1,158 @@ package it.fabioformosa.quartzmanager.controllers; -import java.util.Collections; -import java.util.Map; - -import javax.annotation.Resource; - -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.SimpleScheduleBuilder; -import org.quartz.SimpleTrigger; -import org.quartz.Trigger; -import org.quartz.TriggerBuilder; +import io.swagger.annotations.Api; +import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; +import it.fabioformosa.quartzmanager.dto.SchedulerDTO; +import it.fabioformosa.quartzmanager.dto.TriggerStatus; +import it.fabioformosa.quartzmanager.enums.SchedulerStates; +import it.fabioformosa.quartzmanager.services.SchedulerService; +import org.quartz.*; import org.quartz.impl.triggers.SimpleTriggerImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.springframework.core.convert.ConversionService; import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; -import io.swagger.annotations.Api; -import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; -import it.fabioformosa.quartzmanager.dto.TriggerStatus; -import it.fabioformosa.quartzmanager.enums.SchedulerStates; -import it.fabioformosa.quartzmanager.scheduler.TriggerMonitor; +import javax.annotation.Resource; +import java.util.Collections; +import java.util.Map; /** * This controller provides scheduler info about config and status. It provides * also methods to set new config and start/stop/resume the scheduler. * * @author Fabio.Formosa - * */ @RestController @RequestMapping("/quartz-manager/scheduler") @Api(value = "scheduler") public class SchedulerController { - private static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24; - private static final int SEC_IN_A_DAY = 60 * 60 * 24; - - private final Logger log = LoggerFactory.getLogger(SchedulerController.class); - - @Resource - private Scheduler scheduler; - - @Resource - private TriggerMonitor triggerMonitor; - - private long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) { - return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills); - } - - private int fromTriggerPerDayToMillsInterval(long triggerPerDay) { - return (int) Math.ceil(Long.valueOf(MILLS_IN_A_DAY) / triggerPerDay); // with ceil the triggerPerDay is a max value - } + private final Logger log = LoggerFactory.getLogger(SchedulerController.class); - @SuppressWarnings("unused") - private int fromTriggerPerDayToSecInterval(long triggerPerDay) { - return (int) Math.ceil(Long.valueOf(SEC_IN_A_DAY) / triggerPerDay); - } + private SchedulerService schedulerService; - @GetMapping("/config") - public SchedulerConfigParam getConfig() throws SchedulerException { - log.debug("SCHEDULER - GET CONFIG params"); + public SchedulerController(SchedulerService schedulerService, ConversionService conversionService) { + this.schedulerService = schedulerService; + this.conversionService = conversionService; + } - SimpleTrigger jobTrigger = (SimpleTrigger) scheduler.getTrigger(triggerMonitor.getTrigger().getKey()); - int maxCount = jobTrigger.getRepeatCount() + 1; - long triggersPerDay = fromMillsIntervalToTriggerPerDay(jobTrigger.getRepeatInterval()); + // @Resource +// private Scheduler scheduler; - return new SchedulerConfigParam(triggersPerDay, maxCount); - } + //TODO REMOVEME +// @Resource +// private TriggerMonitor triggerMonitor; - @GetMapping("/progress") - public TriggerStatus getProgressInfo() throws SchedulerException { - log.trace("SCHEDULER - GET PROGRESS INFO"); - TriggerStatus progress = new TriggerStatus(); - - SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) scheduler.getTrigger(triggerMonitor.getTrigger().getKey()); - if (jobTrigger != null && jobTrigger.getJobKey() != null) { - progress.setJobKey(jobTrigger.getJobKey().getName()); - progress.setJobClass(jobTrigger.getClass().getSimpleName()); - progress.setTimesTriggered(jobTrigger.getTimesTriggered()); - progress.setRepeatCount(jobTrigger.getRepeatCount()); - progress.setFinalFireTime(jobTrigger.getFinalFireTime()); - progress.setNextFireTime(jobTrigger.getNextFireTime()); - progress.setPreviousFireTime(jobTrigger.getPreviousFireTime()); - } - - return progress; - } + @Resource + private ConversionService conversionService; - @GetMapping(produces = "application/json") - public Map getStatus() throws SchedulerException { - log.trace("SCHEDULER - GET STATUS"); - String schedulerState = ""; - if (scheduler.isShutdown() || !scheduler.isStarted()) - schedulerState = SchedulerStates.STOPPED.toString(); - else if (scheduler.isStarted() && scheduler.isInStandbyMode()) - schedulerState = SchedulerStates.PAUSED.toString(); - else - schedulerState = SchedulerStates.RUNNING.toString(); - return Collections.singletonMap("data", schedulerState.toLowerCase()); - } + @GetMapping("/config") + public SchedulerConfigParam getConfig() throws SchedulerException { + log.debug("SCHEDULER - GET CONFIG params"); - @GetMapping("/pause") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void pause() throws SchedulerException { - log.info("SCHEDULER - PAUSE COMMAND"); - scheduler.standby(); - } + SchedulerConfigParam schedulerConfigParam = schedulerService.getOneSimpleTrigger() + .map(SchedulerController::fromSimpleTriggerToSchedulerConfigParam) + .orElse(new SchedulerConfigParam(0, 0, 0)); - @PostMapping("/config") - public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException { - log.info("SCHEDULER - NEW CONFIG {}", config); - SimpleTrigger trigger = (SimpleTrigger) triggerMonitor.getTrigger(); + return schedulerConfigParam; + } - TriggerBuilder triggerBuilder = trigger.getTriggerBuilder(); + public static SchedulerConfigParam fromSimpleTriggerToSchedulerConfigParam(SimpleTrigger simpleTrigger){ + int timesTriggered = simpleTrigger.getTimesTriggered(); + int maxCount = simpleTrigger.getRepeatCount() + 1; + long triggersPerDay = SchedulerService.fromMillsIntervalToTriggerPerDay(simpleTrigger.getRepeatInterval()); + return new SchedulerConfigParam(triggersPerDay, maxCount, timesTriggered); + } - int intervalInMills = fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); - Trigger newTrigger = triggerBuilder - .withSchedule( - SimpleScheduleBuilder.simpleSchedule() - .withIntervalInMilliseconds(intervalInMills) - .withRepeatCount(config.getMaxCount() - 1) - .withMisfireHandlingInstructionNextWithRemainingCount() - ) - .build(); - scheduler.rescheduleJob(triggerMonitor.getTrigger().getKey(), newTrigger); - triggerMonitor.setTrigger(newTrigger); - return config; - } + @GetMapping + public SchedulerDTO getScheduler() { + log.debug("SCHEDULER - GET Scheduler..."); + SchedulerDTO schedulerDTO = conversionService.convert(schedulerService.getScheduler(), SchedulerDTO.class); + return schedulerDTO; + } - @GetMapping("/resume") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void resume() throws SchedulerException { - log.info("SCHEDULER - RESUME COMMAND"); - scheduler.start(); - } + @GetMapping("/progress") + public TriggerStatus getProgressInfo() throws SchedulerException { + log.trace("SCHEDULER - GET PROGRESS INFO"); + TriggerStatus progress = new TriggerStatus(); - @GetMapping("/run") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void run() throws SchedulerException { - log.info("SCHEDULER - START COMMAND"); - scheduler.start(); + SimpleTriggerImpl jobTrigger = (SimpleTriggerImpl) schedulerService.getOneSimpleTrigger().get(); + if (jobTrigger != null && jobTrigger.getJobKey() != null) { + progress.setJobKey(jobTrigger.getJobKey().getName()); + progress.setJobClass(jobTrigger.getClass().getSimpleName()); + progress.setTimesTriggered(jobTrigger.getTimesTriggered()); + progress.setRepeatCount(jobTrigger.getRepeatCount()); + progress.setFinalFireTime(jobTrigger.getFinalFireTime()); + progress.setNextFireTime(jobTrigger.getNextFireTime()); + progress.setPreviousFireTime(jobTrigger.getPreviousFireTime()); } - @GetMapping("/stop") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void stop() throws SchedulerException { - log.info("SCHEDULER - STOP COMMAND"); - scheduler.shutdown(true); - } + return progress; + } + + @GetMapping(value = "/status", produces = "application/json") + public Map getStatus() throws SchedulerException { + log.trace("SCHEDULER - GET STATUS"); + String schedulerState = ""; + if (schedulerService.getScheduler().isShutdown() || !schedulerService.getScheduler().isStarted()) + schedulerState = SchedulerStates.STOPPED.toString(); + else if (schedulerService.getScheduler().isStarted() && schedulerService.getScheduler().isInStandbyMode()) + schedulerState = SchedulerStates.PAUSED.toString(); + else + schedulerState = SchedulerStates.RUNNING.toString(); + return Collections.singletonMap("data", schedulerState.toLowerCase()); + } + + @GetMapping("/pause") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void pause() throws SchedulerException { + log.info("SCHEDULER - PAUSE COMMAND"); + schedulerService.getScheduler().standby(); + } + +// @PostMapping("/config") +// public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException { +// log.info("SCHEDULER - NEW CONFIG {}", config); +// +// int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); +// +// Trigger newTrigger = TriggerBuilder.newTrigger() +// .withSchedule( +// SimpleScheduleBuilder.simpleSchedule() +// .withIntervalInMilliseconds(intervalInMills) +// .withRepeatCount(config.getMaxCount() - 1) +// .withMisfireHandlingInstructionNextWithRemainingCount() +// ) +// .build(); +// +// schedulerService.getScheduler().rescheduleJob(schedulerService.getOneTriggerKey().get(), newTrigger); +//// triggerMonitor.setTrigger(newTrigger); REMOVEME +// return config; +// } + + @GetMapping("/resume") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void resume() throws SchedulerException { + log.info("SCHEDULER - RESUME COMMAND"); + schedulerService.getScheduler().start(); + } + + @GetMapping("/run") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void run() throws SchedulerException { + log.info("SCHEDULER - START COMMAND"); + schedulerService.getScheduler().start(); + } + + @GetMapping("/stop") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void stop() throws SchedulerException { + log.info("SCHEDULER - STOP COMMAND"); + schedulerService.getScheduler().shutdown(true); + } } 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 new file mode 100644 index 00000000..f3d8be31 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/TriggerController.java @@ -0,0 +1,72 @@ +package it.fabioformosa.quartzmanager.controllers; + +import io.swagger.annotations.Api; +import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import it.fabioformosa.quartzmanager.services.SchedulerService; +import lombok.extern.slf4j.Slf4j; +import org.quartz.*; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.convert.ConversionService; +import org.springframework.web.bind.annotation.*; + +@Slf4j +@RequestMapping("/quartz-manager/triggers") +@RestController +@Api(value = "triggers") +public class TriggerController { + + @Value("${quartz-manager.jobClass}") + private String jobClassname; + + private Scheduler scheduler; + private SchedulerService schedulerService; + private ConversionService conversionService; + + public TriggerController(Scheduler scheduler, SchedulerService schedulerService, ConversionService conversionService) { + this.scheduler = scheduler; + this.schedulerService = schedulerService; + this.conversionService = conversionService; + } + + @GetMapping("/{name}") + public TriggerDTO getTrigger(@PathVariable String name) throws SchedulerException { + Trigger trigger = scheduler.getTrigger(new TriggerKey(name)); + TriggerDTO triggerDTO = conversionService.convert(trigger, TriggerDTO.class); + return triggerDTO; + } + + @PostMapping("/{name}") + public TriggerDTO postTrigger(@PathVariable String name, @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { + log.info("TRIGGER - POST trigger {}", config); + int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); + + Class jobClass = (Class) Class.forName(jobClassname); + JobDetail jobDetail = JobBuilder.newJob() + .ofType(jobClass) + .storeDurably(false) + .build(); + + Trigger newTrigger = TriggerBuilder.newTrigger() + .withSchedule( + SimpleScheduleBuilder.simpleSchedule() + .withIntervalInMilliseconds(intervalInMills) + .withRepeatCount(config.getMaxCount() - 1) + .withMisfireHandlingInstructionNextWithRemainingCount() + ) + .build(); + +// Optional optionalTriggerKey = schedulerService.getTriggerByKey(name); +// TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name)); + + scheduler.scheduleJob(jobDetail, newTrigger); +// scheduler.rescheduleJob(triggerKey, newTrigger); + + TriggerDTO newTriggerDTO = conversionService.convert(newTrigger, TriggerDTO.class); + + log.info("Rescheduled new trigger {}", newTriggerDTO); + return newTriggerDTO; + } + + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/JobKeyToJobKeyDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/JobKeyToJobKeyDTO.java new file mode 100644 index 00000000..8bfd4855 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/JobKeyToJobKeyDTO.java @@ -0,0 +1,15 @@ +package it.fabioformosa.quartzmanager.converters; + +import it.fabioformosa.metamorphosis.core.converters.AbstractBaseConverterToDTO; +import it.fabioformosa.quartzmanager.dto.JobKeyDTO; +import org.quartz.JobKey; +import org.springframework.stereotype.Component; + +@Component +public class JobKeyToJobKeyDTO extends AbstractBaseConverterToDTO { + @Override + protected void convert(JobKey source, JobKeyDTO target) { + target.setName(source.getName()); + target.setGroup(source.getGroup()); + } +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/SchedulerToSchedulerDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/SchedulerToSchedulerDTO.java new file mode 100644 index 00000000..fcc01a7f --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/SchedulerToSchedulerDTO.java @@ -0,0 +1,21 @@ +package it.fabioformosa.quartzmanager.converters; + +import it.fabioformosa.metamorphosis.core.converters.AbstractBaseConverterToDTO; +import it.fabioformosa.quartzmanager.dto.SchedulerDTO; +import lombok.SneakyThrows; +import org.quartz.Scheduler; +import org.quartz.impl.matchers.GroupMatcher; +import org.springframework.stereotype.Component; + +@Component +public class SchedulerToSchedulerDTO extends AbstractBaseConverterToDTO { + + @SneakyThrows + @Override + protected void convert(Scheduler source, SchedulerDTO target) { + target.setName(source.getSchedulerName()); + target.setInstanceId(source.getSchedulerInstanceId()); + target.setTriggerKeys(source.getTriggerKeys(GroupMatcher.anyTriggerGroup())); + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerKeyToTriggerKeyDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerKeyToTriggerKeyDTO.java new file mode 100644 index 00000000..ec5e01eb --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerKeyToTriggerKeyDTO.java @@ -0,0 +1,16 @@ +package it.fabioformosa.quartzmanager.converters; + +import it.fabioformosa.metamorphosis.core.converters.AbstractBaseConverterToDTO; +import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO; +import org.quartz.TriggerKey; +import org.springframework.stereotype.Component; + +@Component +public class TriggerKeyToTriggerKeyDTO extends AbstractBaseConverterToDTO { + + @Override + protected void convert(TriggerKey source, TriggerKeyDTO target) { + target.setName(source.getName()); + target.setGroup(source.getGroup()); + } +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerToTriggerDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerToTriggerDTO.java new file mode 100644 index 00000000..479be884 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/converters/TriggerToTriggerDTO.java @@ -0,0 +1,36 @@ +package it.fabioformosa.quartzmanager.converters; + +import it.fabioformosa.metamorphosis.core.converters.AbstractBaseConverterToDTO; +import it.fabioformosa.quartzmanager.dto.JobKeyDTO; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO; +import org.quartz.JobKey; +import org.quartz.Trigger; +import org.quartz.TriggerKey; +import org.springframework.stereotype.Component; + +@Component +public class TriggerToTriggerDTO extends AbstractBaseConverterToDTO { + + @Override + protected void convert(Trigger source, TriggerDTO target) { + TriggerKey triggerKey = source.getKey(); + TriggerKeyDTO triggerKeyDTO = conversionService.convert(triggerKey, TriggerKeyDTO.class); + target.setTriggerKeyDTO(triggerKeyDTO); + + target.setStartTime(source.getStartTime()); + target.setDescription(source.getDescription()); + target.setEndTime(source.getEndTime()); + target.setFinalFireTime(source.getFinalFireTime()); + target.setMisfireInstruction(source.getMisfireInstruction()); + target.setNextFireTime(source.getNextFireTime()); + target.setPriority(source.getPriority()); + target.setMayFireAgain(source.mayFireAgain()); + + JobKey jobKey = source.getJobKey(); + JobKeyDTO jobKeyDTO = conversionService.convert(jobKey, JobKeyDTO.class); + target.setJobKeyDTO(jobKeyDTO); + + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java new file mode 100644 index 00000000..1a9bfc3a --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java @@ -0,0 +1,22 @@ +package it.fabioformosa.quartzmanager.dto; + +public class JobKeyDTO { + private String name; + private String group; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getGroup() { + return group; + } +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java index 8caf0d13..60026ae1 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java @@ -1,40 +1,14 @@ package it.fabioformosa.quartzmanager.dto; -public class SchedulerConfigParam { +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +@NoArgsConstructor +@AllArgsConstructor +@Data +public class SchedulerConfigParam { public long triggerPerDay; public int maxCount; - - public SchedulerConfigParam() { - super(); - } - - public SchedulerConfigParam(long triggerPerDay, int maxCount) { - super(); - this.triggerPerDay = triggerPerDay; - this.maxCount = maxCount; - } - - public int getMaxCount() { - return maxCount; - } - - public long getTriggerPerDay() { - return triggerPerDay; - } - - public void setMaxCount(int maxCount) { - this.maxCount = maxCount; - } - - public void setTriggerPerDay(long triggerPerDay) { - this.triggerPerDay = triggerPerDay; - } - - @Override - public String toString() { - return "SchedulerConfigParam [triggerPerDay=" + triggerPerDay - + ", maxCount=" + maxCount + "]"; - } - + public int timesTriggered; } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerDTO.java new file mode 100644 index 00000000..7dca3478 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerDTO.java @@ -0,0 +1,35 @@ +package it.fabioformosa.quartzmanager.dto; + +import org.quartz.TriggerKey; + +import java.util.Set; + +public class SchedulerDTO { + private String name; + private String instanceId; + private Set triggerKeys; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setInstanceId(String instanceId) { + this.instanceId = instanceId; + } + + public String getInstanceId() { + return instanceId; + } + + public void setTriggerKeys(Set triggerKeys) { + this.triggerKeys = triggerKeys; + } + + public Set getTriggerKeys() { + return triggerKeys; + } +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java new file mode 100644 index 00000000..ff41c222 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java @@ -0,0 +1,23 @@ +package it.fabioformosa.quartzmanager.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +@AllArgsConstructor +@NoArgsConstructor +@Data +public class TriggerDTO { + private TriggerKeyDTO triggerKeyDTO; + private int priority; + private Date startTime; + private String description; + private Date endTime; + private Date finalFireTime; + private int misfireInstruction; + private Date nextFireTime; + private JobKeyDTO jobKeyDTO; + private boolean mayFireAgain; +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java new file mode 100644 index 00000000..4a26e048 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java @@ -0,0 +1,22 @@ +package it.fabioformosa.quartzmanager.dto; + +public class TriggerKeyDTO { + private String name; + private String group; + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setGroup(String group) { + this.group = group; + } + + public String getGroup() { + return group; + } +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java new file mode 100644 index 00000000..75f63d56 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java @@ -0,0 +1,60 @@ +package it.fabioformosa.quartzmanager.services; + +import it.fabioformosa.quartzmanager.common.utils.Try; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; +import org.quartz.SimpleTrigger; +import org.quartz.TriggerKey; +import org.quartz.impl.matchers.GroupMatcher; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +public class SchedulerService { + + public static final int MILLS_IN_A_DAY = 1000 * 60 * 60 * 24; + public static final int SEC_IN_A_DAY = 60 * 60 * 24; + + private Scheduler scheduler; + + public SchedulerService(Scheduler scheduler) { + this.scheduler = scheduler; + } + + 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 + } + + public static int fromTriggerPerDayToSecInterval(long triggerPerDay) { + return (int) Math.ceil(Long.valueOf(SchedulerService.SEC_IN_A_DAY) / triggerPerDay); + } + + public static long fromMillsIntervalToTriggerPerDay(long repeatIntervalInMills) { + return (int) Math.ceil(MILLS_IN_A_DAY / repeatIntervalInMills); + } + + public Scheduler getScheduler() { + return scheduler; + } + + public Optional getTriggerByKey(String triggerKeyName) throws SchedulerException { + return scheduler.getTriggerKeys(GroupMatcher.anyGroup()).stream() + .filter(triggerKey -> triggerKey.getName().equals(triggerKeyName)) + .findFirst(); + } + + public Optional getOneSimpleTrigger() throws SchedulerException { + return getOneTriggerKey() + .map(Try.with(triggerKey -> scheduler.getTrigger(triggerKey))) + .filter(Try::isSuccess).map(Try::getSuccess) + .filter(trigger -> trigger instanceof SimpleTrigger) + .map(trigger -> (SimpleTrigger) trigger); + } + + public Optional getOneTriggerKey() throws SchedulerException { + return scheduler.getTriggerKeys(GroupMatcher.anyGroup()).stream() + .findFirst(); + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java index 86901838..517bd29a 100644 --- a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java @@ -1,69 +1,61 @@ -package it.fabioformosa.quartzmanager.persistence; - -import javax.sql.DataSource; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.PropertySource; - -import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; -import liquibase.integration.spring.SpringLiquibase; -import lombok.Data; -import lombok.extern.slf4j.Slf4j; - -@Slf4j -@Configuration -@PropertySource("classpath:quartz-manager-application-persistence.properties") -public class PersistenceConfig { - - @Data - public class PersistenceDatasourceProps { - private String url; - private String changeLog; - private String contexts; - private String user; - private String password; - } - - // @Data - // public class QuartzModuleProperties{ - // private Properties properties; - // } - - @Bean - public SpringLiquibase liquibase(PersistenceDatasourceProps persistenceDatasourceProps, DataSource quartzManagerDatasource) { - SpringLiquibase liquibase = new SpringLiquibase(); - liquibase.setContexts(persistenceDatasourceProps.getContexts()); - liquibase.setChangeLog(persistenceDatasourceProps.getChangeLog()); - liquibase.setDataSource(quartzManagerDatasource); - liquibase.setDropFirst(false); - return liquibase; - } - - @Bean - @ConfigurationProperties(prefix = "spring.liquibase") - public PersistenceDatasourceProps persistenceDatasourceProps() { - return new PersistenceDatasourceProps(); - } - - @Bean("quartzPersistenceProperties") - @ConfigurationProperties(prefix = "spring.quartz") - public QuartzModuleProperties persistenceQuartzProps() { - return new QuartzModuleProperties(); - } - - @Primary - @Bean - public DataSource quartzManagerDatasource(PersistenceDatasourceProps persistenceDatasourceProps) { - return DataSourceBuilder.create() - .url(persistenceDatasourceProps.getUrl()) - .driverClassName("org.postgresql.Driver") - .username(persistenceDatasourceProps.getUser()) - .password(persistenceDatasourceProps.getPassword()) - .build(); - } - -} +package it.fabioformosa.quartzmanager.persistence; + +import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; +import liquibase.integration.spring.SpringLiquibase; +import lombok.Data; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.boot.jdbc.DataSourceBuilder; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Primary; +import org.springframework.context.annotation.PropertySource; + +import javax.sql.DataSource; + +@Configuration +@PropertySource("classpath:quartz-manager-application-persistence.properties") +public class PersistenceConfig { + + @Data + public class PersistenceDatasourceProps { + private String url; + private String changeLog; + private String contexts; + private String user; + private String password; + } + + @Bean + public SpringLiquibase liquibase(PersistenceDatasourceProps persistenceDatasourceProps, DataSource quartzManagerDatasource) { + SpringLiquibase liquibase = new SpringLiquibase(); + liquibase.setContexts(persistenceDatasourceProps.getContexts()); + liquibase.setChangeLog(persistenceDatasourceProps.getChangeLog()); + liquibase.setDataSource(quartzManagerDatasource); + liquibase.setDropFirst(false); + return liquibase; + } + + @Bean + @ConfigurationProperties(prefix = "spring.liquibase") + public PersistenceDatasourceProps persistenceDatasourceProps() { + return new PersistenceDatasourceProps(); + } + + @Bean("quartzPersistenceProperties") + @ConfigurationProperties(prefix = "spring.quartz") + public QuartzModuleProperties persistenceQuartzProps() { + return new QuartzModuleProperties(); + } + + @Primary + @Bean + public DataSource quartzManagerDatasource(PersistenceDatasourceProps persistenceDatasourceProps) { + return DataSourceBuilder.create() + .url(persistenceDatasourceProps.getUrl()) + .driverClassName("org.postgresql.Driver") + .username(persistenceDatasourceProps.getUser()) + .password(persistenceDatasourceProps.getPassword()) + .build(); + } + +} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml index 413c274b..96206fc1 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/logback.xml @@ -12,6 +12,9 @@ + + + @@ -23,4 +26,4 @@
- \ No newline at end of file + From c4e8eb94d663ecf551f533d2f6d86d8e0666df3e Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Tue, 26 Oct 2021 00:32:38 +0200 Subject: [PATCH 06/17] #14 clean up --- .../properties/QuartzModuleProperties.java | 24 +- .../persistence/PersistenceConfig.java | 36 +- .../QuartzPersistencePropConfig.java | 17 + ...manager-application-persistence.properties | 20 -- .../resources/quartz-persistence.properties | 23 +- .../quartz-manager-web-showcase/pom.xml | 320 +++++++++--------- .../src/main/resources/application.yml | 6 + .../src/main/resources/quartz.properties | 10 - 8 files changed, 230 insertions(+), 226 deletions(-) create mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/QuartzPersistencePropConfig.java delete mode 100644 quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties diff --git a/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java index 9140b82a..72e41c7f 100644 --- a/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java +++ b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/properties/QuartzModuleProperties.java @@ -1,12 +1,12 @@ -package it.fabioformosa.quartzmanager.common.properties; - -import java.util.Properties; - -import lombok.Data; - -@Data -public class QuartzModuleProperties{ - - private Properties properties; - -} +package it.fabioformosa.quartzmanager.common.properties; + +import lombok.Data; + +import java.util.Properties; + +@Data +public class QuartzModuleProperties{ + + private Properties properties = new Properties(); + +} diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java index 517bd29a..aa0621b4 100644 --- a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/PersistenceConfig.java @@ -3,26 +3,30 @@ import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; import liquibase.integration.spring.SpringLiquibase; import lombok.Data; +import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Primary; -import org.springframework.context.annotation.PropertySource; +import org.springframework.context.annotation.*; import javax.sql.DataSource; @Configuration -@PropertySource("classpath:quartz-manager-application-persistence.properties") +@PropertySource("classpath:quartz-persistence.properties") public class PersistenceConfig { + @Value("${quartz-manager.persistence.quartz.datasource.url}") + private String quartzDatasourceUrl; + + @Value("${quartz-manager.persistence.quartz.datasource.user}") + private String quartzDatasourceUser; + + @Value("${quartz-manager.persistence.quartz.datasource.password}") + private String quartzDatasourcePassword; + @Data public class PersistenceDatasourceProps { - private String url; private String changeLog; private String contexts; - private String user; - private String password; } @Bean @@ -42,19 +46,23 @@ public PersistenceDatasourceProps persistenceDatasourceProps() { } @Bean("quartzPersistenceProperties") - @ConfigurationProperties(prefix = "spring.quartz") - public QuartzModuleProperties persistenceQuartzProps() { - return new QuartzModuleProperties(); + public QuartzModuleProperties persistenceQuartzProps(QuartzPersistencePropConfig quartzPersistencePropConfig) { + QuartzModuleProperties quartzModuleProperties = new QuartzModuleProperties(); + quartzModuleProperties.setProperties(quartzPersistencePropConfig.getProperties()); + quartzModuleProperties.getProperties().setProperty("org.quartz.dataSource.quartzDataSource.URL", quartzDatasourceUrl); + quartzModuleProperties.getProperties().setProperty("org.quartz.dataSource.quartzDataSource.user", quartzDatasourceUser); + quartzModuleProperties.getProperties().setProperty("org.quartz.dataSource.quartzDataSource.password", quartzDatasourcePassword); + return quartzModuleProperties; } @Primary @Bean public DataSource quartzManagerDatasource(PersistenceDatasourceProps persistenceDatasourceProps) { return DataSourceBuilder.create() - .url(persistenceDatasourceProps.getUrl()) + .url(quartzDatasourceUrl) .driverClassName("org.postgresql.Driver") - .username(persistenceDatasourceProps.getUser()) - .password(persistenceDatasourceProps.getPassword()) + .username(quartzDatasourceUser) + .password(quartzDatasourcePassword) .build(); } diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/QuartzPersistencePropConfig.java b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/QuartzPersistencePropConfig.java new file mode 100644 index 00000000..800f95c4 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/java/it/fabioformosa/quartzmanager/persistence/QuartzPersistencePropConfig.java @@ -0,0 +1,17 @@ +package it.fabioformosa.quartzmanager.persistence; + +import lombok.Getter; +import lombok.Setter; +import org.springframework.boot.context.properties.ConfigurationProperties; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +import java.util.Properties; + +@Configuration +@PropertySource("classpath:quartz-persistence.properties") +@ConfigurationProperties(prefix = "spring.quartz") +@Getter @Setter +public class QuartzPersistencePropConfig { + private Properties properties; +} diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties deleted file mode 100644 index 9edbfcfb..00000000 --- a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-manager-application-persistence.properties +++ /dev/null @@ -1,20 +0,0 @@ -spring.liquibase.url=jdbc:postgresql://localhost:5432/quartzmanager -spring.liquibase.change-log=classpath:db/quartz-scheduler/liquibase-changelog-master.xml -spring.liquibase.contexts=default -spring.liquibase.user=quartzmanager -spring.liquibase.password=quartzmanager -spring.quartz.job-store-type=jdbc -spring.quartz.initialize-schema=never -spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -spring.quartz.properties.org.quartz.dataSource.quartzDataSource.driver=org.postgresql.Driver -spring.quartz.properties.org.quartz.dataSource.quartzDataSource.URL=jdbc:postgresql://localhost:5432/quartzmanager -spring.quartz.properties.org.quartz.dataSource.quartzDataSource.user=quartzmanager -spring.quartz.properties.org.quartz.dataSource.quartzDataSource.password=quartzmanager -spring.quartz.properties.org.quartz.dataSource.quartzDataSource.maxConnections=5 -spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX -spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -spring.quartz.properties.org.quartz.jobStore.dataSource=quartzDataSource -spring.quartz.properties.org.quartz.dataSource.quartzDataSource.provider=hikaricp -spring.quartz.properties.org.quartz.jobStore.misfireThreshold=1000 -# org.quartz.jobStore.isClustered=true -# org.quartz.scheduler.instanceId=AUTO \ No newline at end of file diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties index 3e68aac0..fbd821ce 100644 --- a/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties +++ b/quartz-manager-parent/quartz-manager-starter-persistence/src/main/resources/quartz-persistence.properties @@ -1,10 +1,13 @@ -org.quartz.dataSource.quartzDataSource.driver = org.postgresql.Driver -org.quartz.dataSource.quartzDataSource.URL = jdbc:postgresql://localhost:5432/quartzmanager -org.quartz.dataSource.quartzDataSource.user quartzmanager -org.quartz.dataSource.quartzDataSource.password = quartzmanager -org.quartz.dataSource.quartzDataSource.maxConnections = 5 -org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX -org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -org.quartz.jobStore.dataSource = quartzDataSource -org.quartz.dataSource.quartzDataSource.provider=hikaricp -org.quartz.jobStore.misfireThreshold=1000 \ No newline at end of file +spring.liquibase.change-log=classpath:db/quartz-scheduler/liquibase-changelog-master.xml +spring.liquibase.contexts=default +spring.quartz.job-store-type=jdbc +spring.quartz.initialize-schema=never +spring.quartz.properties.org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.PostgreSQLDelegate +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.driver=org.postgresql.Driver +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.maxConnections=5 +spring.quartz.properties.org.quartz.jobStore.class=org.quartz.impl.jdbcjobstore.JobStoreTX +spring.quartz.properties.org.quartz.jobStore.dataSource=quartzDataSource +spring.quartz.properties.org.quartz.dataSource.quartzDataSource.provider=hikaricp +spring.quartz.properties.org.quartz.jobStore.misfireThreshold=1000 +# org.quartz.jobStore.isClustered=true +# org.quartz.scheduler.instanceId=AUTO diff --git a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml index e4787b0b..bfc2f24a 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -1,160 +1,160 @@ - - - 4.0.0 - - - it.fabioformosa.quartz-manager - quartz-manager-parent - 3.0.2-SNAPSHOT - - - quartz-manager-web-showcase - - war - - Quartz Manager Web Showcase - A webapp that imports Quartz Manager API lib and the frontend webjar - - - UTF-8 - UTF-8 - 2.9.2 - 1.8 - - - - - it.fabioformosa.quartz-manager - quartz-manager-starter-api - - - it.fabioformosa.quartz-manager - quartz-manager-starter-ui - - - it.fabioformosa.quartz-manager - quartz-manager-starter-security - - - it.fabioformosa.quartz-manager - quartz-manager-starter-persistence - - - - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-security - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-devtools - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-tomcat - provided - - - org.springframework.boot - spring-boot-starter-test - test - - - - - io.jsonwebtoken - jjwt - 0.9.0 - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-annotations - - - com.h2database - h2 - runtime - - - org.codehaus.groovy - groovy - - - net.sourceforge.nekohtml - nekohtml - - - io.rest-assured - spring-mock-mvc - test - - - org.projectlombok - lombok - provided - - - org.apache.commons - commons-lang3 - - - - - org.liquibase - liquibase-core - - - - org.postgresql - postgresql - - - - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - repackage - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - - - - - - - - + + + 4.0.0 + + + it.fabioformosa.quartz-manager + quartz-manager-parent + 3.0.2-SNAPSHOT + + + quartz-manager-web-showcase + + war + + Quartz Manager Web Showcase + A webapp that imports Quartz Manager API lib and the frontend webjar + + + UTF-8 + UTF-8 + 2.9.2 + 1.8 + + + + + it.fabioformosa.quartz-manager + quartz-manager-starter-api + + + it.fabioformosa.quartz-manager + quartz-manager-starter-ui + + + it.fabioformosa.quartz-manager + quartz-manager-starter-security + + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-test + test + + + + + io.jsonwebtoken + jjwt + 0.9.0 + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + com.h2database + h2 + runtime + + + org.codehaus.groovy + groovy + + + net.sourceforge.nekohtml + nekohtml + + + io.rest-assured + spring-mock-mvc + test + + + org.projectlombok + lombok + provided + + + org.apache.commons + commons-lang3 + + + + + org.liquibase + liquibase-core + + + + + + + + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + repackage + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + + + + + 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 5d2e4abe..74a5d68f 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 @@ -47,6 +47,12 @@ logging: org.quartz: DEBUG quartz-manager: +# persistence: +# quartz: +# datasource: +# url: "jdbc:postgresql://localhost:5432/quartzmanager" +# user: "quartzmanager" +# password: "quartzmanager" security: login-model: form-login-enabled: true diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties index 44b1da16..d00f1535 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties @@ -1,13 +1,3 @@ org.quartz.scheduler.instanceName=example org.quartz.scheduler.instanceId=AUTO org.quartz.threadPool.threadCount=1 -#org.quartz.dataSource.quartzDataSource.driver = org.postgresql.Driver -#org.quartz.dataSource.quartzDataSource.URL = jdbc:postgresql://localhost:5432/quartzmanager -#org.quartz.dataSource.quartzDataSource.user quartzmanager -#org.quartz.dataSource.quartzDataSource.password = quartzmanager -#org.quartz.dataSource.quartzDataSource.maxConnections = 5 -#org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX -#org.quartz.jobStore.driverDelegateClass = org.quartz.impl.jdbcjobstore.PostgreSQLDelegate -#org.quartz.jobStore.dataSource = quartzDataSource -#org.quartz.dataSource.quartzDataSource.provider=hikaricp -#org.quartz.jobStore.misfireThreshold=1000 \ No newline at end of file From 70827393b72d7b015717fe34d598e409b2677487 Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Sat, 30 Oct 2021 00:22:44 +0200 Subject: [PATCH 07/17] #14 fixed the trigger rescheduling --- .../scheduler-config.component.html | 4 +-- .../scheduler-config.component.ts | 8 +++-- .../src/app/services/scheduler.service.ts | 6 +++- .../controllers/TriggerController.java | 32 +++++++++++++++++++ 4 files changed, 44 insertions(+), 6 deletions(-) diff --git a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html index 630519be..fce2ade3 100644 --- a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html +++ b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html @@ -4,14 +4,14 @@ - + - +
diff --git a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts index ea5cd31e..6106e8cf 100644 --- a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts +++ b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.ts @@ -47,10 +47,12 @@ export class SchedulerConfigComponent implements OnInit { }) } - shouldShowTriggerConfig = (): boolean => this.fetchedTriggers && this.triggerInProgress; + existsATriggerInProgress = (): boolean => this.fetchedTriggers && this.triggerInProgress; submitConfig = () => { - this.schedulerService.updateConfig(this.config) + const schedulerServiceCall = this.existsATriggerInProgress() ? this.schedulerService.updateConfig : this.schedulerService.saveConfig; + + schedulerServiceCall(this.config) .subscribe(res => { this.configBackup = this.config; this.enabledTriggerForm = false; @@ -61,5 +63,5 @@ export class SchedulerConfigComponent implements OnInit { }); }; - enableTriggerForm = () => this.enabledTriggerForm = true; + enableTriggerForm = () => this.enabledTriggerForm = true; } diff --git a/quartz-manager-frontend/src/app/services/scheduler.service.ts b/quartz-manager-frontend/src/app/services/scheduler.service.ts index 930df9f8..ead76f30 100644 --- a/quartz-manager-frontend/src/app/services/scheduler.service.ts +++ b/quartz-manager-frontend/src/app/services/scheduler.service.ts @@ -37,9 +37,13 @@ export class SchedulerService { return this.apiService.get(getBaseUrl() + '/quartz-manager/scheduler/config') } - updateConfig = (config: Object) => { + saveConfig = (config: Object) => { return this.apiService.post(getBaseUrl() + '/quartz-manager/triggers/mytrigger', config) } + updateConfig = (config: Object) => { + return this.apiService.put(getBaseUrl() + '/quartz-manager/triggers/mytrigger', config) + } + } 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 f3d8be31..9bb9498f 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 @@ -10,6 +10,8 @@ import org.springframework.core.convert.ConversionService; import org.springframework.web.bind.annotation.*; +import java.util.Optional; + @Slf4j @RequestMapping("/quartz-manager/triggers") @RestController @@ -54,6 +56,7 @@ public TriggerDTO postTrigger(@PathVariable String name, @RequestBody SchedulerC .withRepeatCount(config.getMaxCount() - 1) .withMisfireHandlingInstructionNextWithRemainingCount() ) + .withIdentity(name) .build(); // Optional optionalTriggerKey = schedulerService.getTriggerByKey(name); @@ -68,5 +71,34 @@ public TriggerDTO postTrigger(@PathVariable String name, @RequestBody SchedulerC return newTriggerDTO; } + @PutMapping("/{name}") + public TriggerDTO rescheduleTrigger(@PathVariable String name, @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { + log.info("TRIGGER - RESCHEDULE trigger {}", config); + int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); + + Optional optionalTriggerKey = schedulerService.getTriggerByKey(name); + TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name)); + Trigger trigger = scheduler.getTrigger(triggerKey); + + Trigger newTrigger = TriggerBuilder.newTrigger() + .withSchedule( + SimpleScheduleBuilder.simpleSchedule() + .withIntervalInMilliseconds(intervalInMills) + .withRepeatCount(config.getMaxCount() - 1) + .withMisfireHandlingInstructionNextWithRemainingCount() + ) + .forJob(trigger.getJobKey().getName()) + .withIdentity(name) + .build(); + +// scheduler.scheduleJob(jobDetail, newTrigger); + scheduler.rescheduleJob(triggerKey, newTrigger); + + TriggerDTO newTriggerDTO = conversionService.convert(newTrigger, TriggerDTO.class); + + log.info("Rescheduled new trigger {}", newTriggerDTO); + return newTriggerDTO; + } + } From 9bf0871ff6d8500d2fcc5f38075edd1ef66cfd9f Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Sat, 30 Oct 2021 00:55:24 +0200 Subject: [PATCH 08/17] #14 imported quartz-manager-persistence into the web-showcase --- .../pom.xml | 98 ++++---- .../quartz-manager-web-showcase/pom.xml | 24 +- .../src/main/resources/application.yml | 26 +-- .../db/liquibase-changelog-master.xml | 10 - .../V202102190034_quartz_tables.sql | 218 ------------------ 5 files changed, 69 insertions(+), 307 deletions(-) delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml delete mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql diff --git a/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml b/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml index 4b25241e..8f6908f7 100644 --- a/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml +++ b/quartz-manager-parent/quartz-manager-starter-persistence/pom.xml @@ -1,47 +1,51 @@ - - 4.0.0 - - it.fabioformosa.quartz-manager - quartz-manager-parent - 3.0.2-SNAPSHOT - - - quartz-manager-starter-persistence - - Quartz Manager Starter Security - Persist quartz jobs into a database - - https://github.com/fabioformosa/quartz-manager - - ${basedir}/../.. - UTF-8 - UTF-8 - 1.8 - - - - - it.fabioformosa.quartz-manager - quartz-manager-common - - - org.liquibase - liquibase-core - - - org.springframework.boot - spring-boot-starter-data-jpa - - - org.springframework.boot - spring-boot-configuration-processor - true - - - org.projectlombok - lombok - provided - - - - \ No newline at end of file + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 3.0.2-SNAPSHOT + + + quartz-manager-starter-persistence + + Quartz Manager Starter Security + Persist quartz jobs into a database + + https://github.com/fabioformosa/quartz-manager + + ${basedir}/../.. + UTF-8 + UTF-8 + 1.8 + + + + + it.fabioformosa.quartz-manager + quartz-manager-common + + + org.liquibase + liquibase-core + + + org.springframework.boot + spring-boot-starter-data-jpa + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.postgresql + postgresql + + + org.projectlombok + lombok + provided + + + + diff --git a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml index bfc2f24a..371f02a6 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -35,10 +35,10 @@ it.fabioformosa.quartz-manager quartz-manager-starter-security - - - - + + it.fabioformosa.quartz-manager + quartz-manager-starter-persistence + @@ -49,10 +49,10 @@ org.springframework.boot spring-boot-starter-security - - org.springframework.boot - spring-boot-starter-data-jpa - + + + + org.springframework.boot spring-boot-devtools @@ -116,10 +116,10 @@ - - org.liquibase - liquibase-core - + + + + 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 74a5d68f..9f468cc2 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 @@ -12,22 +12,8 @@ spring: cache: false mode: LEGACYHTML5 jpa.open-in-view: false -# liquibase: -# change-log: "classpath:db/liquibase-changelog-master.xml" -# contexts: default -# user: quartzmanager -# password: quartzmanager -# datasource: -# url: "jdbc:postgresql://localhost:5432/quartzmanager" -# username: quartzmanager -# password: quartzmanager # quartz: -# job-store-type: jdbc -# initialize-schema: never -# properties: -# org.quartz.jobStore.driverDelegateClass: org.quartz.impl.jdbcjobstore.PostgreSQLDelegate - # org.quartz.jobStore.isClustered: true # org.quartz.scheduler.instanceId=AUTO @@ -47,12 +33,12 @@ logging: org.quartz: DEBUG quartz-manager: -# persistence: -# quartz: -# datasource: -# url: "jdbc:postgresql://localhost:5432/quartzmanager" -# user: "quartzmanager" -# password: "quartzmanager" + persistence: + quartz: + datasource: + url: "jdbc:postgresql://localhost:5432/quartzmanager" + user: "quartzmanager" + password: "quartzmanager" security: login-model: form-login-enabled: true diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml deleted file mode 100644 index ad7fc84b..00000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/liquibase-changelog-master.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql deleted file mode 100644 index 1fc97540..00000000 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/db/migrations/V202102190034_quartz_tables.sql +++ /dev/null @@ -1,218 +0,0 @@ ---liquibase formatted sql - -/* https://github.com/quartz-scheduler/quartz/blob/master/quartz-core/src/main/resources/org/quartz/impl/jdbcjobstore/tables_postgres.sql */ - ---changeset V202102190034_01 (dbms:postgresql) -DROP TABLE IF EXISTS QRTZ_FIRED_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_PAUSED_TRIGGER_GRPS; -DROP TABLE IF EXISTS QRTZ_SCHEDULER_STATE; -DROP TABLE IF EXISTS QRTZ_LOCKS; -DROP TABLE IF EXISTS QRTZ_SIMPLE_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_CRON_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_SIMPROP_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_BLOB_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_TRIGGERS; -DROP TABLE IF EXISTS QRTZ_JOB_DETAILS; -DROP TABLE IF EXISTS QRTZ_CALENDARS; - ---changeset V202102190034_02 (dbms:postgresql) -CREATE TABLE QRTZ_JOB_DETAILS -( - SCHED_NAME VARCHAR(120) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - JOB_CLASS_NAME VARCHAR(250) NOT NULL, - IS_DURABLE BOOL NOT NULL, - IS_NONCONCURRENT BOOL NOT NULL, - IS_UPDATE_DATA BOOL NOT NULL, - REQUESTS_RECOVERY BOOL NOT NULL, - JOB_DATA BYTEA NULL, - PRIMARY KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) -); - ---changeset V202102190034_03 (dbms:postgresql) -CREATE TABLE QRTZ_TRIGGERS -( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - JOB_NAME VARCHAR(200) NOT NULL, - JOB_GROUP VARCHAR(200) NOT NULL, - DESCRIPTION VARCHAR(250) NULL, - NEXT_FIRE_TIME BIGINT NULL, - PREV_FIRE_TIME BIGINT NULL, - PRIORITY INTEGER NULL, - TRIGGER_STATE VARCHAR(16) NOT NULL, - TRIGGER_TYPE VARCHAR(8) NOT NULL, - START_TIME BIGINT NOT NULL, - END_TIME BIGINT NULL, - CALENDAR_NAME VARCHAR(200) NULL, - MISFIRE_INSTR SMALLINT NULL, - JOB_DATA BYTEA NULL, - PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME, JOB_NAME, JOB_GROUP) - REFERENCES QRTZ_JOB_DETAILS (SCHED_NAME, JOB_NAME, JOB_GROUP) -); - ---changeset V202102190034_04 (dbms:postgresql) -CREATE TABLE QRTZ_SIMPLE_TRIGGERS -( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - REPEAT_COUNT BIGINT NOT NULL, - REPEAT_INTERVAL BIGINT NOT NULL, - TIMES_TRIGGERED BIGINT NOT NULL, - PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) -); - ---changeset V202102190034_05 (dbms:postgresql) -CREATE TABLE QRTZ_CRON_TRIGGERS -( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - CRON_EXPRESSION VARCHAR(120) NOT NULL, - TIME_ZONE_ID VARCHAR(80), - PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) -); - ---changeset V202102190034_06 (dbms:postgresql) -CREATE TABLE QRTZ_SIMPROP_TRIGGERS -( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - STR_PROP_1 VARCHAR(512) NULL, - STR_PROP_2 VARCHAR(512) NULL, - STR_PROP_3 VARCHAR(512) NULL, - INT_PROP_1 INT NULL, - INT_PROP_2 INT NULL, - LONG_PROP_1 BIGINT NULL, - LONG_PROP_2 BIGINT NULL, - DEC_PROP_1 NUMERIC(13, 4) NULL, - DEC_PROP_2 NUMERIC(13, 4) NULL, - BOOL_PROP_1 BOOL NULL, - BOOL_PROP_2 BOOL NULL, - PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) -); - ---changeset V202102190034_07 (dbms:postgresql) -CREATE TABLE QRTZ_BLOB_TRIGGERS -( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - BLOB_DATA BYTEA NULL, - PRIMARY KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP), - FOREIGN KEY (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) - REFERENCES QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP) -); - ---changeset V202102190034_08 (dbms:postgresql) -CREATE TABLE QRTZ_CALENDARS -( - SCHED_NAME VARCHAR(120) NOT NULL, - CALENDAR_NAME VARCHAR(200) NOT NULL, - CALENDAR BYTEA NOT NULL, - PRIMARY KEY (SCHED_NAME, CALENDAR_NAME) -); - ---changeset V202102190034_09 (dbms:postgresql) -CREATE TABLE QRTZ_PAUSED_TRIGGER_GRPS -( - SCHED_NAME VARCHAR(120) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - PRIMARY KEY (SCHED_NAME, TRIGGER_GROUP) -); - ---changeset V202102190034_10 (dbms:postgresql) -CREATE TABLE QRTZ_FIRED_TRIGGERS -( - SCHED_NAME VARCHAR(120) NOT NULL, - ENTRY_ID VARCHAR(95) NOT NULL, - TRIGGER_NAME VARCHAR(200) NOT NULL, - TRIGGER_GROUP VARCHAR(200) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - FIRED_TIME BIGINT NOT NULL, - SCHED_TIME BIGINT NOT NULL, - PRIORITY INTEGER NOT NULL, - STATE VARCHAR(16) NOT NULL, - JOB_NAME VARCHAR(200) NULL, - JOB_GROUP VARCHAR(200) NULL, - IS_NONCONCURRENT BOOL NULL, - REQUESTS_RECOVERY BOOL NULL, - PRIMARY KEY (SCHED_NAME, ENTRY_ID) -); - ---changeset V202102190034_11 (dbms:postgresql) -CREATE TABLE QRTZ_SCHEDULER_STATE -( - SCHED_NAME VARCHAR(120) NOT NULL, - INSTANCE_NAME VARCHAR(200) NOT NULL, - LAST_CHECKIN_TIME BIGINT NOT NULL, - CHECKIN_INTERVAL BIGINT NOT NULL, - PRIMARY KEY (SCHED_NAME, INSTANCE_NAME) -); - ---changeset V202102190034_12 (dbms:postgresql) -CREATE TABLE QRTZ_LOCKS -( - SCHED_NAME VARCHAR(120) NOT NULL, - LOCK_NAME VARCHAR(40) NOT NULL, - PRIMARY KEY (SCHED_NAME, LOCK_NAME) -); - ---changeset V202102190034_13 (dbms:postgresql) -CREATE INDEX IDX_QRTZ_J_REQ_RECOVERY - ON QRTZ_JOB_DETAILS (SCHED_NAME, REQUESTS_RECOVERY); -CREATE INDEX IDX_QRTZ_J_GRP - ON QRTZ_JOB_DETAILS (SCHED_NAME, JOB_GROUP); - -CREATE INDEX IDX_QRTZ_T_J - ON QRTZ_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP); -CREATE INDEX IDX_QRTZ_T_JG - ON QRTZ_TRIGGERS (SCHED_NAME, JOB_GROUP); -CREATE INDEX IDX_QRTZ_T_C - ON QRTZ_TRIGGERS (SCHED_NAME, CALENDAR_NAME); -CREATE INDEX IDX_QRTZ_T_G - ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP); -CREATE INDEX IDX_QRTZ_T_STATE - ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_N_STATE - ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP, TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_N_G_STATE - ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_GROUP, TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_NEXT_FIRE_TIME - ON QRTZ_TRIGGERS (SCHED_NAME, NEXT_FIRE_TIME); -CREATE INDEX IDX_QRTZ_T_NFT_ST - ON QRTZ_TRIGGERS (SCHED_NAME, TRIGGER_STATE, NEXT_FIRE_TIME); -CREATE INDEX IDX_QRTZ_T_NFT_MISFIRE - ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME); -CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE - ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_STATE); -CREATE INDEX IDX_QRTZ_T_NFT_ST_MISFIRE_GRP - ON QRTZ_TRIGGERS (SCHED_NAME, MISFIRE_INSTR, NEXT_FIRE_TIME, TRIGGER_GROUP, TRIGGER_STATE); - -CREATE INDEX IDX_QRTZ_FT_TRIG_INST_NAME - ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME); -CREATE INDEX IDX_QRTZ_FT_INST_JOB_REQ_RCVRY - ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, INSTANCE_NAME, REQUESTS_RECOVERY); -CREATE INDEX IDX_QRTZ_FT_J_G - ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_NAME, JOB_GROUP); -CREATE INDEX IDX_QRTZ_FT_JG - ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, JOB_GROUP); -CREATE INDEX IDX_QRTZ_FT_T_G - ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_NAME, TRIGGER_GROUP); -CREATE INDEX IDX_QRTZ_FT_TG - ON QRTZ_FIRED_TRIGGERS (SCHED_NAME, TRIGGER_GROUP); - - -COMMIT; From 87ee4bebb3626fdd1c3c389fe5f3528a41e0c9e4 Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Sat, 30 Oct 2021 00:56:08 +0200 Subject: [PATCH 09/17] #14 added a new line to the .gitignore --- quartz-manager-parent/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/quartz-manager-parent/.gitignore b/quartz-manager-parent/.gitignore index d6593c54..a080dd84 100644 --- a/quartz-manager-parent/.gitignore +++ b/quartz-manager-parent/.gitignore @@ -3,3 +3,4 @@ /**/target .classpath .project +.idea From fb2d8da53d7ab4e25640f65459305c4c12f9248a Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Sat, 30 Oct 2021 16:22:21 +0200 Subject: [PATCH 10/17] #14 cleanup --- .../quartz-manager-starter-api/pom.xml | 74 +++++----- .../configuration/SchedulerConfig.java | 38 +----- .../controllers/SchedulerController.java | 31 ----- .../controllers/TriggerController.java | 77 ++--------- .../controllers/UserController.java | 13 +- .../services/SchedulerService.java | 64 ++++++++- .../quartz-manager-web-showcase/pom.xml | 128 ++++++++---------- .../quartzmanager/jobs/myjobs/SampleJob.java | 3 +- .../src/main/resources/application.yml | 4 - .../src/main/resources/quartz.properties | 1 - 10 files changed, 171 insertions(+), 262 deletions(-) diff --git a/quartz-manager-parent/quartz-manager-starter-api/pom.xml b/quartz-manager-parent/quartz-manager-starter-api/pom.xml index 512eee22..b200ffa1 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/pom.xml +++ b/quartz-manager-parent/quartz-manager-starter-api/pom.xml @@ -91,45 +91,45 @@ 1.3.2 - - - io.projectreactor - reactor-core - - - io.projectreactor - reactor-net - 2.0.8.RELEASE - - - io.projectreactor.spring - reactor-spring-context - 2.0.7.RELEASE - - - io.netty - netty-all - - - org.springframework.boot - spring-boot-starter-aop - - - org.yaml - snakeyaml - + + + io.projectreactor + reactor-core + + + io.projectreactor + reactor-net + 2.0.8.RELEASE + + + io.projectreactor.spring + reactor-spring-context + 2.0.7.RELEASE + + + io.netty + netty-all + + + org.springframework.boot + spring-boot-starter-aop + + + org.yaml + snakeyaml + - - io.springfox - springfox-swagger2 - ${springfox.version} - - - io.springfox - springfox-swagger-ui - ${springfox.version} - + + io.springfox + springfox-swagger2 + ${springfox.version} + + + io.springfox + springfox-swagger-ui + ${springfox.version} + diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java index 7701a35a..4d9749a5 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/configuration/SchedulerConfig.java @@ -3,8 +3,6 @@ import it.fabioformosa.quartzmanager.common.properties.QuartzModuleProperties; import it.fabioformosa.quartzmanager.scheduler.AutowiringSpringBeanJobFactory; import org.quartz.Job; -import org.quartz.JobDetail; -import org.quartz.SimpleTrigger; import org.quartz.spi.JobFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -17,7 +15,6 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.scheduling.quartz.JobDetailFactoryBean; import org.springframework.scheduling.quartz.SchedulerFactoryBean; -import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; import java.io.IOException; import java.util.Properties; @@ -27,8 +24,6 @@ @ConditionalOnProperty(name = "quartz.enabled") public class SchedulerConfig { - private static final int DEFAULT_MISFIRE_INSTRUCTION = SimpleTrigger.MISFIRE_INSTRUCTION_RESCHEDULE_NEXT_WITH_REMAINING_COUNT; - private static JobDetailFactoryBean createJobDetail(Class jobClass) { JobDetailFactoryBean factoryBean = new JobDetailFactoryBean(); factoryBean.setJobClass(jobClass); @@ -36,35 +31,13 @@ private static JobDetailFactoryBean createJobDetail(Class jobClas return factoryBean; } - private static SimpleTriggerFactoryBean createTrigger(JobDetail jobDetail, long pollFrequencyMs, - int repeatCount) { - SimpleTriggerFactoryBean factoryBean = new SimpleTriggerFactoryBean(); - factoryBean.setJobDetail(jobDetail); - factoryBean.setStartDelay(3000L); - factoryBean.setRepeatInterval(pollFrequencyMs); - factoryBean.setRepeatCount(repeatCount); - factoryBean - .setMisfireInstruction(DEFAULT_MISFIRE_INSTRUCTION);// in case of misfire, ignore all missed triggers and continue - return factoryBean; - } - @Value("${quartz-manager.jobClass}") private String jobClassname; @Autowired(required = false) private QuartzModuleProperties quartzModuleProperties; - - // REMOVEME -// @Bean(name = "triggerMonitor") -// public TriggerMonitor createTriggerMonitor(@Qualifier("jobTrigger") Trigger trigger) { -// TriggerMonitor triggerMonitor = new TriggerMonitorImpl(); -// triggerMonitor.setTrigger(trigger); -// return triggerMonitor; -// } - @Bean - @SuppressWarnings("unchecked") public JobDetailFactoryBean jobDetail() throws ClassNotFoundException { Class JobClass = (Class) Class.forName(jobClassname); return createJobDetail(JobClass); @@ -85,24 +58,15 @@ public Properties quartzProperties() throws IOException { return propertiesFactoryBean.getObject(); } -// @Bean(name = "jobTrigger") -// public SimpleTriggerFactoryBean sampleJobTrigger(@Qualifier("jobDetail") JobDetail jobDetail, -// @Value("${job.frequency}") long frequency, @Value("${job.repeatCount}") int repeatCount) { -// return createTrigger(jobDetail, frequency, repeatCount); -// } - @Bean(name = "scheduler") public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory) throws IOException { -// public SchedulerFactoryBean schedulerFactoryBean(JobFactory jobFactory, -// @Qualifier("jobTrigger") Trigger sampleJobTrigger) throws IOException { SchedulerFactoryBean factory = new SchedulerFactoryBean(); factory.setJobFactory(jobFactory); Properties mergedProperties = new Properties(); - mergedProperties.putAll(quartzProperties()); if(quartzModuleProperties != null) mergedProperties.putAll(quartzModuleProperties.getProperties()); + mergedProperties.putAll(quartzProperties()); factory.setQuartzProperties(mergedProperties); - //factory.setTriggers(sampleJobTrigger); factory.setAutoStartup(false); return factory; } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java index ca554ba5..ebd48871 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/SchedulerController.java @@ -38,24 +38,15 @@ public SchedulerController(SchedulerService schedulerService, ConversionService this.conversionService = conversionService; } - // @Resource -// private Scheduler scheduler; - - //TODO REMOVEME -// @Resource -// private TriggerMonitor triggerMonitor; - @Resource private ConversionService conversionService; @GetMapping("/config") public SchedulerConfigParam getConfig() throws SchedulerException { log.debug("SCHEDULER - GET CONFIG params"); - SchedulerConfigParam schedulerConfigParam = schedulerService.getOneSimpleTrigger() .map(SchedulerController::fromSimpleTriggerToSchedulerConfigParam) .orElse(new SchedulerConfigParam(0, 0, 0)); - return schedulerConfigParam; } @@ -66,8 +57,6 @@ public static SchedulerConfigParam fromSimpleTriggerToSchedulerConfigParam(Simpl return new SchedulerConfigParam(triggersPerDay, maxCount, timesTriggered); } - - @GetMapping public SchedulerDTO getScheduler() { log.debug("SCHEDULER - GET Scheduler..."); @@ -114,26 +103,6 @@ public void pause() throws SchedulerException { schedulerService.getScheduler().standby(); } -// @PostMapping("/config") -// public SchedulerConfigParam postConfig(@RequestBody SchedulerConfigParam config) throws SchedulerException { -// log.info("SCHEDULER - NEW CONFIG {}", config); -// -// int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); -// -// Trigger newTrigger = TriggerBuilder.newTrigger() -// .withSchedule( -// SimpleScheduleBuilder.simpleSchedule() -// .withIntervalInMilliseconds(intervalInMills) -// .withRepeatCount(config.getMaxCount() - 1) -// .withMisfireHandlingInstructionNextWithRemainingCount() -// ) -// .build(); -// -// schedulerService.getScheduler().rescheduleJob(schedulerService.getOneTriggerKey().get(), newTrigger); -//// triggerMonitor.setTrigger(newTrigger); REMOVEME -// return config; -// } - @GetMapping("/resume") @ResponseStatus(HttpStatus.NO_CONTENT) public void resume() throws SchedulerException { 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 9bb9498f..19c3f138 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 @@ -5,13 +5,10 @@ import it.fabioformosa.quartzmanager.dto.TriggerDTO; import it.fabioformosa.quartzmanager.services.SchedulerService; import lombok.extern.slf4j.Slf4j; -import org.quartz.*; +import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Value; -import org.springframework.core.convert.ConversionService; import org.springframework.web.bind.annotation.*; -import java.util.Optional; - @Slf4j @RequestMapping("/quartz-manager/triggers") @RestController @@ -21,83 +18,31 @@ public class TriggerController { @Value("${quartz-manager.jobClass}") private String jobClassname; - private Scheduler scheduler; private SchedulerService schedulerService; - private ConversionService conversionService; - public TriggerController(Scheduler scheduler, SchedulerService schedulerService, ConversionService conversionService) { - this.scheduler = scheduler; + public TriggerController(SchedulerService schedulerService) { this.schedulerService = schedulerService; - this.conversionService = conversionService; } @GetMapping("/{name}") public TriggerDTO getTrigger(@PathVariable String name) throws SchedulerException { - Trigger trigger = scheduler.getTrigger(new TriggerKey(name)); - TriggerDTO triggerDTO = conversionService.convert(trigger, TriggerDTO.class); - return triggerDTO; + return schedulerService.getTriggerByName(name); } @PostMapping("/{name}") public TriggerDTO postTrigger(@PathVariable String name, @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { - log.info("TRIGGER - POST trigger {}", config); - int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); - - Class jobClass = (Class) Class.forName(jobClassname); - JobDetail jobDetail = JobBuilder.newJob() - .ofType(jobClass) - .storeDurably(false) - .build(); - - Trigger newTrigger = TriggerBuilder.newTrigger() - .withSchedule( - SimpleScheduleBuilder.simpleSchedule() - .withIntervalInMilliseconds(intervalInMills) - .withRepeatCount(config.getMaxCount() - 1) - .withMisfireHandlingInstructionNextWithRemainingCount() - ) - .withIdentity(name) - .build(); - -// Optional optionalTriggerKey = schedulerService.getTriggerByKey(name); -// TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name)); - - scheduler.scheduleJob(jobDetail, newTrigger); -// scheduler.rescheduleJob(triggerKey, newTrigger); - - TriggerDTO newTriggerDTO = conversionService.convert(newTrigger, TriggerDTO.class); - - log.info("Rescheduled new trigger {}", newTriggerDTO); + log.info("TRIGGER - CREATING a trigger {} {}", name, config); + TriggerDTO newTriggerDTO = schedulerService.scheduleNewTrigger(name, jobClassname, config); + log.info("TRIGGER - CREATED a trigger {}", newTriggerDTO); return newTriggerDTO; } @PutMapping("/{name}") - public TriggerDTO rescheduleTrigger(@PathVariable String name, @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { - log.info("TRIGGER - RESCHEDULE trigger {}", config); - int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); - - Optional optionalTriggerKey = schedulerService.getTriggerByKey(name); - TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name)); - Trigger trigger = scheduler.getTrigger(triggerKey); - - Trigger newTrigger = TriggerBuilder.newTrigger() - .withSchedule( - SimpleScheduleBuilder.simpleSchedule() - .withIntervalInMilliseconds(intervalInMills) - .withRepeatCount(config.getMaxCount() - 1) - .withMisfireHandlingInstructionNextWithRemainingCount() - ) - .forJob(trigger.getJobKey().getName()) - .withIdentity(name) - .build(); - -// scheduler.scheduleJob(jobDetail, newTrigger); - scheduler.rescheduleJob(triggerKey, newTrigger); - - TriggerDTO newTriggerDTO = conversionService.convert(newTrigger, TriggerDTO.class); - - log.info("Rescheduled new trigger {}", newTriggerDTO); - return newTriggerDTO; + public TriggerDTO rescheduleTrigger(@PathVariable String name, @RequestBody SchedulerConfigParam config) throws SchedulerException { + log.info("TRIGGER - RESCHEDULING the trigger {} {}", name, config); + TriggerDTO triggerDTO = schedulerService.rescheduleTrigger(name, config); + log.info("TRIGGER - RESCHEDULED the trigger {}", triggerDTO); + return triggerDTO; } diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java index 5e431ea3..9e1b8200 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/controllers/UserController.java @@ -12,7 +12,6 @@ @RequestMapping(value = "/quartz-manager/api", produces = MediaType.APPLICATION_JSON_VALUE) public class UserController { - @GetMapping("/whoami") public @ResponseBody Object user() { SecurityContext context = SecurityContextHolder.getContext(); @@ -21,12 +20,12 @@ public class UserController { return "\"NO_AUTH\""; } - /** - * JWT Temporary disabled - * - * @author Fabio.Formosa - * - */ +// /** +// * JWT Temporary disabled +// * +// * @author Fabio.Formosa +// * +// */ // @Autowired // private UserService userService; diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java index 75f63d56..7900aee1 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/services/SchedulerService.java @@ -1,11 +1,11 @@ package it.fabioformosa.quartzmanager.services; import it.fabioformosa.quartzmanager.common.utils.Try; -import org.quartz.Scheduler; -import org.quartz.SchedulerException; -import org.quartz.SimpleTrigger; -import org.quartz.TriggerKey; +import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import org.quartz.*; import org.quartz.impl.matchers.GroupMatcher; +import org.springframework.core.convert.ConversionService; import org.springframework.stereotype.Service; import java.util.Optional; @@ -17,9 +17,11 @@ public class SchedulerService { public static final int SEC_IN_A_DAY = 60 * 60 * 24; private Scheduler scheduler; + private ConversionService conversionService; - public SchedulerService(Scheduler scheduler) { + public SchedulerService(Scheduler scheduler, ConversionService conversionService) { this.scheduler = scheduler; + this.conversionService = conversionService; } public static int fromTriggerPerDayToMillsInterval(long triggerPerDay) { @@ -57,4 +59,56 @@ public Optional getOneTriggerKey() throws SchedulerException { .findFirst(); } + public TriggerDTO getTriggerByName(String name) throws SchedulerException { + Trigger trigger = scheduler.getTrigger(new TriggerKey(name)); + return conversionService.convert(trigger, TriggerDTO.class); + } + + public TriggerDTO scheduleNewTrigger(String name, String jobClassname, SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { + Class jobClass = (Class) Class.forName(jobClassname); + JobDetail jobDetail = JobBuilder.newJob() + .ofType(jobClass) + .storeDurably(false) + .build(); + + int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); + + Trigger newTrigger = TriggerBuilder.newTrigger() + .withSchedule( + SimpleScheduleBuilder.simpleSchedule() + .withIntervalInMilliseconds(intervalInMills) + .withRepeatCount(config.getMaxCount() - 1) + .withMisfireHandlingInstructionNextWithRemainingCount() + ) + .withIdentity(name) + .build(); + + scheduler.scheduleJob(jobDetail, newTrigger); + + return conversionService.convert(newTrigger, TriggerDTO.class); + } + + public TriggerDTO rescheduleTrigger(String name, SchedulerConfigParam config) throws SchedulerException { + int intervalInMills = SchedulerService.fromTriggerPerDayToMillsInterval(config.getTriggerPerDay()); + + Optional optionalTriggerKey = getTriggerByKey(name); + TriggerKey triggerKey = optionalTriggerKey.orElse(TriggerKey.triggerKey(name)); + Trigger trigger = scheduler.getTrigger(triggerKey); + + Trigger newTrigger = TriggerBuilder.newTrigger() + .withSchedule( + SimpleScheduleBuilder.simpleSchedule() + .withIntervalInMilliseconds(intervalInMills) + .withRepeatCount(config.getMaxCount() - 1) + .withMisfireHandlingInstructionNextWithRemainingCount() + ) + .forJob(trigger.getJobKey().getName()) + .withIdentity(name) + .build(); + + scheduler.rescheduleJob(triggerKey, newTrigger); + + return conversionService.convert(newTrigger, TriggerDTO.class); + } + } diff --git a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml index 371f02a6..d291ec7e 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/pom.xml +++ b/quartz-manager-parent/quartz-manager-web-showcase/pom.xml @@ -41,70 +41,66 @@ - - org.springframework.boot - spring-boot-starter-web - - - org.springframework.boot - spring-boot-starter-security - - - - - - - org.springframework.boot - spring-boot-devtools - org.springframework.boot - spring-boot-configuration-processor - true - - - org.springframework.boot - spring-boot-starter-tomcat - provided - - - org.springframework.boot - spring-boot-starter-test - test - + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-security + + + org.springframework.boot + spring-boot-devtools + + + org.springframework.boot + spring-boot-configuration-processor + true + + + org.springframework.boot + spring-boot-starter-tomcat + provided + + + org.springframework.boot + spring-boot-starter-test + test + - - io.jsonwebtoken - jjwt - 0.9.0 - - - com.fasterxml.jackson.core - jackson-databind - - - com.fasterxml.jackson.core - jackson-annotations - - - com.h2database - h2 - runtime - - - org.codehaus.groovy - groovy - - - net.sourceforge.nekohtml - nekohtml - - - io.rest-assured - spring-mock-mvc - test - + + io.jsonwebtoken + jjwt + 0.9.0 + + + com.fasterxml.jackson.core + jackson-databind + + + com.fasterxml.jackson.core + jackson-annotations + + + com.h2database + h2 + runtime + + + org.codehaus.groovy + groovy + + + net.sourceforge.nekohtml + nekohtml + + + io.rest-assured + spring-mock-mvc + test + org.projectlombok lombok @@ -114,18 +110,6 @@ org.apache.commons commons-lang3 - - - - - - - - - - - - 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 203c5b5d..7c139815 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 @@ -8,10 +8,9 @@ public class SampleJob extends AbstractLoggingJob { - @Override public LogRecord doIt(JobExecutionContext jobExecutionContext) { - return new LogRecord(LogType.INFO, "Hello!"); + return new LogRecord(LogType.INFO, "Hello!"); } } 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 9f468cc2..eb534ff5 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 @@ -13,10 +13,6 @@ spring: mode: LEGACYHTML5 jpa.open-in-view: false -# quartz: -# org.quartz.jobStore.isClustered: true -# org.quartz.scheduler.instanceId=AUTO - quartz: enabled: true diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties index d00f1535..cdcc9e43 100644 --- a/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/main/resources/quartz.properties @@ -1,3 +1,2 @@ org.quartz.scheduler.instanceName=example -org.quartz.scheduler.instanceId=AUTO org.quartz.threadPool.threadCount=1 From f37ad1ae58ed7940003f8140d62f228b5e01dded Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Mon, 1 Nov 2021 13:02:31 +0100 Subject: [PATCH 11/17] #37 added the mockMvcTest for the TriggerController --- .../quartz-manager-common/pom.xml | 40 ++++++++------ .../quartzmanager/common/utils/DateUtils.java | 18 +++++++ .../quartz-manager-starter-api/pom.xml | 7 +++ .../controllers/TriggerController.java | 6 ++- .../quartzmanager/dto/JobKeyDTO.java | 3 ++ .../dto/SchedulerConfigParam.java | 2 + .../quartzmanager/dto/TriggerDTO.java | 2 + .../quartzmanager/dto/TriggerKeyDTO.java | 3 ++ .../QuartManagerApplicationTests.java | 13 +++++ .../controllers/TriggerControllerTest.java | 54 +++++++++++++++++++ .../controllers/utils/TestUtils.java | 15 ++++++ .../controllers/utils/TriggerUtils.java | 33 ++++++++++++ .../controllers/TriggerControllerTest.java | 52 ++++++++++++++++++ .../controllers/utils/TestUtils.java | 15 ++++++ .../controllers/utils/TriggerUtils.java | 33 ++++++++++++ 15 files changed, 278 insertions(+), 18 deletions(-) create mode 100644 quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/DateUtils.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/QuartManagerApplicationTests.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java create mode 100644 quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java create mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java create mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java create mode 100644 quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java diff --git a/quartz-manager-parent/quartz-manager-common/pom.xml b/quartz-manager-parent/quartz-manager-common/pom.xml index cb1510df..a51d260c 100644 --- a/quartz-manager-parent/quartz-manager-common/pom.xml +++ b/quartz-manager-parent/quartz-manager-common/pom.xml @@ -1,17 +1,23 @@ - - 4.0.0 - - it.fabioformosa.quartz-manager - quartz-manager-parent - 3.0.2-SNAPSHOT - - quartz-manager-common - - - - org.projectlombok - lombok - provided - - - \ No newline at end of file + + 4.0.0 + + it.fabioformosa.quartz-manager + quartz-manager-parent + 3.0.2-SNAPSHOT + + quartz-manager-common + + + + org.projectlombok + lombok + provided + + + org.junit.jupiter + junit-jupiter-engine + 5.8.1 + test + + + diff --git a/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/DateUtils.java b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/DateUtils.java new file mode 100644 index 00000000..c0cef7ec --- /dev/null +++ b/quartz-manager-parent/quartz-manager-common/src/main/java/it/fabioformosa/quartzmanager/common/utils/DateUtils.java @@ -0,0 +1,18 @@ +package it.fabioformosa.quartzmanager.common.utils; + +import java.time.Duration; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Date; + +public class DateUtils { + + static public Date fromLocaleDateTimeToDate(LocalDateTime localDateTime){ + return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant()); + } + + static public Date getHoursFromNow(long hours){ + return DateUtils.fromLocaleDateTimeToDate(LocalDateTime.now().plus(Duration.ofHours(hours))); + } + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/pom.xml b/quartz-manager-parent/quartz-manager-starter-api/pom.xml index b200ffa1..395b3f48 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/pom.xml +++ b/quartz-manager-parent/quartz-manager-starter-api/pom.xml @@ -130,6 +130,13 @@ springfox-swagger-ui ${springfox.version} + + + + org.junit.platform + junit-platform-launcher + test + 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 19c3f138..73307698 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 @@ -7,14 +7,17 @@ import lombok.extern.slf4j.Slf4j; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Value; +import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.*; @Slf4j -@RequestMapping("/quartz-manager/triggers") +@RequestMapping(TriggerController.TRIGGER_CONTROLLER_BASE_URL) @RestController @Api(value = "triggers") public class TriggerController { + static public final String TRIGGER_CONTROLLER_BASE_URL = "/quartz-manager/triggers"; + @Value("${quartz-manager.jobClass}") private String jobClassname; @@ -29,6 +32,7 @@ public TriggerDTO getTrigger(@PathVariable String name) throws SchedulerExceptio return schedulerService.getTriggerByName(name); } + @ResponseStatus(HttpStatus.CREATED) @PostMapping("/{name}") public TriggerDTO postTrigger(@PathVariable String name, @RequestBody SchedulerConfigParam config) throws SchedulerException, ClassNotFoundException { log.info("TRIGGER - CREATING a trigger {} {}", name, config); diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java index 1a9bfc3a..d1b302e2 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/JobKeyDTO.java @@ -1,5 +1,8 @@ package it.fabioformosa.quartzmanager.dto; +import lombok.Builder; + +@Builder public class JobKeyDTO { private String name; private String group; diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java index 60026ae1..f259a964 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/SchedulerConfigParam.java @@ -1,11 +1,13 @@ package it.fabioformosa.quartzmanager.dto; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @NoArgsConstructor @AllArgsConstructor +@Builder @Data public class SchedulerConfigParam { public long triggerPerDay; diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java index ff41c222..952c9b5a 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerDTO.java @@ -1,6 +1,7 @@ package it.fabioformosa.quartzmanager.dto; import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Data; import lombok.NoArgsConstructor; @@ -9,6 +10,7 @@ @AllArgsConstructor @NoArgsConstructor @Data +@Builder public class TriggerDTO { private TriggerKeyDTO triggerKeyDTO; private int priority; diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java index 4a26e048..2992b48f 100644 --- a/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java +++ b/quartz-manager-parent/quartz-manager-starter-api/src/main/java/it/fabioformosa/quartzmanager/dto/TriggerKeyDTO.java @@ -1,5 +1,8 @@ package it.fabioformosa.quartzmanager.dto; +import lombok.Builder; + +@Builder public class TriggerKeyDTO { private String name; private String group; diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/QuartManagerApplicationTests.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/QuartManagerApplicationTests.java new file mode 100644 index 00000000..97f14ef8 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/QuartManagerApplicationTests.java @@ -0,0 +1,13 @@ +package it.fabioformosa.quartzmanager; + +import org.junit.Test; +import org.springframework.boot.test.context.SpringBootTest; + +@SpringBootTest +public class QuartManagerApplicationTests { + + @Test + public void contextLoads() { + } + +} 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 new file mode 100644 index 00000000..aabdc42c --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java @@ -0,0 +1,54 @@ +package it.fabioformosa.quartzmanager.controllers; + +import it.fabioformosa.quartzmanager.controllers.utils.TestUtils; +import it.fabioformosa.quartzmanager.controllers.utils.TriggerUtils; +import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import it.fabioformosa.quartzmanager.services.SchedulerService; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.api.Test; +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.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.post; + +@Disabled +@WebMvcTest(controllers = TriggerController.class, properties = { + "quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob" +}) +class TriggerControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private SchedulerService schedulerService; + + @AfterEach + void cleanUp(){ + Mockito.reset(schedulerService); + } + + @Test + void givenASchedulerConfigParam_whenPosted_thenANewTriggerIsCreated() throws Exception { + TriggerDTO expectedTriggerDTO = TriggerUtils.getTriggerInstance(); + Mockito.when(schedulerService.scheduleNewTrigger(any(), any(), any())).thenReturn(expectedTriggerDTO); + + SchedulerConfigParam configParamToPost = SchedulerConfigParam.builder().maxCount(20).triggerPerDay(20000L).build(); + 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))) + ; + } +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java new file mode 100644 index 00000000..34333cfa --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java @@ -0,0 +1,15 @@ +package it.fabioformosa.quartzmanager.controllers.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; + +public class TestUtils { + + static public ObjectMapper objectMapper = new ObjectMapper(); + + @SneakyThrows + static public String toJson(Object object){ + return objectMapper.writeValueAsString(object); + }; + +} diff --git a/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java new file mode 100644 index 00000000..6c04827c --- /dev/null +++ b/quartz-manager-parent/quartz-manager-starter-api/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java @@ -0,0 +1,33 @@ +package it.fabioformosa.quartzmanager.controllers.utils; + +import it.fabioformosa.quartzmanager.common.utils.DateUtils; +import it.fabioformosa.quartzmanager.dto.JobKeyDTO; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO; + +import java.time.LocalDateTime; + +public class TriggerUtils { + + static public TriggerDTO getTriggerInstance(){ + return TriggerDTO.builder() + .description("sample trigger") + .endTime(DateUtils.getHoursFromNow(2L)) + .finalFireTime(DateUtils.getHoursFromNow(2L)) + .jobKeyDTO(JobKeyDTO.builder() + .group("defaultJobGroup") + .name("sampleJob") + .build()) + .mayFireAgain(true) + .triggerKeyDTO(TriggerKeyDTO.builder() + .group("defaultTriggerGroup") + .name("sampleTrigger") + .build()) + .misfireInstruction(1) + .nextFireTime(DateUtils.getHoursFromNow(1L)) + .priority(1) + .startTime(DateUtils.fromLocaleDateTimeToDate(LocalDateTime.now())) + .build(); + } + +} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java new file mode 100644 index 00000000..a4d38797 --- /dev/null +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/TriggerControllerTest.java @@ -0,0 +1,52 @@ +package it.fabioformosa.quartzmanager.controllers; + +import it.fabioformosa.quartzmanager.controllers.utils.TestUtils; +import it.fabioformosa.quartzmanager.controllers.utils.TriggerUtils; +import it.fabioformosa.quartzmanager.dto.SchedulerConfigParam; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import it.fabioformosa.quartzmanager.services.SchedulerService; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Test; +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.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.post; + +@WebMvcTest(controllers = TriggerController.class, properties = { + "quartz-manager.jobClass=it.fabioformosa.quartzmanager.jobs.myjobs.SampleJob" +}) +class TriggerControllerTest { + + @Autowired + private MockMvc mockMvc; + + @MockBean + private SchedulerService schedulerService; + + @AfterEach + void cleanUp(){ + Mockito.reset(schedulerService); + } + + @Test + void givenASchedulerConfigParam_whenPosted_thenANewTriggerIsCreated() throws Exception { + TriggerDTO expectedTriggerDTO = TriggerUtils.getTriggerInstance(); + Mockito.when(schedulerService.scheduleNewTrigger(any(), any(), any())).thenReturn(expectedTriggerDTO); + + SchedulerConfigParam configParamToPost = SchedulerConfigParam.builder().maxCount(20).triggerPerDay(20000L).build(); + 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))) + ; + } +} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java new file mode 100644 index 00000000..34333cfa --- /dev/null +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TestUtils.java @@ -0,0 +1,15 @@ +package it.fabioformosa.quartzmanager.controllers.utils; + +import com.fasterxml.jackson.databind.ObjectMapper; +import lombok.SneakyThrows; + +public class TestUtils { + + static public ObjectMapper objectMapper = new ObjectMapper(); + + @SneakyThrows + static public String toJson(Object object){ + return objectMapper.writeValueAsString(object); + }; + +} diff --git a/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java new file mode 100644 index 00000000..6c04827c --- /dev/null +++ b/quartz-manager-parent/quartz-manager-web-showcase/src/test/java/it/fabioformosa/quartzmanager/controllers/utils/TriggerUtils.java @@ -0,0 +1,33 @@ +package it.fabioformosa.quartzmanager.controllers.utils; + +import it.fabioformosa.quartzmanager.common.utils.DateUtils; +import it.fabioformosa.quartzmanager.dto.JobKeyDTO; +import it.fabioformosa.quartzmanager.dto.TriggerDTO; +import it.fabioformosa.quartzmanager.dto.TriggerKeyDTO; + +import java.time.LocalDateTime; + +public class TriggerUtils { + + static public TriggerDTO getTriggerInstance(){ + return TriggerDTO.builder() + .description("sample trigger") + .endTime(DateUtils.getHoursFromNow(2L)) + .finalFireTime(DateUtils.getHoursFromNow(2L)) + .jobKeyDTO(JobKeyDTO.builder() + .group("defaultJobGroup") + .name("sampleJob") + .build()) + .mayFireAgain(true) + .triggerKeyDTO(TriggerKeyDTO.builder() + .group("defaultTriggerGroup") + .name("sampleTrigger") + .build()) + .misfireInstruction(1) + .nextFireTime(DateUtils.getHoursFromNow(1L)) + .priority(1) + .startTime(DateUtils.fromLocaleDateTimeToDate(LocalDateTime.now())) + .build(); + } + +} From 95fa10272056c959cc50ffc606c5e78b8be976b5 Mon Sep 17 00:00:00 2001 From: Fabio Formosa Date: Mon, 1 Nov 2021 16:17:29 +0100 Subject: [PATCH 12/17] #39 changed the appearance of the fields in the config param form --- .../scheduler-config.component.html | 14 +++++++++--- .../scheduler-config.component.ts | 2 ++ .../quartzmanager/dto/JobKeyDTO.java | 22 +++++-------------- .../quartzmanager/dto/TriggerKeyDTO.java | 22 +++++-------------- .../src/main/resources/application.yml | 2 +- 5 files changed, 26 insertions(+), 36 deletions(-) diff --git a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html index fce2ade3..cf397306 100644 --- a/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html +++ b/quartz-manager-frontend/src/app/components/scheduler-config/scheduler-config.component.html @@ -14,13 +14,15 @@
- + + Freq [Num per day] - + + Max Occurrences Misfire Policy
+