Imports System.Collections.Specialized Imports DigitalData.Modules.Database Imports DigitalData.Modules.Logging Imports Quartz Imports Quartz.Impl Imports Quartz.Impl.Matchers Imports Quartz.Logging Public Class Scheduler Private _Factory As StdSchedulerFactory Private _MSSQL As MSSQLServer Private _Scheduler As IScheduler Private _LogConfig As LogConfig Private _Logger As DigitalData.Modules.Logging.Logger Private _JobListener As JobListener Private _Props = New NameValueCollection From { {"quartz.serializer.type", "binary"} } Private Const JOB_GROUP As String = "DatatableJobs" Public Sub New(LogConfig As LogConfig, MSSQL_ECM As MSSQLServer, TableStore As DataSet) _LogConfig = LogConfig _Logger = LogConfig.GetLogger() _Factory = New StdSchedulerFactory(_Props) _MSSQL = MSSQL_ECM _JobListener = New JobListener(LogConfig, _MSSQL, TableStore) Logging.LogProvider.SetCurrentLogProvider(New LogProvider(_Logger)) End Sub Public Async Sub Start() ' Get new scheduler _Scheduler = Await _Factory.GetScheduler() ' configure it _Scheduler.ListenerManager.AddJobListener(_JobListener, GroupMatcher(Of JobKey).GroupEquals(JOB_GROUP)) ' start it Await _Scheduler.Start() Dim oCronjobs As DataTable = Await GetCronJobs() Try If oCronjobs IsNot Nothing Then _Logger.Debug("Loaded {0} cron jobs", oCronjobs.Rows.Count) For Each oRow As DataRow In oCronjobs.Rows Dim oDefinition As String = oRow.Item("CRON_DEFINITION") Dim oTitle As String = oRow.Item("TITLE") Dim oGuid As Integer = oRow.Item("GUID") Dim oCronTrigger As ITrigger Dim oInitTrigger As ITrigger Dim oJob As IJobDetail Dim oInitJob As IJobDetail Dim oJobData As New JobDataMap From { {"LogConfig", _LogConfig}, {"MSSQL", _MSSQL}, {"CronJobId", oGuid}, {"CronJobTitle", oTitle} } Dim oIdentity As String = $"CRON-JOB-{oGuid}" oCronTrigger = TriggerBuilder.Create(). WithIdentity(oIdentity & "-TRIGGER", JOB_GROUP). WithCronSchedule(oDefinition). Build() oJob = JobBuilder.Create(Of DatatableJob)(). WithIdentity(oIdentity, JOB_GROUP). UsingJobData(oJobData). Build() Await _Scheduler.ScheduleJob(oJob, oCronTrigger) ' Also create variant of the job that runs immediately, once Dim oInitIdentity As String = $"CRON-JOB-INIT-{oGuid}" oInitTrigger = TriggerBuilder.Create(). WithIdentity(oInitIdentity & "-TRIGGER", JOB_GROUP). StartNow(). Build() oInitJob = JobBuilder.Create(Of DatatableJob)(). WithIdentity(oInitIdentity, JOB_GROUP). UsingJobData(oJobData). Build() Await _Scheduler.ScheduleJob(oInitJob, oInitTrigger) _Logger.Debug("Scheduled a new job for Cron Job [{0}]", oTitle) Next Else _Logger.Warn("CronJobs could not be fetched!") End If Catch ex As Exception _Logger.Error(ex) _Logger.Warn("Unexpected Error while setting up scheduler: " & ex.Message) End Try End Sub Public Async Function GetCronJobs() As Task(Of DataTable) Try Dim oSQL As String = "SELECT * FROM TBAPPSERV_CRON_JOB WHERE ACTIVE = 1" Dim oDatatable As DataTable = Await _MSSQL.GetDatatableAsync(oSQL) Return oDatatable Catch ex As Exception Return Nothing End Try End Function Public Async Function GetCronJobDetails(CronJobId As Integer) As Task(Of DataTable) Try Dim oSQL As String = $"SELECT * FROM TBAPPSERV_CRON_DETAIL WHERE CRON_ID = {CronJobId}" Dim oDatatable As DataTable = Await _MSSQL.GetDatatableAsync(oSQL) Return oDatatable Catch ex As Exception Return Nothing End Try End Function Public Async Sub [Stop]() Await _Scheduler.Shutdown() End Sub Private Class LogProvider Implements ILogProvider Private _Logger As Modules.Logging.Logger Public Sub New(Logger As DigitalData.Modules.Logging.Logger) MyBase.New() _Logger = Logger End Sub Public Function OpenNestedContext(message As String) As IDisposable Implements ILogProvider.OpenNestedContext Throw New NotImplementedException() End Function Public Function OpenMappedContext(key As String, value As Object, Optional destructure As Boolean = False) As IDisposable Implements ILogProvider.OpenMappedContext Throw New NotImplementedException() End Function Private Function GetLogger(name As String) As Logging.Logger Implements ILogProvider.GetLogger Return Function(level, func, exception, parameters) If exception IsNot Nothing Then _Logger.Error(exception) ElseIf level >= LogLevel.Debug AndAlso func IsNot Nothing Then _Logger.Debug(func(), parameters) ElseIf level >= LogLevel.Info AndAlso func IsNot Nothing Then _Logger.Info(func(), parameters) End If Return True End Function End Function End Class End Class