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
{