Compare commits
5 Commits
786a3e128d
...
b20260674e
| Author | SHA1 | Date | |
|---|---|---|---|
| b20260674e | |||
| 7e5ff6bcb2 | |||
| 6eed9b1e31 | |||
| d4b1a4921c | |||
| f078bafdde |
@@ -1,7 +0,0 @@
|
||||
namespace EnvelopeGenerator.Jobs
|
||||
{
|
||||
public class Class1
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -19,23 +19,4 @@
|
||||
<ProjectReference Include="..\EnvelopeGenerator.PdfEditor\EnvelopeGenerator.PdfEditor.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include="Jobs\**\*.cs">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</Content>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="Jobs\APIBackendJobs\APIEnvelopeJob.cs" />
|
||||
<Compile Remove="Jobs\DataRowExtensions.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\FinalizeDocumentExceptions.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\FinalizeDocumentJob.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\PDFBurner.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\PDFBurnerParams.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\PDFMerger.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\ReportCreator.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\ReportItem.cs" />
|
||||
<Compile Remove="Jobs\FinalizeDocument\ReportSource.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -7,20 +7,11 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Quartz;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.APIBackendJobs;
|
||||
namespace EnvelopeGenerator.Jobs.APIBackendJobs;
|
||||
|
||||
public class APIEnvelopeJob : IJob
|
||||
public class APIEnvelopeJob(ILogger<APIEnvelopeJob>? logger = null) : IJob
|
||||
{
|
||||
private readonly ILogger<APIEnvelopeJob> _logger;
|
||||
|
||||
public APIEnvelopeJob() : this(NullLogger<APIEnvelopeJob>.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
public APIEnvelopeJob(ILogger<APIEnvelopeJob> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
private readonly ILogger<APIEnvelopeJob> _logger = logger ?? NullLogger<APIEnvelopeJob>.Instance;
|
||||
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System;
|
||||
using System.Data;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs;
|
||||
namespace EnvelopeGenerator.Jobs;
|
||||
|
||||
public static class DataRowExtensions
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public static class FinalizeDocumentExceptions
|
||||
{
|
||||
|
||||
@@ -4,15 +4,14 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Quartz;
|
||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class FinalizeDocumentJob : IJob
|
||||
{
|
||||
@@ -23,17 +22,16 @@ public class FinalizeDocumentJob : IJob
|
||||
|
||||
private record ConfigSettings(string DocumentPath, string DocumentPathOrigin, string ExportPath);
|
||||
|
||||
public FinalizeDocumentJob()
|
||||
: this(NullLogger<FinalizeDocumentJob>.Instance)
|
||||
{
|
||||
}
|
||||
|
||||
public FinalizeDocumentJob(ILogger<FinalizeDocumentJob> logger)
|
||||
public FinalizeDocumentJob(
|
||||
ILogger<FinalizeDocumentJob> logger,
|
||||
PDFBurner pdfBurner,
|
||||
PDFMerger pdfMerger,
|
||||
ReportCreator reportCreator)
|
||||
{
|
||||
_logger = logger;
|
||||
_pdfBurner = new PDFBurner();
|
||||
_pdfMerger = new PDFMerger();
|
||||
_reportCreator = new ReportCreator();
|
||||
_pdfBurner = pdfBurner;
|
||||
_pdfMerger = pdfMerger;
|
||||
_reportCreator = reportCreator;
|
||||
}
|
||||
|
||||
public async Task Execute(IJobExecutionContext context)
|
||||
@@ -77,20 +75,22 @@ public class FinalizeDocumentJob : IJob
|
||||
continue;
|
||||
}
|
||||
|
||||
var data = envelopeData.Value;
|
||||
|
||||
var envelope = new Envelope
|
||||
{
|
||||
Id = envelopeId,
|
||||
Uuid = envelopeData.EnvelopeUuid ?? string.Empty,
|
||||
Title = envelopeData.Title ?? string.Empty,
|
||||
FinalEmailToCreator = FinalEmailType.No,
|
||||
FinalEmailToReceivers = FinalEmailType.No
|
||||
Uuid = data.EnvelopeUuid ?? string.Empty,
|
||||
Title = data.Title ?? string.Empty,
|
||||
FinalEmailToCreator = (int)FinalEmailType.No,
|
||||
FinalEmailToReceivers = (int)FinalEmailType.No
|
||||
};
|
||||
|
||||
var burned = _pdfBurner.BurnAnnotsToPDF(envelopeData.DocumentBytes, envelopeData.AnnotationData, envelopeId);
|
||||
var burned = _pdfBurner.BurnAnnotsToPDF(data.DocumentBytes, data.AnnotationData, envelopeId);
|
||||
var report = _reportCreator.CreateReport(connection, envelope);
|
||||
var merged = _pdfMerger.MergeDocuments(burned, report);
|
||||
|
||||
var outputDirectory = Path.Combine(config.ExportPath, envelopeData.ParentFolderUid);
|
||||
var outputDirectory = Path.Combine(config.ExportPath, data.ParentFolderUid);
|
||||
Directory.CreateDirectory(outputDirectory);
|
||||
var outputPath = Path.Combine(outputDirectory, $"{envelope.Uuid}.pdf");
|
||||
await File.WriteAllBytesAsync(outputPath, merged, context.CancellationToken);
|
||||
|
||||
@@ -1,21 +1,25 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
using iText.IO.Image;
|
||||
using iText.Kernel.Colors;
|
||||
using iText.Kernel.Pdf;
|
||||
using iText.Kernel.Pdf.Canvas;
|
||||
using iText.Layout;
|
||||
using iText.Layout.Element;
|
||||
using iText.Layout.Font;
|
||||
using iText.Layout.Properties;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using Newtonsoft.Json;
|
||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
using LayoutImage = iText.Layout.Element.Image;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class PDFBurner
|
||||
{
|
||||
private static readonly FontProvider FontProvider = CreateFontProvider();
|
||||
private readonly ILogger<PDFBurner> _logger;
|
||||
private readonly PDFBurnerParams _pdfBurnerParams;
|
||||
|
||||
@@ -110,17 +114,20 @@ public class PDFBurner
|
||||
}
|
||||
|
||||
var page = pdf.GetPage(annotation.pageIndex + 1);
|
||||
var canvas = new PdfCanvas(page);
|
||||
var bounds = annotation.bbox.Select(ToInches).ToList();
|
||||
var x = bounds[0];
|
||||
var y = bounds[1];
|
||||
var width = bounds[2];
|
||||
var height = bounds[3];
|
||||
var x = (float)bounds[0];
|
||||
var y = (float)bounds[1];
|
||||
var width = (float)bounds[2];
|
||||
var height = (float)bounds[3];
|
||||
|
||||
var imageBytes = Convert.FromBase64String(attachment.binary);
|
||||
var imageData = ImageDataFactory.Create(imageBytes);
|
||||
canvas.AddImageAt(imageData, x, y, false)
|
||||
.ScaleToFit(width, height);
|
||||
var image = new LayoutImage(imageData)
|
||||
.ScaleAbsolute(width, height)
|
||||
.SetFixedPosition(annotation.pageIndex + 1, x, y);
|
||||
|
||||
using var canvas = new Canvas(new PdfCanvas(page), page.GetPageSize());
|
||||
canvas.Add(image);
|
||||
}
|
||||
|
||||
private void AddInkAnnotation(PdfDocument pdf, Annotation annotation)
|
||||
@@ -156,24 +163,46 @@ public class PDFBurner
|
||||
}
|
||||
}
|
||||
|
||||
private static FontProvider CreateFontProvider()
|
||||
{
|
||||
var provider = new FontProvider();
|
||||
provider.AddStandardPdfFonts();
|
||||
provider.AddSystemFonts();
|
||||
return provider;
|
||||
}
|
||||
|
||||
private void AddFormFieldValue(PdfDocument pdf, Annotation annotation, string value)
|
||||
{
|
||||
var bounds = annotation.bbox.Select(ToInches).ToList();
|
||||
var x = bounds[0];
|
||||
var y = bounds[1];
|
||||
var width = bounds[2];
|
||||
var height = bounds[3];
|
||||
var x = (float)bounds[0];
|
||||
var y = (float)bounds[1];
|
||||
var width = (float)bounds[2];
|
||||
var height = (float)bounds[3];
|
||||
|
||||
var page = pdf.GetPage(annotation.pageIndex + 1);
|
||||
var canvas = new Canvas(new PdfCanvas(page), page.GetPageSize());
|
||||
canvas.ShowTextAligned(new Paragraph(value)
|
||||
.SetFontSize(_pdfBurnerParams.FontSize)
|
||||
.SetFontColor(ColorConstants.BLACK)
|
||||
.SetFontFamily(_pdfBurnerParams.FontName)
|
||||
.SetItalic(_pdfBurnerParams.FontStyle.HasFlag(FontStyle.Italic))
|
||||
.SetBold(_pdfBurnerParams.FontStyle.HasFlag(FontStyle.Bold)),
|
||||
x + _pdfBurnerParams.TopMargin,
|
||||
y + _pdfBurnerParams.YOffset,
|
||||
canvas.SetProperty(Property.FONT_PROVIDER, FontProvider);
|
||||
canvas.SetProperty(Property.FONT, FontProvider.GetFontSet());
|
||||
|
||||
var paragraph = new Paragraph(value)
|
||||
.SetFontSize(_pdfBurnerParams.FontSize)
|
||||
.SetFontColor(ColorConstants.BLACK)
|
||||
.SetFontFamily(_pdfBurnerParams.FontName);
|
||||
|
||||
if (_pdfBurnerParams.FontStyle.HasFlag(FontStyle.Italic))
|
||||
{
|
||||
paragraph.SetItalic();
|
||||
}
|
||||
|
||||
if (_pdfBurnerParams.FontStyle.HasFlag(FontStyle.Bold))
|
||||
{
|
||||
paragraph.SetBold();
|
||||
}
|
||||
|
||||
canvas.ShowTextAligned(
|
||||
paragraph,
|
||||
x + (float)_pdfBurnerParams.TopMargin,
|
||||
y + (float)_pdfBurnerParams.YOffset,
|
||||
annotation.pageIndex + 1,
|
||||
iText.Layout.Properties.TextAlignment.LEFT,
|
||||
iText.Layout.Properties.VerticalAlignment.TOP,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class PDFBurnerParams
|
||||
{
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.IO;
|
||||
using EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
using iText.Kernel.Pdf;
|
||||
using iText.Kernel.Utils;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class PDFMerger
|
||||
{
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
using iText.Kernel.Pdf;
|
||||
using iText.Layout;
|
||||
using iText.Layout.Element;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging.Abstractions;
|
||||
using static EnvelopeGenerator.Jobs.FinalizeDocument.FinalizeDocumentExceptions;
|
||||
using LayoutDocument = iText.Layout.Document;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class ReportCreator
|
||||
{
|
||||
@@ -32,7 +32,7 @@ public class ReportCreator
|
||||
using var stream = new MemoryStream();
|
||||
using var writer = new PdfWriter(stream);
|
||||
using var pdf = new PdfDocument(writer);
|
||||
using var document = new Document(pdf);
|
||||
using var document = new LayoutDocument(pdf);
|
||||
|
||||
document.Add(new Paragraph("Envelope Finalization Report").SetFontSize(16));
|
||||
document.Add(new Paragraph($"Envelope Id: {envelope.Id}"));
|
||||
@@ -69,7 +69,7 @@ public class ReportCreator
|
||||
|
||||
private List<ReportItem> LoadReportItems(SqlConnection connection, int envelopeId)
|
||||
{
|
||||
const string sql = "SELECT ENVELOPE_ID, HEAD_TITLE, HEAD_SUBJECT, POS_WHEN, POS_STATUS, POS_WHO FROM VWSIG_ENVELOPE_REPORT WHERE ENVELOPE_ID = @EnvelopeId";
|
||||
const string sql = "SELECT ENVELOPE_ID, POS_WHEN, POS_STATUS, POS_WHO FROM VWSIG_ENVELOPE_REPORT WHERE ENVELOPE_ID = @EnvelopeId";
|
||||
var result = new List<ReportItem>();
|
||||
|
||||
using var command = new SqlCommand(sql, connection);
|
||||
@@ -80,11 +80,9 @@ public class ReportCreator
|
||||
result.Add(new ReportItem
|
||||
{
|
||||
EnvelopeId = reader.GetInt32(0),
|
||||
EnvelopeTitle = reader.IsDBNull(1) ? string.Empty : reader.GetString(1),
|
||||
EnvelopeSubject = reader.IsDBNull(2) ? string.Empty : reader.GetString(2),
|
||||
ItemDate = reader.IsDBNull(3) ? DateTime.MinValue : reader.GetDateTime(3),
|
||||
ItemStatus = reader.IsDBNull(4) ? default : (EnvelopeGenerator.Domain.Constants.EnvelopeStatus)reader.GetInt32(4),
|
||||
ItemUserReference = reader.IsDBNull(5) ? string.Empty : reader.GetString(5)
|
||||
ItemDate = reader.IsDBNull(1) ? DateTime.MinValue : reader.GetDateTime(1),
|
||||
ItemStatus = reader.IsDBNull(2) ? default : (EnvelopeGenerator.Domain.Constants.EnvelopeStatus)reader.GetInt32(2),
|
||||
ItemUserReference = reader.IsDBNull(3) ? string.Empty : reader.GetString(3)
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Domain.Entities;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class ReportItem
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
namespace EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
public class ReportSource
|
||||
{
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
using EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
|
||||
namespace EnvelopeGenerator.WorkerService.Configuration;
|
||||
|
||||
public sealed class WorkerSettings
|
||||
{
|
||||
public string ConnectionString { get; set; } = string.Empty;
|
||||
|
||||
public bool Debug { get; set; }
|
||||
|
||||
public int IntervalMinutes { get; set; } = 1;
|
||||
|
||||
public PDFBurnerParams PdfBurner { get; set; } = new();
|
||||
}
|
||||
@@ -9,5 +9,10 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.1" />
|
||||
<PackageReference Include="Quartz.Extensions.Hosting" Version="3.9.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\EnvelopeGenerator.Jobs\EnvelopeGenerator.Jobs.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
@@ -1,6 +1,66 @@
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using EnvelopeGenerator.Jobs.APIBackendJobs;
|
||||
using EnvelopeGenerator.Jobs.FinalizeDocument;
|
||||
using EnvelopeGenerator.WorkerService;
|
||||
using EnvelopeGenerator.WorkerService.Configuration;
|
||||
using EnvelopeGenerator.WorkerService.Services;
|
||||
using Quartz;
|
||||
|
||||
var builder = Host.CreateApplicationBuilder(args);
|
||||
|
||||
builder.Services.Configure<WorkerSettings>(builder.Configuration.GetSection("WorkerSettings"));
|
||||
|
||||
builder.Services.AddSingleton<TempFileManager>();
|
||||
builder.Services.AddSingleton(provider =>
|
||||
{
|
||||
var settings = provider.GetRequiredService<Microsoft.Extensions.Options.IOptions<WorkerSettings>>().Value;
|
||||
var logger = provider.GetRequiredService<ILogger<PDFBurner>>();
|
||||
return new PDFBurner(logger, settings.PdfBurner);
|
||||
});
|
||||
builder.Services.AddSingleton<PDFMerger>();
|
||||
builder.Services.AddSingleton<ReportCreator>();
|
||||
|
||||
builder.Services.AddQuartz(q =>
|
||||
{
|
||||
q.UseMicrosoftDependencyInjectionJobFactory();
|
||||
q.UseDefaultThreadPool(tp => tp.MaxConcurrency = 5);
|
||||
|
||||
var settings = new WorkerSettings();
|
||||
builder.Configuration.GetSection("WorkerSettings").Bind(settings);
|
||||
var intervalMinutes = Math.Max(1, settings.IntervalMinutes);
|
||||
|
||||
var finalizeJobKey = new JobKey("FinalizeDocumentJob");
|
||||
q.AddJob<FinalizeDocumentJob>(opts => opts
|
||||
.WithIdentity(finalizeJobKey)
|
||||
.UsingJobData(Value.DATABASE, settings.ConnectionString));
|
||||
|
||||
q.AddTrigger(opts => opts
|
||||
.ForJob(finalizeJobKey)
|
||||
.WithIdentity("FinalizeDocumentJob-trigger")
|
||||
.StartNow()
|
||||
.WithSimpleSchedule(x => x
|
||||
.WithIntervalInMinutes(intervalMinutes)
|
||||
.RepeatForever()));
|
||||
|
||||
var apiJobKey = new JobKey("APIEnvelopeJob");
|
||||
q.AddJob<APIEnvelopeJob>(opts => opts
|
||||
.WithIdentity(apiJobKey)
|
||||
.UsingJobData(Value.DATABASE, settings.ConnectionString));
|
||||
|
||||
q.AddTrigger(opts => opts
|
||||
.ForJob(apiJobKey)
|
||||
.WithIdentity("APIEnvelopeJob-trigger")
|
||||
.StartNow()
|
||||
.WithSimpleSchedule(x => x
|
||||
.WithIntervalInMinutes(intervalMinutes)
|
||||
.RepeatForever()));
|
||||
});
|
||||
|
||||
builder.Services.AddQuartzHostedService(options =>
|
||||
{
|
||||
options.WaitForJobsToComplete = true;
|
||||
});
|
||||
|
||||
builder.Services.AddHostedService<Worker>();
|
||||
|
||||
var host = builder.Build();
|
||||
|
||||
74
EnvelopeGenerator.WorkerService/Services/TempFileManager.cs
Normal file
74
EnvelopeGenerator.WorkerService/Services/TempFileManager.cs
Normal file
@@ -0,0 +1,74 @@
|
||||
using System.IO;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace EnvelopeGenerator.WorkerService.Services;
|
||||
|
||||
public sealed class TempFileManager
|
||||
{
|
||||
private readonly ILogger<TempFileManager> _logger;
|
||||
|
||||
public TempFileManager(ILogger<TempFileManager> logger)
|
||||
{
|
||||
_logger = logger;
|
||||
TempPath = Path.Combine(Path.GetTempPath(), "EnvelopeGenerator");
|
||||
}
|
||||
|
||||
public string TempPath { get; }
|
||||
|
||||
public Task CreateAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!Directory.Exists(TempPath))
|
||||
{
|
||||
Directory.CreateDirectory(TempPath);
|
||||
_logger.LogDebug("Created temp folder {TempPath}", TempPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
CleanUpFiles();
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to create temp folder {TempPath}", TempPath);
|
||||
throw;
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task CleanupAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Directory.Exists(TempPath))
|
||||
{
|
||||
_logger.LogDebug("Deleting temp folder {TempPath}", TempPath);
|
||||
Directory.Delete(TempPath, recursive: true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Failed to clean up temp folder {TempPath}", TempPath);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private void CleanUpFiles()
|
||||
{
|
||||
foreach (var file in Directory.GetFiles(TempPath))
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogDebug("Deleting temp file {File}", file);
|
||||
File.Delete(file);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Failed to delete temp file {File}", file);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,71 @@
|
||||
namespace EnvelopeGenerator.WorkerService
|
||||
using EnvelopeGenerator.WorkerService.Configuration;
|
||||
using EnvelopeGenerator.WorkerService.Services;
|
||||
using Microsoft.Data.SqlClient;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace EnvelopeGenerator.WorkerService;
|
||||
|
||||
public class Worker : BackgroundService
|
||||
{
|
||||
public class Worker : BackgroundService
|
||||
private readonly ILogger<Worker> _logger;
|
||||
private readonly WorkerSettings _settings;
|
||||
private readonly TempFileManager _tempFiles;
|
||||
|
||||
public Worker(
|
||||
ILogger<Worker> logger,
|
||||
IOptions<WorkerSettings> settings,
|
||||
TempFileManager tempFiles)
|
||||
{
|
||||
private readonly ILogger<Worker> _logger;
|
||||
_logger = logger;
|
||||
_settings = settings.Value;
|
||||
_tempFiles = tempFiles;
|
||||
}
|
||||
|
||||
public Worker(ILogger<Worker> logger)
|
||||
public override async Task StartAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Starting EnvelopeGenerator worker...");
|
||||
_logger.LogInformation("Debug mode: {Debug}", _settings.Debug);
|
||||
|
||||
ValidateConfiguration();
|
||||
await EnsureDatabaseConnectionAsync(cancellationToken);
|
||||
await _tempFiles.CreateAsync(cancellationToken);
|
||||
|
||||
await base.StartAsync(cancellationToken);
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
_logger.LogInformation("EnvelopeGenerator worker is running. Jobs are scheduled every {Interval} minute(s).", Math.Max(1, _settings.IntervalMinutes));
|
||||
await Task.Delay(Timeout.Infinite, stoppingToken);
|
||||
}
|
||||
|
||||
public override async Task StopAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
_logger.LogInformation("Stopping EnvelopeGenerator worker...");
|
||||
await _tempFiles.CleanupAsync(cancellationToken);
|
||||
await base.StopAsync(cancellationToken);
|
||||
}
|
||||
|
||||
private void ValidateConfiguration()
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(_settings.ConnectionString))
|
||||
{
|
||||
_logger = logger;
|
||||
throw new InvalidOperationException("Connection string cannot be empty. Configure 'WorkerSettings:ConnectionString'.");
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
private async Task EnsureDatabaseConnectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
while (!stoppingToken.IsCancellationRequested)
|
||||
{
|
||||
if (_logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
|
||||
}
|
||||
await Task.Delay(1000, stoppingToken);
|
||||
}
|
||||
await using var connection = new SqlConnection(_settings.ConnectionString);
|
||||
await connection.OpenAsync(cancellationToken);
|
||||
_logger.LogInformation("Database connection established successfully.");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Database connection could not be established.");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,30 @@
|
||||
{
|
||||
"Logging": {
|
||||
"LogLevel": {
|
||||
"Default": "Information",
|
||||
"Default": "Debug",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"WorkerSettings": {
|
||||
"ConnectionString": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;",
|
||||
"Debug": true,
|
||||
"IntervalMinutes": 1,
|
||||
"PdfBurner": {
|
||||
"IgnoredLabels": [
|
||||
"Date",
|
||||
"Datum",
|
||||
"ZIP",
|
||||
"PLZ",
|
||||
"Place",
|
||||
"Ort",
|
||||
"Position",
|
||||
"Stellung"
|
||||
],
|
||||
"TopMargin": 0.1,
|
||||
"YOffset": -0.3,
|
||||
"FontName": "Arial",
|
||||
"FontSize": 8,
|
||||
"FontStyle": "Italic"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,5 +4,18 @@
|
||||
"Default": "Information",
|
||||
"Microsoft.Hosting.Lifetime": "Information"
|
||||
}
|
||||
},
|
||||
"WorkerSettings": {
|
||||
"ConnectionString": "Server=SDD-VMP04-SQL17\\DD_DEVELOP01;Database=DD_ECM;User Id=sa;Password=dd;Encrypt=false;TrustServerCertificate=True;",
|
||||
"Debug": false,
|
||||
"IntervalMinutes": 1,
|
||||
"PdfBurner": {
|
||||
"IgnoredLabels": ["Date", "Datum", "ZIP", "PLZ", "Place", "Ort", "Position", "Stellung"],
|
||||
"TopMargin": 0.1,
|
||||
"YOffset": -0.3,
|
||||
"FontName": "Arial",
|
||||
"FontSize": 8,
|
||||
"FontStyle": "Italic"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user