Migrate legacy VB.NET service to modern C# Worker
Migrated the legacy VB.NET Windows Service to a modern C# Worker Service targeting .NET Framework 4.6.2. Key changes include: - Added `Microsoft.Extensions.Hosting.WindowsServices`, `NLog`, and `Quartz` for logging and scheduling. - Introduced `LogConfigFactory` to bridge `ServiceConfig` and `LogConfig` for Quartz jobs. - Rewrote `Worker` to handle the full service lifecycle, including database connection, temp file management, and scheduler initialization. - Implemented `SchedulerFinishEnvelope` and `SchedulerEnvelopeTaskApi` for Quartz job scheduling. - Created `TempFiles` for service-level temp file management. - Configured `NLog` for file and console logging. - Updated `appsettings.json` for connection strings and service-specific configuration. - Replaced legacy `ProjectInstaller` with `AddWindowsService()` for SCM integration.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
using System.Collections.Specialized;
|
||||
using DigitalData.Modules.Logging;
|
||||
using EnvelopeGenerator.CommonServices.Jobs;
|
||||
using EnvelopeGenerator.CommonServices.Jobs.FinalizeDocument;
|
||||
using EnvelopeGenerator.Domain.Constants;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Quartz;
|
||||
using Quartz.Logging;
|
||||
|
||||
namespace EnvelopeGenerator.Service.Schedulers;
|
||||
|
||||
/// <summary>
|
||||
/// Schedules <see cref="FinalizeDocumentJob"/> via Quartz.
|
||||
/// C# rewrite of the legacy <c>Scheduler_FinishEnvelope.vb</c>.
|
||||
/// </summary>
|
||||
public sealed class SchedulerFinishEnvelope
|
||||
{
|
||||
private readonly ILogger<SchedulerFinishEnvelope> _logger;
|
||||
private readonly ServiceConfig _config;
|
||||
private readonly string _connectionString;
|
||||
|
||||
private IScheduler? _scheduler;
|
||||
|
||||
private const string JobName = "CertificateDocumentJob";
|
||||
|
||||
public SchedulerFinishEnvelope(
|
||||
ILogger<SchedulerFinishEnvelope> logger,
|
||||
IOptions<ServiceConfig> config,
|
||||
string connectionString)
|
||||
{
|
||||
_logger = logger;
|
||||
_config = config.Value;
|
||||
_connectionString = connectionString;
|
||||
}
|
||||
|
||||
public async Task Start(string licenseKey, LogConfig logConfig)
|
||||
{
|
||||
try
|
||||
{
|
||||
_logger.LogDebug("Starting SchedulerFinishEnvelope...");
|
||||
|
||||
LogProvider.SetCurrentLogProvider(new QuartzLogProvider(_logger));
|
||||
|
||||
_scheduler = await SchedulerBuilder
|
||||
.Create(new NameValueCollection())
|
||||
.UseDefaultThreadPool(x => x.MaxConcurrency = 5)
|
||||
.BuildScheduler();
|
||||
|
||||
var jobKey = new JobKey(JobName);
|
||||
|
||||
var jobData = new JobDataMap
|
||||
{
|
||||
{ Value.GDPICTURE, licenseKey },
|
||||
{ Value.LOGCONFIG, logConfig },
|
||||
{ Value.DATABASE, _connectionString },
|
||||
{ Value.PDF_BURNER_PARAMS, _config.PDFBurnerParams }
|
||||
};
|
||||
|
||||
_logger.LogDebug("Initialized Job [{JobName}]", JobName);
|
||||
|
||||
var job = JobBuilder.Create<FinalizeDocumentJob>()
|
||||
.UsingJobData(jobData)
|
||||
.WithIdentity(jobKey)
|
||||
.Build();
|
||||
|
||||
var trigger = TriggerBuilder.Create()
|
||||
.ForJob(jobKey)
|
||||
.WithIdentity($"{JobName}-trigger")
|
||||
.WithSimpleSchedule(s => s
|
||||
.RepeatForever()
|
||||
.WithIntervalInMinutes(_config.IntervalInMin))
|
||||
.StartNow()
|
||||
.Build();
|
||||
|
||||
_logger.LogDebug("Initialized Trigger");
|
||||
|
||||
await _scheduler.ScheduleJob(job, trigger);
|
||||
_logger.LogDebug("Job scheduled.");
|
||||
|
||||
await _scheduler.Start();
|
||||
_logger.LogDebug("Scheduler started!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "SchedulerFinishEnvelope failed to start");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Stop()
|
||||
{
|
||||
if (_scheduler is null) return;
|
||||
_logger.LogInformation("Stopping SchedulerFinishEnvelope...");
|
||||
await _scheduler.Shutdown();
|
||||
_logger.LogInformation("SchedulerFinishEnvelope stopped!");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user