Wire notification service and finalization worker into server host

This commit is contained in:
2026-10-22 01:35:22 +02:00
parent 658cb28e1c
commit fb155fe706
4 changed files with 98 additions and 24 deletions

View File

@@ -18,6 +18,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\EnvelopeGenerator.Infrastructure.Notification\EnvelopeGenerator.Infrastructure.Notification.csproj" />
<ProjectReference Include="..\EnvelopeGenerator.Server.Client\EnvelopeGenerator.Server.Client.csproj" />
<ProjectReference Include="..\..\EnvelopeGenerator.Application\EnvelopeGenerator.Application.csproj" />
<ProjectReference Include="..\..\EnvelopeGenerator.Domain\EnvelopeGenerator.Domain.csproj" />

View File

@@ -1,34 +1,35 @@
using DevExpress.Blazor;
using DigitalData.Auth.Claims;
using DigitalData.Auth.Client;
using DigitalData.Core.Abstractions;
using DigitalData.Core.Abstractions.Security.Extensions;
using DigitalData.Core.API;
using DigitalData.Core.Application;
using DigitalData.EmailProfilerDispatcher;
using DigitalData.UserManager.DependencyInjection;
using EnvelopeGenerator.Application;
using EnvelopeGenerator.Application.Common.Interfaces.Doc;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Infrastructure;
using EnvelopeGenerator.Infrastructure.Crypt.DependencyInjection;
using EnvelopeGenerator.Infrastructure.Doc;
using EnvelopeGenerator.Infrastructure.Notification;
using EnvelopeGenerator.Server;
using EnvelopeGenerator.Server.Client.Services;
using EnvelopeGenerator.Server.Components;
using EnvelopeGenerator.Server.Models;
using EnvelopeGenerator.Server.Options;
using DevExpress.Blazor;
using EnvelopeGenerator.Server.Client.Services;
using DigitalData.Core.API;
using DigitalData.Core.Application;
using EnvelopeGenerator.Infrastructure;
using EnvelopeGenerator.Domain.Constants;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Localization;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System.Globalization;
using Scalar.AspNetCore;
using Microsoft.OpenApi.Models;
using DigitalData.UserManager.DependencyInjection;
using EnvelopeGenerator.Application;
using DigitalData.Auth.Client;
using DigitalData.Core.Abstractions;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using DigitalData.Core.Abstractions.Security.Extensions;
using NLog.Web;
using Microsoft.OpenApi.Models;
using NLog;
using DigitalData.Auth.Claims;
using EnvelopeGenerator.Server;
using DigitalData.EmailProfilerDispatcher;
using EnvelopeGenerator.Application.Common.Interfaces.Doc;
using EnvelopeGenerator.Infrastructure.Doc;
using EnvelopeGenerator.Infrastructure.Crypt.DependencyInjection;
using NLog.Web;
using Scalar.AspNetCore;
using System.Globalization;
var logger = LogManager.Setup().LoadConfigurationFromAppSettings().GetCurrentClassLogger();
logger.Info("EnvelopeGenerator.Server logging initialized!");
@@ -325,7 +326,8 @@ try
});
opt.AddSQLExecutor(executor => executor.ConnectionString = connStr);
})
.AddEnvelopeGeneratorServices(config);
.AddEnvelopeGeneratorServices(config)
.AddNotificationInfrastructure(config);
#pragma warning restore CS0618
builder.Services.AddDispatcher<EGDbContext>();
@@ -373,6 +375,7 @@ try
builder.Services.AddScoped<EnvelopeGenerator.Server.Services.IEnvelopeAuthService, EnvelopeGenerator.Server.Services.EnvelopeAuthService>();
builder.Services.AddScoped<EnvelopeGenerator.Server.Services.EnvelopeReceiverAuthorizationService>();
builder.Services.AddScoped<EnvelopeGenerator.Server.Services.EnvelopeReceiverPageDataService>();
builder.Services.AddHostedService<EnvelopeGenerator.Server.Services.EnvelopeFinalizationWorker>();
// DevExpress Server-Side Services (CRITICAL for DxPdfViewer)
builder.Services.AddDevExpressBlazor();

View File

@@ -0,0 +1,63 @@
using EnvelopeGenerator.Application.PdfSigning;
using EnvelopeGenerator.Domain.Constants;
using EnvelopeGenerator.Infrastructure;
using MediatR;
using Microsoft.EntityFrameworkCore;
namespace EnvelopeGenerator.Server.Services;
public sealed class EnvelopeFinalizationWorker(
IServiceScopeFactory scopeFactory,
ILogger<EnvelopeFinalizationWorker> logger) : BackgroundService
{
private static readonly TimeSpan PollInterval = TimeSpan.FromMinutes(1);
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
try
{
using var scope = scopeFactory.CreateScope();
var dbContext = scope.ServiceProvider.GetRequiredService<EGDbContext>();
var sender = scope.ServiceProvider.GetRequiredService<ISender>();
var envelopeIds = await dbContext.Envelopes
.AsNoTracking()
.Where(e => e.Status == EnvelopeStatus.EnvelopeCompletelySigned && e.DocResult == null)
.Select(e => e.Id)
.ToListAsync(stoppingToken);
foreach(var envelopeId in envelopeIds)
{
try
{
await sender.Send(new FinalizeEnvelopeCommand()
{
Id = envelopeId,
BurnedAllowed = false,
SaveDocResult = true,
}, stoppingToken);
}
catch(Exception ex)
{
logger.LogError(ex, "Unexpected exception happened during finalization of envelope. Envelope ID: {EnvelopeId}", envelopeId);
}
}
// continue here
logger.LogDebug("EnvelopeFinalizationWorker found {Count} signed envelope(s) without DOC_RESULT.", envelopeIds.Count);
}
catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested)
{
break;
}
catch (Exception ex)
{
logger.LogError(ex, "EnvelopeFinalizationWorker failed while reading envelopes.");
}
await Task.Delay(PollInterval, stoppingToken);
}
}
}

View File

@@ -40,9 +40,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Dependenc
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EnvelopeGenerator.Server", "EnvelopeGenerator.Server", "{BF1700D5-592E-4FFA-84E8-5480E289A1F0}"
ProjectSection(SolutionItems) = preProject
EnvelopeGenerator.Server\cnn_sftp_soft_hsm.bat = EnvelopeGenerator.Server\cnn_sftp_soft_hsm.bat
EnvelopeGenerator.Server\cnn_ssh_soft_hsm.bat = EnvelopeGenerator.Server\cnn_ssh_soft_hsm.bat
EnvelopeGenerator.Server\publish.bat = EnvelopeGenerator.Server\publish.bat
EnvelopeGenerator.Server\cnn_sftp_soft_hsm.bat = EnvelopeGenerator.Server\cnn_sftp_soft_hsm.bat
SENDER_SAVE_EDIT_MIGRATION_PLAN.md = SENDER_SAVE_EDIT_MIGRATION_PLAN.md
EndProjectSection
EndProject
@@ -58,6 +58,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Infrastru
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Infrastructure.Crypt", "EnvelopeGenerator.Infrastructure.Crypt\EnvelopeGenerator.Infrastructure.Crypt.csproj", "{B33A3B17-A4F8-4307-9C51-DDFE1B292DE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EnvelopeGenerator.Infrastructure.Notification", "EnvelopeGenerator.Infrastructure.Notification\EnvelopeGenerator.Infrastructure.Notification.csproj", "{6F328677-0E90-40A7-9CA9-CE050182D7FC}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -128,6 +130,10 @@ Global
{B33A3B17-A4F8-4307-9C51-DDFE1B292DE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B33A3B17-A4F8-4307-9C51-DDFE1B292DE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B33A3B17-A4F8-4307-9C51-DDFE1B292DE7}.Release|Any CPU.Build.0 = Release|Any CPU
{6F328677-0E90-40A7-9CA9-CE050182D7FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6F328677-0E90-40A7-9CA9-CE050182D7FC}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6F328677-0E90-40A7-9CA9-CE050182D7FC}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6F328677-0E90-40A7-9CA9-CE050182D7FC}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -153,6 +159,7 @@ Global
{6B87FB5F-F4EA-45BE-A218-385DC2CE8E80} = {E3C758DC-914D-4B7E-8457-0813F1FDB0CB}
{3B6EFE8D-F1EE-4666-87A0-9F90149CC61A} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{B33A3B17-A4F8-4307-9C51-DDFE1B292DE7} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
{6F328677-0E90-40A7-9CA9-CE050182D7FC} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {73E60370-756D-45AD-A19A-C40A02DACCC7}