diff --git a/src/Core/Jobs/BaseJobsHostedService.cs b/src/Core/Jobs/BaseJobsHostedService.cs index 897a382a2..05ef3eac5 100644 --- a/src/Core/Jobs/BaseJobsHostedService.cs +++ b/src/Core/Jobs/BaseJobsHostedService.cs @@ -1,9 +1,7 @@ -using System.Collections.Specialized; -using Bit.Core.Settings; +using Bit.Core.Settings; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Quartz; -using Quartz.Impl; using Quartz.Impl.Matchers; namespace Bit.Core.Jobs; @@ -35,32 +33,29 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable public virtual async Task StartAsync(CancellationToken cancellationToken) { - var props = new NameValueCollection - { - {"quartz.serializer.type", "binary"}, - }; + var schedulerBuilder = SchedulerBuilder.Create() + .WithName(GetType().FullName) // Ensure each project has a unique instanceName + .WithId("AUTO") + .UseJobFactory(); if (!string.IsNullOrEmpty(_globalSettings.SqlServer.JobSchedulerConnectionString)) { - // Ensure each project has a unique instanceName - props.Add("quartz.scheduler.instanceName", GetType().FullName); - props.Add("quartz.scheduler.instanceId", "AUTO"); - props.Add("quartz.jobStore.type", "Quartz.Impl.AdoJobStore.JobStoreTX"); - props.Add("quartz.jobStore.driverDelegateType", "Quartz.Impl.AdoJobStore.SqlServerDelegate"); - props.Add("quartz.jobStore.useProperties", "true"); - props.Add("quartz.jobStore.dataSource", "default"); - props.Add("quartz.jobStore.tablePrefix", "QRTZ_"); - props.Add("quartz.jobStore.clustered", "true"); - props.Add("quartz.dataSource.default.provider", "SqlServer"); - props.Add("quartz.dataSource.default.connectionString", _globalSettings.SqlServer.JobSchedulerConnectionString); + schedulerBuilder = schedulerBuilder.UsePersistentStore(options => + { + options.UseProperties = true; + options.UseClustering(); + options.UseBinarySerializer(); + options.UseSqlServer(connectionString: _globalSettings.SqlServer.JobSchedulerConnectionString); + }); } - var factory = new StdSchedulerFactory(props); + var factory = schedulerBuilder.Build(); _scheduler = await factory.GetScheduler(cancellationToken); - _scheduler.JobFactory = new JobFactory(_serviceProvider); - _scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger), - GroupMatcher.AnyGroup()); + + _scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger), GroupMatcher.AnyGroup()); + await _scheduler.Start(cancellationToken); + if (Jobs != null) { foreach (var (job, trigger) in Jobs) @@ -70,23 +65,23 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable // There's a race condition when starting multiple containers simultaneously, retry until it succeeds.. try { - var dupeT = await _scheduler.GetTrigger(trigger.Key); + var dupeT = await _scheduler.GetTrigger(trigger.Key, cancellationToken); if (dupeT != null) { - await _scheduler.RescheduleJob(trigger.Key, trigger); + await _scheduler.RescheduleJob(trigger.Key, trigger, cancellationToken); } var jobDetail = JobBuilder.Create(job) .WithIdentity(job.FullName) .Build(); - var dupeJ = await _scheduler.GetJobDetail(jobDetail.Key); + var dupeJ = await _scheduler.GetJobDetail(jobDetail.Key, cancellationToken); if (dupeJ != null) { - await _scheduler.DeleteJob(jobDetail.Key); + await _scheduler.DeleteJob(jobDetail.Key, cancellationToken); } - await _scheduler.ScheduleJob(jobDetail, trigger); + await _scheduler.ScheduleJob(jobDetail, trigger, cancellationToken); break; } catch (Exception e) @@ -105,7 +100,7 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable } // Delete old Jobs and Triggers - var existingJobKeys = await _scheduler.GetJobKeys(GroupMatcher.AnyGroup()); + var existingJobKeys = await _scheduler.GetJobKeys(GroupMatcher.AnyGroup(), cancellationToken); var jobKeys = Jobs.Select(j => { var job = j.Item1; @@ -122,10 +117,10 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable } _logger.LogInformation($"Deleting old job with key {key}"); - await _scheduler.DeleteJob(key); + await _scheduler.DeleteJob(key, cancellationToken); } - var existingTriggerKeys = await _scheduler.GetTriggerKeys(GroupMatcher.AnyGroup()); + var existingTriggerKeys = await _scheduler.GetTriggerKeys(GroupMatcher.AnyGroup(), cancellationToken); var triggerKeys = Jobs.Select(j => j.Item2.Key); foreach (var key in existingTriggerKeys) @@ -136,7 +131,7 @@ public abstract class BaseJobsHostedService : IHostedService, IDisposable } _logger.LogInformation($"Unscheduling old trigger with key {key}"); - await _scheduler.UnscheduleJob(key); + await _scheduler.UnscheduleJob(key, cancellationToken); } }