From bdff38410c7b0b8303e14febaee032764df5e692 Mon Sep 17 00:00:00 2001 From: Jonathan Jenne Date: Fri, 1 Dec 2023 15:05:41 +0100 Subject: [PATCH] scheduler --- EnvelopeGenerator.Common/Constants.vb | 7 +++ .../EnvelopeGenerator.Common.vbproj | 9 ++++ .../Jobs/CertificateDocumentJob.vb | 20 ++++++++ .../Services/ActionService.vb | 49 ++++++++++++++----- .../Services/EmailService.vb | 25 ++++------ .../Services/HistoryService.vb | 10 +++- EnvelopeGenerator.Common/packages.config | 5 ++ .../Controllers/EnvelopeEditorController.vb | 27 ++-------- .../Controllers/DocumentController.cs | 2 +- .../Controllers/EnvelopeController.cs | 2 +- .../EnvelopeGenerator.Web.csproj | 4 ++ EnvelopeGenerator.Web/Program.cs | 25 ++++++++++ EnvelopeGenerator.Web/Scheduler.cs | 44 +++++++++++++++++ 13 files changed, 178 insertions(+), 51 deletions(-) create mode 100644 EnvelopeGenerator.Common/Jobs/CertificateDocumentJob.vb create mode 100644 EnvelopeGenerator.Common/packages.config create mode 100644 EnvelopeGenerator.Web/Scheduler.cs diff --git a/EnvelopeGenerator.Common/Constants.vb b/EnvelopeGenerator.Common/Constants.vb index 678219e7..0883a995 100644 --- a/EnvelopeGenerator.Common/Constants.vb +++ b/EnvelopeGenerator.Common/Constants.vb @@ -56,4 +56,11 @@ End Enum #End Region + +#Region "Constants" + + Public Const DATABASE = "DATABASE" + Public Const LOGCONFIG = "LOGCONFIG" + +#End Region End Class diff --git a/EnvelopeGenerator.Common/EnvelopeGenerator.Common.vbproj b/EnvelopeGenerator.Common/EnvelopeGenerator.Common.vbproj index 484a9531..442d5ff3 100644 --- a/EnvelopeGenerator.Common/EnvelopeGenerator.Common.vbproj +++ b/EnvelopeGenerator.Common/EnvelopeGenerator.Common.vbproj @@ -75,14 +75,21 @@ ..\..\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll + + ..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll + ..\packages\NLog.5.0.5\lib\net46\NLog.dll + + ..\packages\Quartz.3.8.0\lib\net462\Quartz.dll + + @@ -123,6 +130,7 @@ + @@ -246,6 +254,7 @@ My Settings.Designer.vb + diff --git a/EnvelopeGenerator.Common/Jobs/CertificateDocumentJob.vb b/EnvelopeGenerator.Common/Jobs/CertificateDocumentJob.vb new file mode 100644 index 00000000..e658ba2f --- /dev/null +++ b/EnvelopeGenerator.Common/Jobs/CertificateDocumentJob.vb @@ -0,0 +1,20 @@ +Imports DigitalData.Modules.Logging +Imports Quartz + +Public Class CertificateDocumentJob + Implements IJob + + Public Function Execute(context As IJobExecutionContext) As Task Implements IJob.Execute + Dim connectionString As String = context.MergedJobDataMap.Item(Constants.DATABASE) + Dim logConfig As LogConfig = context.MergedJobDataMap.Item(Constants.LOGCONFIG) + Dim logger As Logger = logConfig.GetLogger + + Dim JobId = context.JobDetail.Key + logger.Info("Starting job {0}", JobId) + + ' Do important work... + + logger.Info("Completed job {0}", JobId) + Return Task.FromResult(True) + End Function +End Class diff --git a/EnvelopeGenerator.Common/Services/ActionService.vb b/EnvelopeGenerator.Common/Services/ActionService.vb index 2a6d1d32..6dbd8b22 100644 --- a/EnvelopeGenerator.Common/Services/ActionService.vb +++ b/EnvelopeGenerator.Common/Services/ActionService.vb @@ -15,36 +15,63 @@ Public Class ActionService EmailService = New EmailService(pState) HistoryService = New HistoryService(pState) - ReceiverModel = New ReceiverModel(pState) End Sub + Public Function SendEnvelope(pEnvelope As Envelope) As Boolean + If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.EnvelopeQueued, pEnvelope.User.Email) = False Then + Return False + End If + + Dim oSendResult = pEnvelope.Receivers. + Select(Function(r) EmailService.SendDocumentReceivedEmail(pEnvelope, r)). + All(Function(r) r = True) + + If oSendResult = False Then + Return False + End If + + Return True + End Function + Public Function DeleteEnvelope(pEnvelope As Envelope) As Boolean - HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.EnvelopeDeleted, pEnvelope.User.Email) + If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.EnvelopeDeleted, pEnvelope.User.Email) = False Then + Return False + End If + + Dim oSendResult = pEnvelope.Receivers. + Select(Function(r) EmailService.SendEnvelopeDeletedEmail(pEnvelope, r)). + All(Function(r) r = True) + + If oSendResult = False Then + Return False + End If For Each oReceiver As EnvelopeReceiver In pEnvelope.Receivers - EmailService.SendEnvelopeDeletedEmail(oReceiver.Id, pEnvelope.Id) + EmailService.SendEnvelopeDeletedEmail(pEnvelope, oReceiver) Next Return True End Function - Public Function OpenEnvelope(pEnvelope As Envelope, pReceiverId As Integer) As Boolean - Dim oReceiver As EnvelopeReceiver = ReceiverModel.GetById(pReceiverId) - Dim oUserReference = oReceiver.Email + Public Function OpenEnvelope(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean + Dim oUserReference = pReceiver.Email - Return HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.DocumentOpened, oUserReference) + If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.DocumentOpened, oUserReference) = False Then + Return False + End If + + Return True End Function - Public Function SignEnvelope(pEnvelope As Envelope, pReceiverId As Integer) As Boolean - Dim oReceiver As EnvelopeReceiver = ReceiverModel.GetById(pReceiverId) - Dim oUserReference = oReceiver.Email + Public Function SignEnvelope(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean + Dim oUserReference = pReceiver.Email If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.DocumentSigned, oUserReference) = False Then Return False End If - Return EmailService.SendSignedEmail(oReceiver.Id, pEnvelope.Id) + Return EmailService.SendSignedEmail(pEnvelope, pReceiver) End Function diff --git a/EnvelopeGenerator.Common/Services/EmailService.vb b/EnvelopeGenerator.Common/Services/EmailService.vb index bd697836..cbc26758 100644 --- a/EnvelopeGenerator.Common/Services/EmailService.vb +++ b/EnvelopeGenerator.Common/Services/EmailService.vb @@ -23,11 +23,8 @@ Public Class EmailService EmailTemplate = New EmailTemplate() End Sub - Public Function SendEnvelopeDeletedEmail(pReceiverId As Integer, pEnvelopeId As Integer) As Boolean - Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) - Dim oReceiver = ReceiverModel.GetById(pReceiverId) - - Dim oEmailData As New EmailData(oEnvelope, oReceiver) With + Public Function SendEnvelopeDeletedEmail(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean + Dim oEmailData As New EmailData(pEnvelope, pReceiver) With { .SignatureLink = "" } @@ -42,13 +39,10 @@ Public Class EmailService Return True End Function - Public Function SendInitialEmail(pReceiverId As Integer, pEnvelopeId As Integer) As Boolean - Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) - Dim oReceiver = ReceiverModel.GetById(pReceiverId) - - Dim oEmailData As New EmailData(oEnvelope, oReceiver) With + Public Function SendDocumentReceivedEmail(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean + Dim oEmailData As New EmailData(pEnvelope, pReceiver) With { - .SignatureLink = Helpers.GetEnvelopeURL(State.DbConfig.SignatureHost, oEnvelope.Uuid, oReceiver.Signature) + .SignatureLink = Helpers.GetEnvelopeURL(State.DbConfig.SignatureHost, pEnvelope.Uuid, pReceiver.Signature) } EmailTemplate.FillDocumentReceivedEmailBody(oEmailData) @@ -61,11 +55,12 @@ Public Class EmailService Return True End Function - Public Function SendSignedEmail(pReceiverId As Integer, pEnvelopeId As Integer) As Boolean - Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) - Dim oReceiver = ReceiverModel.GetById(pReceiverId) + Public Function SendSignedEmail(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean + Dim oEmailData = New EmailData(pEnvelope, pReceiver) With + { + .SignatureLink = "" + } - Dim oEmailData = New EmailData(oEnvelope, oReceiver) With {.SignatureLink = ""} EmailTemplate.FillDocumentSignedEmailBody(oEmailData) If EmailModel.Insert(oEmailData) = False Then diff --git a/EnvelopeGenerator.Common/Services/HistoryService.vb b/EnvelopeGenerator.Common/Services/HistoryService.vb index ae341a66..587590d6 100644 --- a/EnvelopeGenerator.Common/Services/HistoryService.vb +++ b/EnvelopeGenerator.Common/Services/HistoryService.vb @@ -22,11 +22,19 @@ Public Class HistoryService End Sub Public Function SetEnvelopeStatus(pEnvelope As Envelope, pStatus As EnvelopeStatus, pUserReference As String) As Boolean - Return HistoryModel.Insert(New EnvelopeHistoryEntry() With { + Dim oResult = HistoryModel.Insert(New EnvelopeHistoryEntry() With { .EnvelopeId = pEnvelope.Id, .ActionDate = Now(), .Status = pStatus, .UserReference = pUserReference }) + + If oResult = False Then + Logger.Warn("Could not set Envelope status to [{0}] for Envelope [{1}].", pStatus.ToString, pEnvelope.Id) + Return False + End If + + Logger.Debug("Envelope status set to [{0}] for Envelope [{1}].", pStatus.ToString, pEnvelope.Id) + Return True End Function End Class diff --git a/EnvelopeGenerator.Common/packages.config b/EnvelopeGenerator.Common/packages.config new file mode 100644 index 00000000..ce073819 --- /dev/null +++ b/EnvelopeGenerator.Common/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/EnvelopeGenerator.Form/Controllers/EnvelopeEditorController.vb b/EnvelopeGenerator.Form/Controllers/EnvelopeEditorController.vb index c2cab334..39567bb6 100644 --- a/EnvelopeGenerator.Form/Controllers/EnvelopeEditorController.vb +++ b/EnvelopeGenerator.Form/Controllers/EnvelopeEditorController.vb @@ -10,6 +10,8 @@ Public Class EnvelopeEditorController Public ReadOnly Envelope As Envelope = Nothing Public ReadOnly EmailService As EmailService + Public ReadOnly ActionService As ActionService + Public ReadOnly Thumbnail As Thumbnail @@ -19,6 +21,7 @@ Public Class EnvelopeEditorController Envelope = CreateEnvelope() Thumbnail = New Thumbnail(pState.LogConfig) EmailService = New EmailService(pState) + ActionService = New ActionService(pState) End Sub Public Sub New(pState As State, pEnvelope As Envelope) @@ -29,32 +32,12 @@ Public Class EnvelopeEditorController Envelope.Receivers = ReceiverModel.ListEnvelopeReceivers(pEnvelope.Id).ToList() Thumbnail = New Thumbnail(pState.LogConfig) - EmailService = New EmailService(pState) + ActionService = New ActionService(pState) End Sub #Region "Public" Public Function SendEnvelope() As Boolean - - For Each receiverItem As EnvelopeReceiver In Envelope.Receivers - If EmailService.SendInitialEmail(receiverItem.Id, Envelope.Id) = False Then - Logger.Warn("Email could not be sent.") - Return False - End If - Next - - Dim newHistoryEntry As New EnvelopeHistoryEntry With { - .EnvelopeId = Envelope.Id, - .Status = EnvelopeStatus.EnvelopeQueued, - .UserReference = Envelope.User.Email - } - - If HistoryModel.Insert(newHistoryEntry) Then - Return True - Else - Logger.Warn("History Entry could not be created!") - Return False - End If - + Return ActionService.SendEnvelope(Envelope) End Function Public Function ValidateEnvelopeForSending(pErrors As List(Of String)) As List(Of String) diff --git a/EnvelopeGenerator.Web/Controllers/DocumentController.cs b/EnvelopeGenerator.Web/Controllers/DocumentController.cs index 1801dc23..95ebb7b1 100644 --- a/EnvelopeGenerator.Web/Controllers/DocumentController.cs +++ b/EnvelopeGenerator.Web/Controllers/DocumentController.cs @@ -56,7 +56,7 @@ namespace EnvelopeGenerator.Web.Controllers envelopeService.EnsureValidEnvelopeKey(envelopeKey); EnvelopeResponse response = envelopeService.LoadEnvelope(envelopeKey); - actionService.OpenEnvelope(response.Envelope, response.Receiver.Id); + actionService.OpenEnvelope(response.Envelope, response.Receiver); return Ok(); } diff --git a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs index 308f5361..0edd5332 100644 --- a/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs +++ b/EnvelopeGenerator.Web/Controllers/EnvelopeController.cs @@ -64,7 +64,7 @@ namespace EnvelopeGenerator.Web.Controllers //emailService.SendSignedEmail(response.Receiver.Id, response.Envelope.Id); - var signResult = actionService?.SignEnvelope(response.Envelope, response.Receiver.Id); + var signResult = actionService?.SignEnvelope(response.Envelope, response.Receiver); return Ok(); } diff --git a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj index 2f938db2..2e3f85ed 100644 --- a/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj +++ b/EnvelopeGenerator.Web/EnvelopeGenerator.Web.csproj @@ -9,6 +9,10 @@ + + + + diff --git a/EnvelopeGenerator.Web/Program.cs b/EnvelopeGenerator.Web/Program.cs index 6c896479..427eb42e 100644 --- a/EnvelopeGenerator.Web/Program.cs +++ b/EnvelopeGenerator.Web/Program.cs @@ -1,4 +1,7 @@ +using DigitalData.Modules.Logging; +using EnvelopeGenerator.Common; using EnvelopeGenerator.Web.Services; +using Quartz; namespace EnvelopeGenerator.Web { @@ -18,6 +21,14 @@ namespace EnvelopeGenerator.Web // Add services to the container. builder.Services.AddControllersWithViews(); + // Configure and start scheduler + builder.Services.AddQuartz(q => + { + Scheduler scheduler = InitScheduler(builder); + scheduler.ScheduleJob(q, "CertificateDocument", 5); + }); + builder.Services.AddQuartzHostedService(); + var app = builder.Build(); // Configure the HTTP request pipeline. @@ -39,5 +50,19 @@ namespace EnvelopeGenerator.Web app.Run(); } + + private static LogConfig InitLogger(WebApplicationBuilder builder) + { + string logPath = builder.Configuration.GetValue("Config:LogPath"); + return new LogConfig(LogConfig.PathType.CustomPath, logPath, "Scheduler", "Digital Data", "ECM.EnvelopeGenerator.Web"); + } + + private static Scheduler InitScheduler( WebApplicationBuilder builder) + { + LogConfig logConfig = InitLogger(builder); + string connectionString = builder.Configuration.GetValue("Config:ConnectionString"); + Scheduler scheduler = new(logConfig, connectionString); + return scheduler; + } } } \ No newline at end of file diff --git a/EnvelopeGenerator.Web/Scheduler.cs b/EnvelopeGenerator.Web/Scheduler.cs new file mode 100644 index 00000000..7c46cecb --- /dev/null +++ b/EnvelopeGenerator.Web/Scheduler.cs @@ -0,0 +1,44 @@ +using DigitalData.Modules.Base; +using DigitalData.Modules.Logging; +using EnvelopeGenerator.Common; +using Quartz; +using System; +using System.Collections.Specialized; +using System.ComponentModel.DataAnnotations; + +namespace EnvelopeGenerator.Web +{ + public class Scheduler : BaseClass + { + private const string DATABASE = "DATABASE"; + private const string LOGCONFIG = "LOGCONFIG"; + + private string ConnectionString; + + public Scheduler(LogConfig logConfig, string connectionString) : base(logConfig) + { + this.ConnectionString = connectionString; + } + + public void ScheduleJob(IServiceCollectionQuartzConfigurator q, string name, int interval) where TJob : IJob + { + var jobKey = new JobKey(name); + var jobData = new JobDataMap + { + { DATABASE, ConnectionString }, + { LOGCONFIG, LogConfig } + }; + + q.AddJob(opts => opts + .WithIdentity(jobKey) + .UsingJobData(jobData)); + + q.AddTrigger(opts => opts + .ForJob(jobKey) + .WithIdentity($"{name}-trigger") + .WithSimpleSchedule(s => s + .RepeatForever() + .WithIntervalInMinutes(interval))); + } + } +}