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);
}
}
}