From 17994d1acd7034f44a9ac725b7e709b751351440 Mon Sep 17 00:00:00 2001 From: LO Kam Tao Leo Date: Thu, 3 Mar 2022 13:28:03 +0000 Subject: [PATCH] Skeleton to run a scheduled job --- pom.xml | 18 ++-- src/org/leolo/rail/ConfigurationManager.java | 10 +++ src/org/leolo/rail/Constants.java | 16 +++- src/org/leolo/rail/LongTermScheduleJob.java | 42 +++++++++ src/org/leolo/rail/NRDataDamon.java | 62 +++++++++++--- src/org/leolo/rail/dao/MetadataDao.java | 123 +++++++++++++++++++++++++++ 6 files changed, 252 insertions(+), 19 deletions(-) create mode 100644 src/org/leolo/rail/LongTermScheduleJob.java create mode 100644 src/org/leolo/rail/dao/MetadataDao.java diff --git a/pom.xml b/pom.xml index 0e19efe..4ada8d7 100644 --- a/pom.xml +++ b/pom.xml @@ -41,15 +41,21 @@ 2.13.3 - org.quartz-scheduler - quartz - 2.3.2 + org.quartz-scheduler + quartz + 2.3.2 - org.apache.activemq - activemq-stomp - 5.16.4 + org.apache.activemq + activemq-stomp + 5.16.4 + + \ No newline at end of file diff --git a/src/org/leolo/rail/ConfigurationManager.java b/src/org/leolo/rail/ConfigurationManager.java index cb8b4b8..7883ca6 100644 --- a/src/org/leolo/rail/ConfigurationManager.java +++ b/src/org/leolo/rail/ConfigurationManager.java @@ -71,4 +71,14 @@ public class ConfigurationManager { return Integer.parseInt(prop.getProperty(key)); return defaultValue; } + + public boolean getBoolean(String key) { + return getBoolean(key, false); + } + + public boolean getBoolean(String key, boolean defaultValue) { + if(prop.containsKey(key)) + return Boolean.parseBoolean(prop.getProperty(key)); + return defaultValue; + } } diff --git a/src/org/leolo/rail/Constants.java b/src/org/leolo/rail/Constants.java index 4612ace..cc562a7 100644 --- a/src/org/leolo/rail/Constants.java +++ b/src/org/leolo/rail/Constants.java @@ -4,18 +4,28 @@ public class Constants { public static class NetworkRail{ - - public static final String TOPIC_NAME_VTSP = "/topic/VSTP_ALL"; public static final String TOPIC_NAME_MVT = "/topic/TRAIN_MVT_ALL_TOC"; - } public static class Generic{ public static final long DEFAULT_SLEEP_TIME = 1000; public static final long INCRESE_RATIO = 2; public static final boolean DEBUG_MODE = true; + public static final long LTR_FORCE_RUN_THRESHOLD = 108_000_000; //1.25 days + public static final long LTR_SKIP_THRESHOLD = 21_600_000; //0.25 days } + public static class Scheduler{ + + public static final String DEFAULT_GROUP_NAME = "dgroup"; + + public static final String LTSJ_CRON_TRIGGER = "T-LTSJ-C"; + + } + + public static class Metadata{ + public static final String LAST_NETOWRK_RAIL_SCHEDULE_UPD = "LNeRSchUpd"; + } } diff --git a/src/org/leolo/rail/LongTermScheduleJob.java b/src/org/leolo/rail/LongTermScheduleJob.java new file mode 100644 index 0000000..c3b1dbd --- /dev/null +++ b/src/org/leolo/rail/LongTermScheduleJob.java @@ -0,0 +1,42 @@ +package org.leolo.rail; + +import java.sql.SQLException; +import java.util.Date; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.leolo.rail.dao.MetadataDao; +import org.quartz.Job; +import org.quartz.JobExecutionContext; +import org.quartz.JobExecutionException; +import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerKey; +import org.quartz.impl.matchers.GroupMatcher; + +public class LongTermScheduleJob implements Job{ + + private Logger log = LogManager.getLogger(LongTermScheduleJob.class); + + @Override + public void execute(JobExecutionContext context) throws JobExecutionException { + MetadataDao mDao = new MetadataDao(); + log.atInfo().log("LongTermScheduleJob started."); + + try { + TriggerKey triggerKey = TriggerKey.triggerKey(Constants.Scheduler.LTSJ_CRON_TRIGGER, Constants.Scheduler.DEFAULT_GROUP_NAME); + Trigger trigger = context.getScheduler().getTrigger(triggerKey); + Date nextFireTime = trigger.getNextFireTime(); + log.info("Next fire at "+nextFireTime); + long timeToNextFire = nextFireTime.getTime() - System.currentTimeMillis(); + if(timeToNextFire > Constants.Generic.LTR_SKIP_THRESHOLD && !ConfigurationManager.getInstance().getBoolean("general.debug", false)) { + log.always().log("Too close to next fire time. Skipping"); + return; + } + } catch (SchedulerException e) { + log.atError().log(e.getMessage(),e); + } + + } + +} diff --git a/src/org/leolo/rail/NRDataDamon.java b/src/org/leolo/rail/NRDataDamon.java index e252c17..fd34db1 100644 --- a/src/org/leolo/rail/NRDataDamon.java +++ b/src/org/leolo/rail/NRDataDamon.java @@ -4,19 +4,30 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; import java.net.UnknownHostException; +import java.sql.SQLException; +import java.util.Date; import org.apache.activemq.transport.stomp.StompConnection; import org.apache.activemq.transport.stomp.StompFrame; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.leolo.rail.dao.MetadataDao; +import org.quartz.CronScheduleBuilder; +import org.quartz.DateBuilder; +import org.quartz.JobBuilder; +import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerBuilder; import org.quartz.impl.StdSchedulerFactory; public class NRDataDamon { private Logger log = LogManager.getLogger(getClass()); + public static Scheduler scheduler = null; + NetowrkRailProcessingThread nrpt; public static void main(String [] args) { @@ -32,20 +43,51 @@ public class NRDataDamon { DatabaseManager.getInstance().testPool(); log.info("Database connected"); try { - Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler(); + scheduler = StdSchedulerFactory.getDefaultScheduler(); scheduler.start(); + //Schedule new scheduled job + try { + Date lastLTRDate = new MetadataDao().getDate(Constants.Metadata.LAST_NETOWRK_RAIL_SCHEDULE_UPD); + boolean scheduleJob = lastLTRDate == null; + if(!scheduleJob) { + long diff = System.currentTimeMillis() - lastLTRDate.getTime(); + if(diff > Constants.Generic.LTR_FORCE_RUN_THRESHOLD) { + scheduleJob = true; + } + } + if(scheduleJob) { + JobDetail jd = JobBuilder.newJob(LongTermScheduleJob.class).withIdentity("J-LTSJ-OF", Constants.Scheduler.DEFAULT_GROUP_NAME).build(); + log.atInfo().log("An extra execution of LT Schedule is scheduled"); + Date rd = DateBuilder.evenMinuteDateAfterNow(); + log.atInfo().log("Running LT Schedule at {}", rd); + Trigger t = TriggerBuilder.newTrigger() + .withIdentity("T-LTSJ-OF", Constants.Scheduler.DEFAULT_GROUP_NAME) + .startAt(rd) + .build(); + scheduler.scheduleJob(jd, t); + } + JobDetail jd = JobBuilder.newJob(LongTermScheduleJob.class).withIdentity("J-LTSJ-C", Constants.Scheduler.DEFAULT_GROUP_NAME).build(); + Trigger t = TriggerBuilder.newTrigger() + .withIdentity(Constants.Scheduler.LTSJ_CRON_TRIGGER, Constants.Scheduler.DEFAULT_GROUP_NAME) + .withSchedule(CronScheduleBuilder.cronSchedule("30 30 2 * * ?")) + .build(); + scheduler.scheduleJob(jd, t); + + } catch (SQLException e) { + log.atError().log(e.getMessage(), e); + } } catch (SchedulerException e) { // TODO Auto-generated catch block e.printStackTrace(); } - NRDataDamon ndd = new NRDataDamon(); - try { - ndd.init(); - ndd.run(); - } catch (Exception e) { - log.error(e.getMessage(), e); - System.exit(-1); - } +// NRDataDamon ndd = new NRDataDamon(); +// try { +//// ndd.init(); +//// ndd.run(); +// } catch (Exception e) { +// log.error(e.getMessage(), e); +// System.exit(-1); +// } } public void init() throws Exception { @@ -60,7 +102,7 @@ public class NRDataDamon { log.warn("Network Rail processing thread died. Restarting..."); nrpt = new NetowrkRailProcessingThread(); nrpt.init(); - nrpt.start(); +// nrpt.start(); } try { Thread.sleep(2500); diff --git a/src/org/leolo/rail/dao/MetadataDao.java b/src/org/leolo/rail/dao/MetadataDao.java new file mode 100644 index 0000000..5eb5299 --- /dev/null +++ b/src/org/leolo/rail/dao/MetadataDao.java @@ -0,0 +1,123 @@ +package org.leolo.rail.dao; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.Date; + +import org.leolo.rail.DatabaseManager; + +public class MetadataDao { + + + public String getString(String key) throws SQLException{ + return getString(key, null); + } + + public String getString(String key, String defaultValue) throws SQLException{ + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("SELECT metadata_value FROM metadata WHERE metadata_name = ?"); + ){ + pstmt.setString(1, key); + try(ResultSet rs = pstmt.executeQuery()){ + if(rs.next()) { + return rs.getString("metadata_value"); + } + } + } + return defaultValue; + } + + public long getLong(String key) throws SQLException{ + return getLong(key, 0); + } + + public long getLong(String key, long defaultValue) throws SQLException{ + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("SELECT metadata_value FROM metadata WHERE metadata_name = ?"); + ){ + pstmt.setString(1, key); + try(ResultSet rs = pstmt.executeQuery()){ + if(rs.next()) { + return rs.getLong("metadata_value"); + } + } + } + return defaultValue; + } + + public Date getDate(String key) throws SQLException{ + return getDate(key, null); + } + + public Date getDate(String key, Date defaultValue) throws SQLException{ + long val = getLong(key, Long.MIN_VALUE); + if(val==Long.MIN_VALUE) { + return defaultValue; + } + return new Date(val); + } + + public void setString(String key, String value) throws SQLException{ + if(value!=null) { + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO metadata (metadata_name, metadata_value) VALUES (?,?)"); + ){ + pstmt.setString(1, key); + pstmt.setString(2, value); + pstmt.executeUpdate(); + conn.commit(); + } + }else { + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("DELETE FROM metadata WHERE metadata_name=?"); + ){ + pstmt.setString(1, key); + pstmt.executeUpdate(); + conn.commit(); + } + } + } + + public void setLong(String key, long value) throws SQLException{ + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO metadata (metadata_name, metadata_value) VALUES (?,?)"); + ){ + pstmt.setString(1, key); + pstmt.setLong(2, value); + pstmt.executeUpdate(); + conn.commit(); + } + } + + + public void setDate(String key, Date value) throws SQLException{ + if(value!=null) { + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("REPLACE INTO metadata (metadata_name, metadata_value) VALUES (?,?)"); + ){ + pstmt.setString(1, key); + pstmt.setLong(2, value.getTime()); + pstmt.executeUpdate(); + conn.commit(); + } + }else { + try( + Connection conn = DatabaseManager.getInstance().getConnection(); + PreparedStatement pstmt = conn.prepareStatement("DELETE FROM metadata WHERE metadata_name=?"); + ){ + pstmt.setString(1, key); + pstmt.executeUpdate(); + conn.commit(); + } + } + } + +}