scheduler

This commit is contained in:
Jonathan Jenne 2023-12-01 15:05:41 +01:00
parent 3ca992e043
commit bdff38410c
13 changed files with 178 additions and 51 deletions

View File

@ -56,4 +56,11 @@
End Enum End Enum
#End Region #End Region
#Region "Constants"
Public Const DATABASE = "DATABASE"
Public Const LOGCONFIG = "LOGCONFIG"
#End Region
End Class End Class

View File

@ -75,14 +75,21 @@
<HintPath>..\..\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath> <HintPath>..\..\DDModules\Logging\bin\Debug\DigitalData.Modules.Logging.dll</HintPath>
</Reference> </Reference>
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=2.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\packages\Microsoft.Extensions.Logging.Abstractions.2.1.1\lib\netstandard2.0\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL"> <Reference Include="NLog, Version=5.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath> <HintPath>..\packages\NLog.5.0.5\lib\net46\NLog.dll</HintPath>
</Reference> </Reference>
<Reference Include="Quartz, Version=3.8.0.0, Culture=neutral, PublicKeyToken=f6b8c98a402cc8a4, processorArchitecture=MSIL">
<HintPath>..\packages\Quartz.3.8.0\lib\net462\Quartz.dll</HintPath>
</Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.IO.Compression" /> <Reference Include="System.IO.Compression" />
<Reference Include="System.Runtime.Remoting" />
<Reference Include="System.Runtime.Serialization" /> <Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" /> <Reference Include="System.ServiceModel" />
<Reference Include="System.Transactions" /> <Reference Include="System.Transactions" />
@ -123,6 +130,7 @@
<Compile Include="Entities\State.vb" /> <Compile Include="Entities\State.vb" />
<Compile Include="Entities\User.vb" /> <Compile Include="Entities\User.vb" />
<Compile Include="Helpers.vb" /> <Compile Include="Helpers.vb" />
<Compile Include="Jobs\CertificateDocumentJob.vb" />
<Compile Include="Models\BaseModel.vb" /> <Compile Include="Models\BaseModel.vb" />
<Compile Include="Models\CertificateModel.vb" /> <Compile Include="Models\CertificateModel.vb" />
<Compile Include="Models\ConfigModel.vb" /> <Compile Include="Models\ConfigModel.vb" />
@ -246,6 +254,7 @@
<CustomToolNamespace>My</CustomToolNamespace> <CustomToolNamespace>My</CustomToolNamespace>
<LastGenOutput>Settings.Designer.vb</LastGenOutput> <LastGenOutput>Settings.Designer.vb</LastGenOutput>
</None> </None>
<None Include="packages.config" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="Images\circle.svg"> <Content Include="Images\circle.svg">

View File

@ -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

View File

@ -15,36 +15,63 @@ Public Class ActionService
EmailService = New EmailService(pState) EmailService = New EmailService(pState)
HistoryService = New HistoryService(pState) HistoryService = New HistoryService(pState)
ReceiverModel = New ReceiverModel(pState) ReceiverModel = New ReceiverModel(pState)
End Sub 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 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 For Each oReceiver As EnvelopeReceiver In pEnvelope.Receivers
EmailService.SendEnvelopeDeletedEmail(oReceiver.Id, pEnvelope.Id) EmailService.SendEnvelopeDeletedEmail(pEnvelope, oReceiver)
Next Next
Return True Return True
End Function End Function
Public Function OpenEnvelope(pEnvelope As Envelope, pReceiverId As Integer) As Boolean Public Function OpenEnvelope(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean
Dim oReceiver As EnvelopeReceiver = ReceiverModel.GetById(pReceiverId) Dim oUserReference = pReceiver.Email
Dim oUserReference = oReceiver.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 End Function
Public Function SignEnvelope(pEnvelope As Envelope, pReceiverId As Integer) As Boolean Public Function SignEnvelope(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean
Dim oReceiver As EnvelopeReceiver = ReceiverModel.GetById(pReceiverId) Dim oUserReference = pReceiver.Email
Dim oUserReference = oReceiver.Email
If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.DocumentSigned, oUserReference) = False Then If HistoryService.SetEnvelopeStatus(pEnvelope, Constants.EnvelopeStatus.DocumentSigned, oUserReference) = False Then
Return False Return False
End If End If
Return EmailService.SendSignedEmail(oReceiver.Id, pEnvelope.Id) Return EmailService.SendSignedEmail(pEnvelope, pReceiver)
End Function End Function

View File

@ -23,11 +23,8 @@ Public Class EmailService
EmailTemplate = New EmailTemplate() EmailTemplate = New EmailTemplate()
End Sub End Sub
Public Function SendEnvelopeDeletedEmail(pReceiverId As Integer, pEnvelopeId As Integer) As Boolean Public Function SendEnvelopeDeletedEmail(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean
Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) Dim oEmailData As New EmailData(pEnvelope, pReceiver) With
Dim oReceiver = ReceiverModel.GetById(pReceiverId)
Dim oEmailData As New EmailData(oEnvelope, oReceiver) With
{ {
.SignatureLink = "" .SignatureLink = ""
} }
@ -42,13 +39,10 @@ Public Class EmailService
Return True Return True
End Function End Function
Public Function SendInitialEmail(pReceiverId As Integer, pEnvelopeId As Integer) As Boolean Public Function SendDocumentReceivedEmail(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean
Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) Dim oEmailData As New EmailData(pEnvelope, pReceiver) With
Dim oReceiver = ReceiverModel.GetById(pReceiverId)
Dim oEmailData As New EmailData(oEnvelope, oReceiver) With
{ {
.SignatureLink = Helpers.GetEnvelopeURL(State.DbConfig.SignatureHost, oEnvelope.Uuid, oReceiver.Signature) .SignatureLink = Helpers.GetEnvelopeURL(State.DbConfig.SignatureHost, pEnvelope.Uuid, pReceiver.Signature)
} }
EmailTemplate.FillDocumentReceivedEmailBody(oEmailData) EmailTemplate.FillDocumentReceivedEmailBody(oEmailData)
@ -61,11 +55,12 @@ Public Class EmailService
Return True Return True
End Function End Function
Public Function SendSignedEmail(pReceiverId As Integer, pEnvelopeId As Integer) As Boolean Public Function SendSignedEmail(pEnvelope As Envelope, pReceiver As EnvelopeReceiver) As Boolean
Dim oEnvelope = EnvelopeModel.GetById(pEnvelopeId) Dim oEmailData = New EmailData(pEnvelope, pReceiver) With
Dim oReceiver = ReceiverModel.GetById(pReceiverId) {
.SignatureLink = ""
}
Dim oEmailData = New EmailData(oEnvelope, oReceiver) With {.SignatureLink = ""}
EmailTemplate.FillDocumentSignedEmailBody(oEmailData) EmailTemplate.FillDocumentSignedEmailBody(oEmailData)
If EmailModel.Insert(oEmailData) = False Then If EmailModel.Insert(oEmailData) = False Then

View File

@ -22,11 +22,19 @@ Public Class HistoryService
End Sub End Sub
Public Function SetEnvelopeStatus(pEnvelope As Envelope, pStatus As EnvelopeStatus, pUserReference As String) As Boolean 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, .EnvelopeId = pEnvelope.Id,
.ActionDate = Now(), .ActionDate = Now(),
.Status = pStatus, .Status = pStatus,
.UserReference = pUserReference .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 Function
End Class End Class

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.Extensions.Logging.Abstractions" version="2.1.1" targetFramework="net462" />
<package id="Quartz" version="3.8.0" targetFramework="net462" />
</packages>

View File

@ -10,6 +10,8 @@ Public Class EnvelopeEditorController
Public ReadOnly Envelope As Envelope = Nothing Public ReadOnly Envelope As Envelope = Nothing
Public ReadOnly EmailService As EmailService Public ReadOnly EmailService As EmailService
Public ReadOnly ActionService As ActionService
Public ReadOnly Thumbnail As Thumbnail Public ReadOnly Thumbnail As Thumbnail
@ -19,6 +21,7 @@ Public Class EnvelopeEditorController
Envelope = CreateEnvelope() Envelope = CreateEnvelope()
Thumbnail = New Thumbnail(pState.LogConfig) Thumbnail = New Thumbnail(pState.LogConfig)
EmailService = New EmailService(pState) EmailService = New EmailService(pState)
ActionService = New ActionService(pState)
End Sub End Sub
Public Sub New(pState As State, pEnvelope As Envelope) Public Sub New(pState As State, pEnvelope As Envelope)
@ -29,32 +32,12 @@ Public Class EnvelopeEditorController
Envelope.Receivers = ReceiverModel.ListEnvelopeReceivers(pEnvelope.Id).ToList() Envelope.Receivers = ReceiverModel.ListEnvelopeReceivers(pEnvelope.Id).ToList()
Thumbnail = New Thumbnail(pState.LogConfig) Thumbnail = New Thumbnail(pState.LogConfig)
EmailService = New EmailService(pState) ActionService = New ActionService(pState)
End Sub End Sub
#Region "Public" #Region "Public"
Public Function SendEnvelope() As Boolean Public Function SendEnvelope() As Boolean
Return ActionService.SendEnvelope(Envelope)
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
End Function End Function
Public Function ValidateEnvelopeForSending(pErrors As List(Of String)) As List(Of String) Public Function ValidateEnvelopeForSending(pErrors As List(Of String)) As List(Of String)

View File

@ -56,7 +56,7 @@ namespace EnvelopeGenerator.Web.Controllers
envelopeService.EnsureValidEnvelopeKey(envelopeKey); envelopeService.EnsureValidEnvelopeKey(envelopeKey);
EnvelopeResponse response = envelopeService.LoadEnvelope(envelopeKey); EnvelopeResponse response = envelopeService.LoadEnvelope(envelopeKey);
actionService.OpenEnvelope(response.Envelope, response.Receiver.Id); actionService.OpenEnvelope(response.Envelope, response.Receiver);
return Ok(); return Ok();
} }

View File

@ -64,7 +64,7 @@ namespace EnvelopeGenerator.Web.Controllers
//emailService.SendSignedEmail(response.Receiver.Id, response.Envelope.Id); //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(); return Ok();
} }

View File

@ -9,6 +9,10 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="NLog" Version="5.2.5" /> <PackageReference Include="NLog" Version="5.2.5" />
<PackageReference Include="Quartz" Version="3.8.0" />
<PackageReference Include="Quartz.AspNetCore" Version="3.8.0" />
<PackageReference Include="Quartz.Plugins" Version="3.8.0" />
<PackageReference Include="Quartz.Serialization.Json" Version="3.8.0" />
<PackageReference Include="System.Data.SqlClient" Version="4.8.5" /> <PackageReference Include="System.Data.SqlClient" Version="4.8.5" />
<PackageReference Include="System.Drawing.Common" Version="7.0.0" /> <PackageReference Include="System.Drawing.Common" Version="7.0.0" />
</ItemGroup> </ItemGroup>

View File

@ -1,4 +1,7 @@
using DigitalData.Modules.Logging;
using EnvelopeGenerator.Common;
using EnvelopeGenerator.Web.Services; using EnvelopeGenerator.Web.Services;
using Quartz;
namespace EnvelopeGenerator.Web namespace EnvelopeGenerator.Web
{ {
@ -18,6 +21,14 @@ namespace EnvelopeGenerator.Web
// Add services to the container. // Add services to the container.
builder.Services.AddControllersWithViews(); builder.Services.AddControllersWithViews();
// Configure and start scheduler
builder.Services.AddQuartz(q =>
{
Scheduler scheduler = InitScheduler(builder);
scheduler.ScheduleJob<CertificateDocumentJob>(q, "CertificateDocument", 5);
});
builder.Services.AddQuartzHostedService();
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline. // Configure the HTTP request pipeline.
@ -39,5 +50,19 @@ namespace EnvelopeGenerator.Web
app.Run(); app.Run();
} }
private static LogConfig InitLogger(WebApplicationBuilder builder)
{
string logPath = builder.Configuration.GetValue<string>("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<string>("Config:ConnectionString");
Scheduler scheduler = new(logConfig, connectionString);
return scheduler;
}
} }
} }

View File

@ -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<TJob>(IServiceCollectionQuartzConfigurator q, string name, int interval) where TJob : IJob
{
var jobKey = new JobKey(name);
var jobData = new JobDataMap
{
{ DATABASE, ConnectionString },
{ LOGCONFIG, LogConfig }
};
q.AddJob<TJob>(opts => opts
.WithIdentity(jobKey)
.UsingJobData(jobData));
q.AddTrigger(opts => opts
.ForJob(jobKey)
.WithIdentity($"{name}-trigger")
.WithSimpleSchedule(s => s
.RepeatForever()
.WithIntervalInMinutes(interval)));
}
}
}