From 670f79a861be18fd3f5463a4d1be0daef1d21fee Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Fri, 10 Aug 2018 11:05:45 -0400 Subject: [PATCH] abstract quartz jobs sevrice out to core --- src/Api/Api.csproj | 1 - src/Api/Jobs/AliveJob.cs | 14 ++---- src/Api/Jobs/JobsHostedService.cs | 56 ++++++--------------- src/Api/Jobs/ValidateOrganizationsJob.cs | 17 ++----- src/Api/Jobs/ValidateUsersJob.cs | 20 +++----- src/Core/Core.csproj | 1 + src/Core/Jobs/BaseJob.cs | 31 ++++++++++++ src/Core/Jobs/BaseJobsHostedService.cs | 63 ++++++++++++++++++++++++ src/{Api => Core}/Jobs/JobFactory.cs | 2 +- src/{Api => Core}/Jobs/JobListener.cs | 2 +- 10 files changed, 127 insertions(+), 80 deletions(-) create mode 100644 src/Core/Jobs/BaseJob.cs create mode 100644 src/Core/Jobs/BaseJobsHostedService.cs rename src/{Api => Core}/Jobs/JobFactory.cs (96%) rename src/{Api => Core}/Jobs/JobListener.cs (98%) diff --git a/src/Api/Api.csproj b/src/Api/Api.csproj index 7cb3c2e2a2..eb0b60f43e 100644 --- a/src/Api/Api.csproj +++ b/src/Api/Api.csproj @@ -18,7 +18,6 @@ - diff --git a/src/Api/Jobs/AliveJob.cs b/src/Api/Jobs/AliveJob.cs index bc06b8a833..97f712b41f 100644 --- a/src/Api/Jobs/AliveJob.cs +++ b/src/Api/Jobs/AliveJob.cs @@ -1,20 +1,16 @@ using System.Threading.Tasks; +using Bit.Core.Jobs; using Microsoft.Extensions.Logging; using Quartz; namespace Bit.Api.Jobs { - public class AliveJob : IJob + public class AliveJob : BaseJob { - private readonly ILogger _logger; + public AliveJob(ILogger logger) + : base(logger) { } - public AliveJob( - ILogger logger) - { - _logger = logger; - } - - public Task Execute(IJobExecutionContext context) + protected override Task ExecuteJobAsync(IJobExecutionContext context) { _logger.LogInformation("It's alive!"); return Task.FromResult(0); diff --git a/src/Api/Jobs/JobsHostedService.cs b/src/Api/Jobs/JobsHostedService.cs index c5d2f8bcbe..1632b568f0 100644 --- a/src/Api/Jobs/JobsHostedService.cs +++ b/src/Api/Jobs/JobsHostedService.cs @@ -1,52 +1,27 @@ using System; -using System.Collections.Specialized; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Bit.Core.Jobs; using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; using Quartz; -using Quartz.Impl; -using Quartz.Impl.Matchers; namespace Bit.Api.Jobs { - public class JobsHostedService : IHostedService, IDisposable + public class JobsHostedService : BaseJobsHostedService { - private readonly IServiceProvider _serviceProvider; - private readonly ILogger _logger; - private readonly ILogger _listenerLogger; - private IScheduler _scheduler; - public JobsHostedService( IServiceProvider serviceProvider, ILogger logger, ILogger listenerLogger) + : base(serviceProvider, logger, listenerLogger) { } + + public override async Task StartAsync(CancellationToken cancellationToken) { - _serviceProvider = serviceProvider; - _logger = logger; - _listenerLogger = listenerLogger; - } - - public async Task StartAsync(CancellationToken cancellationToken) - { - var factory = new StdSchedulerFactory(new NameValueCollection - { - { "quartz.serializer.type", "binary" } - }); - _scheduler = await factory.GetScheduler(cancellationToken); - _scheduler.JobFactory = new JobFactory(_serviceProvider); - _scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger), - GroupMatcher.AnyGroup()); - await _scheduler.Start(cancellationToken); - - var aliveJob = JobBuilder.Create().Build(); - var validateUsersJob = JobBuilder.Create().Build(); - var validateOrganizationsJob = JobBuilder.Create().Build(); - var everyTopOfTheHourTrigger = TriggerBuilder.Create() .StartNow() - .WithCronSchedule("0 0 * * * ?") + .WithCronSchedule("* * * * * ?") .Build(); var everyTopOfTheSixthHourTrigger = TriggerBuilder.Create() .StartNow() @@ -57,19 +32,16 @@ namespace Bit.Api.Jobs .WithCronSchedule("0 30 */12 * * ?") .Build(); - await _scheduler.ScheduleJob(aliveJob, everyTopOfTheHourTrigger); - await _scheduler.ScheduleJob(validateUsersJob, everyTopOfTheSixthHourTrigger); - await _scheduler.ScheduleJob(validateOrganizationsJob, everyTwelfthHourAndThirtyMinutesTrigger); - } + Jobs = new List> + { + new Tuple(typeof(AliveJob), everyTopOfTheHourTrigger), + new Tuple(typeof(ValidateUsersJob), everyTopOfTheSixthHourTrigger), + new Tuple(typeof(ValidateOrganizationsJob), everyTwelfthHourAndThirtyMinutesTrigger) + }; - public async Task StopAsync(CancellationToken cancellationToken) - { - await _scheduler?.Shutdown(cancellationToken); + await base.StartAsync(cancellationToken); } - public void Dispose() - { } - public static void AddJobsServices(IServiceCollection services) { services.AddTransient(); diff --git a/src/Api/Jobs/ValidateOrganizationsJob.cs b/src/Api/Jobs/ValidateOrganizationsJob.cs index bfb2fad3d3..0abde3d6cb 100644 --- a/src/Api/Jobs/ValidateOrganizationsJob.cs +++ b/src/Api/Jobs/ValidateOrganizationsJob.cs @@ -1,34 +1,27 @@ using System; using System.Threading.Tasks; +using Bit.Core.Jobs; using Bit.Core.Services; using Microsoft.Extensions.Logging; using Quartz; namespace Bit.Api.Jobs { - public class ValidateOrganizationsJob : IJob + public class ValidateOrganizationsJob : BaseJob { private readonly ILicensingService _licensingService; - private readonly ILogger _logger; public ValidateOrganizationsJob( ILicensingService licensingService, ILogger logger) + : base(logger) { _licensingService = licensingService; - _logger = logger; } - public async Task Execute(IJobExecutionContext context) + protected async override Task ExecuteJobAsync(IJobExecutionContext context) { - try - { - await _licensingService.ValidateOrganizationsAsync(); - } - catch(Exception e) - { - _logger.LogError(2, e, "Error performing {0}.", nameof(ValidateOrganizationsJob)); - } + await _licensingService.ValidateUsersAsync(); } } } diff --git a/src/Api/Jobs/ValidateUsersJob.cs b/src/Api/Jobs/ValidateUsersJob.cs index 2018481075..c1f5c699b4 100644 --- a/src/Api/Jobs/ValidateUsersJob.cs +++ b/src/Api/Jobs/ValidateUsersJob.cs @@ -1,34 +1,26 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; +using Bit.Core.Jobs; using Bit.Core.Services; using Microsoft.Extensions.Logging; using Quartz; namespace Bit.Api.Jobs { - public class ValidateUsersJob : IJob + public class ValidateUsersJob : BaseJob { private readonly ILicensingService _licensingService; - private readonly ILogger _logger; public ValidateUsersJob( ILicensingService licensingService, ILogger logger) + : base(logger) { _licensingService = licensingService; - _logger = logger; } - public async Task Execute(IJobExecutionContext context) + protected async override Task ExecuteJobAsync(IJobExecutionContext context) { - try - { - await _licensingService.ValidateUsersAsync(); - } - catch(Exception e) - { - _logger.LogError(2, e, "Error performing {0}.", nameof(ValidateUsersJob)); - } + await _licensingService.ValidateUsersAsync(); } } } diff --git a/src/Core/Core.csproj b/src/Core/Core.csproj index e8e068382d..ebc2f09980 100644 --- a/src/Core/Core.csproj +++ b/src/Core/Core.csproj @@ -23,6 +23,7 @@ + diff --git a/src/Core/Jobs/BaseJob.cs b/src/Core/Jobs/BaseJob.cs new file mode 100644 index 0000000000..0e4b206d40 --- /dev/null +++ b/src/Core/Jobs/BaseJob.cs @@ -0,0 +1,31 @@ +using System; +using System.Threading.Tasks; +using Microsoft.Extensions.Logging; +using Quartz; + +namespace Bit.Core.Jobs +{ + public abstract class BaseJob : IJob + { + protected readonly ILogger _logger; + + public BaseJob(ILogger logger) + { + _logger = logger; + } + + public async Task Execute(IJobExecutionContext context) + { + try + { + await ExecuteJobAsync(context); + } + catch(Exception e) + { + _logger.LogError(2, e, "Error performing {0}.", GetType().Name); + } + } + + protected abstract Task ExecuteJobAsync(IJobExecutionContext context); + } +} diff --git a/src/Core/Jobs/BaseJobsHostedService.cs b/src/Core/Jobs/BaseJobsHostedService.cs new file mode 100644 index 0000000000..65c117d65d --- /dev/null +++ b/src/Core/Jobs/BaseJobsHostedService.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Quartz; +using Quartz.Impl; +using Quartz.Impl.Matchers; + +namespace Bit.Core.Jobs +{ + public abstract class BaseJobsHostedService : IHostedService, IDisposable + { + private readonly IServiceProvider _serviceProvider; + private readonly ILogger _listenerLogger; + protected readonly ILogger _logger; + + private IScheduler _scheduler; + + public BaseJobsHostedService( + IServiceProvider serviceProvider, + ILogger logger, + ILogger listenerLogger) + { + _serviceProvider = serviceProvider; + _logger = logger; + _listenerLogger = listenerLogger; + } + + public IEnumerable> Jobs { get; protected set; } + + public virtual async Task StartAsync(CancellationToken cancellationToken) + { + var factory = new StdSchedulerFactory(new NameValueCollection + { + { "quartz.serializer.type", "binary" } + }); + _scheduler = await factory.GetScheduler(cancellationToken); + _scheduler.JobFactory = new JobFactory(_serviceProvider); + _scheduler.ListenerManager.AddJobListener(new JobListener(_listenerLogger), + GroupMatcher.AnyGroup()); + await _scheduler.Start(cancellationToken); + if(Jobs != null) + { + foreach(var job in Jobs) + { + var builtJob = JobBuilder.Create(job.Item1).Build(); + await _scheduler.ScheduleJob(builtJob, job.Item2); + } + } + } + + public virtual async Task StopAsync(CancellationToken cancellationToken) + { + await _scheduler?.Shutdown(cancellationToken); + } + + public virtual void Dispose() + { } + } +} diff --git a/src/Api/Jobs/JobFactory.cs b/src/Core/Jobs/JobFactory.cs similarity index 96% rename from src/Api/Jobs/JobFactory.cs rename to src/Core/Jobs/JobFactory.cs index 57ebed26a1..2cd42035e4 100644 --- a/src/Api/Jobs/JobFactory.cs +++ b/src/Core/Jobs/JobFactory.cs @@ -2,7 +2,7 @@ using Quartz; using Quartz.Spi; -namespace Bit.Api.Jobs +namespace Bit.Core.Jobs { public class JobFactory : IJobFactory { diff --git a/src/Api/Jobs/JobListener.cs b/src/Core/Jobs/JobListener.cs similarity index 98% rename from src/Api/Jobs/JobListener.cs rename to src/Core/Jobs/JobListener.cs index 29c54f8275..4d44d65e27 100644 --- a/src/Api/Jobs/JobListener.cs +++ b/src/Core/Jobs/JobListener.cs @@ -4,7 +4,7 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Quartz; -namespace Bit.Api.Jobs +namespace Bit.Core.Jobs { public class JobListener : IJobListener {