I’m using .NET 8 and I’m trying to setup a Quartz Job.
What I want to achieve is that in production, this job must be scheduled (with a cron schedule), but in dev and in local I don’t need it scheduled, but I still need it to be registered because I want to be able to run a OneTimeJob from a Controller endpoint.
This is my setup:
Inside the Startup.cs
<code> var environmentType = Environment.Type;
services.AddQuartzHostedService(opt =>
opt.WaitForJobsToComplete = true;
if (Environment.Type == EnvironmentType.Production)
services.ConfigureOptions<ProcessIssuersJobSetupWithCron>();
else if (environmentType is EnvironmentType.TestingRc or EnvironmentType.TestingMaster or EnvironmentType.Staging or EnvironmentType.Local)
services.ConfigureOptions<ProcessIssuersJobSetupWithoutCron>();
<code> var environmentType = Environment.Type;
services.AddQuartz();
services.AddQuartzHostedService(opt =>
{
opt.WaitForJobsToComplete = true;
});
if (Environment.Type == EnvironmentType.Production)
{
services.ConfigureOptions<ProcessIssuersJobSetupWithCron>();
}
else if (environmentType is EnvironmentType.TestingRc or EnvironmentType.TestingMaster or EnvironmentType.Staging or EnvironmentType.Local)
{
services.ConfigureOptions<ProcessIssuersJobSetupWithoutCron>();
}
</code>
var environmentType = Environment.Type;
services.AddQuartz();
services.AddQuartzHostedService(opt =>
{
opt.WaitForJobsToComplete = true;
});
if (Environment.Type == EnvironmentType.Production)
{
services.ConfigureOptions<ProcessIssuersJobSetupWithCron>();
}
else if (environmentType is EnvironmentType.TestingRc or EnvironmentType.TestingMaster or EnvironmentType.Staging or EnvironmentType.Local)
{
services.ConfigureOptions<ProcessIssuersJobSetupWithoutCron>();
}
Let’s focus on the WithoutCron job:
<code>public class ProcessIssuersJobSetupWithoutCron : IConfigureOptions<QuartzOptions>
public void Configure(QuartzOptions options)
var processIssuersJobKey = JobKey.Create("ProcessIssuersJob");
.AddJob<ProcessIssuersJob>(jobBuilder => jobBuilder.WithIdentity(processIssuersJobKey))
.ForJob(jobKey: processIssuersJobKey));
<code>public class ProcessIssuersJobSetupWithoutCron : IConfigureOptions<QuartzOptions>
{
public void Configure(QuartzOptions options)
{
var processIssuersJobKey = JobKey.Create("ProcessIssuersJob");
options
.AddJob<ProcessIssuersJob>(jobBuilder => jobBuilder.WithIdentity(processIssuersJobKey))
.AddTrigger(trigger =>
trigger
.ForJob(jobKey: processIssuersJobKey));
}
}
</code>
public class ProcessIssuersJobSetupWithoutCron : IConfigureOptions<QuartzOptions>
{
public void Configure(QuartzOptions options)
{
var processIssuersJobKey = JobKey.Create("ProcessIssuersJob");
options
.AddJob<ProcessIssuersJob>(jobBuilder => jobBuilder.WithIdentity(processIssuersJobKey))
.AddTrigger(trigger =>
trigger
.ForJob(jobKey: processIssuersJobKey));
}
}
And from my Controller I try to trigger that in this way:
<code>public class QuartzController(ISchedulerFactory scheduleFactory) : Controller
private readonly ISchedulerFactory _scheduleFactory = scheduleFactory;
[HttpPost("ProcessIssuers")]
public async Task<IActionResult> ExecuteDataStoredProcedures([FromQuery] DateTime runDate)
var scheduler = await this._scheduleFactory.GetScheduler();
var jobKey = JobKey.Create("ProcessIssuersJob");
var jobDataMap = new JobDataMap();
jobDataMap.Put("runDate", runDate);
await scheduler.TriggerJob(jobKey, jobDataMap);
<code>public class QuartzController(ISchedulerFactory scheduleFactory) : Controller
{
private readonly ISchedulerFactory _scheduleFactory = scheduleFactory;
[HttpPost("ProcessIssuers")]
public async Task<IActionResult> ExecuteDataStoredProcedures([FromQuery] DateTime runDate)
{
var scheduler = await this._scheduleFactory.GetScheduler();
var jobKey = JobKey.Create("ProcessIssuersJob");
var jobDataMap = new JobDataMap();
jobDataMap.Put("runDate", runDate);
await scheduler.TriggerJob(jobKey, jobDataMap);
return this.Ok();
}
}
</code>
public class QuartzController(ISchedulerFactory scheduleFactory) : Controller
{
private readonly ISchedulerFactory _scheduleFactory = scheduleFactory;
[HttpPost("ProcessIssuers")]
public async Task<IActionResult> ExecuteDataStoredProcedures([FromQuery] DateTime runDate)
{
var scheduler = await this._scheduleFactory.GetScheduler();
var jobKey = JobKey.Create("ProcessIssuersJob");
var jobDataMap = new JobDataMap();
jobDataMap.Put("runDate", runDate);
await scheduler.TriggerJob(jobKey, jobDataMap);
return this.Ok();
}
}
but when it comes to the await.scheduler.TriggerJob(jobKey, jobDataMap); I’m getting this error:
<code>Exception Type: Quartz.JobPersistenceException
Error message: The job (DEFAULT.ProcessIssuersJob) referenced by the trigger does not exist.
<code>Exception Type: Quartz.JobPersistenceException
Error message: The job (DEFAULT.ProcessIssuersJob) referenced by the trigger does not exist.
</code>
Exception Type: Quartz.JobPersistenceException
Error message: The job (DEFAULT.ProcessIssuersJob) referenced by the trigger does not exist.
I tried to debug and it actually arrives inside the ProcessIssuersJobSetupWithoutCron Configure method, and the key is the same: DEFAULT.ProcessIssuersJob .
What am I doing wrong? I’m not 100% but I think when I was using the ProcessIssuersWithCron it was working the one time job.. here’s the setup with cron::
<code>public class ProcessIssuersJobSetupWithCron : IConfigureOptions<QuartzOptions>
private static readonly string MonthlyJobCronExpression;
static ProcessIssuersJobSetupWithCron()
MonthlyJobCronExpression = AppSettingBuilder<string>
.Create("MonthlyJobCronExpression", System.Configuration.ConfigurationManager.AppSettings)
public void Configure(QuartzOptions options)
var processIssuersJobKey = JobKey.Create("ProcessIssuersJob");
if (MonthlyJobCronExpression.IsNullOrEmpty())
.AddJob<ProcessIssuersJob>(jobBuilder => jobBuilder.WithIdentity(processIssuersJobKey))
.ForJob(jobKey: processIssuersJobKey)
.WithCronSchedule(MonthlyJobCronExpression, cron => cron.InTimeZone(TimeZoneInfo.Utc)));
<code>public class ProcessIssuersJobSetupWithCron : IConfigureOptions<QuartzOptions>
{
private static readonly string MonthlyJobCronExpression;
static ProcessIssuersJobSetupWithCron()
{
MonthlyJobCronExpression = AppSettingBuilder<string>
.Create("MonthlyJobCronExpression", System.Configuration.ConfigurationManager.AppSettings)
.ToSetting()
.Value;
}
public void Configure(QuartzOptions options)
{
var processIssuersJobKey = JobKey.Create("ProcessIssuersJob");
if (MonthlyJobCronExpression.IsNullOrEmpty())
{
return;
}
options
.AddJob<ProcessIssuersJob>(jobBuilder => jobBuilder.WithIdentity(processIssuersJobKey))
.AddTrigger(trigger =>
trigger
.ForJob(jobKey: processIssuersJobKey)
.WithCronSchedule(MonthlyJobCronExpression, cron => cron.InTimeZone(TimeZoneInfo.Utc)));
}
}
</code>
public class ProcessIssuersJobSetupWithCron : IConfigureOptions<QuartzOptions>
{
private static readonly string MonthlyJobCronExpression;
static ProcessIssuersJobSetupWithCron()
{
MonthlyJobCronExpression = AppSettingBuilder<string>
.Create("MonthlyJobCronExpression", System.Configuration.ConfigurationManager.AppSettings)
.ToSetting()
.Value;
}
public void Configure(QuartzOptions options)
{
var processIssuersJobKey = JobKey.Create("ProcessIssuersJob");
if (MonthlyJobCronExpression.IsNullOrEmpty())
{
return;
}
options
.AddJob<ProcessIssuersJob>(jobBuilder => jobBuilder.WithIdentity(processIssuersJobKey))
.AddTrigger(trigger =>
trigger
.ForJob(jobKey: processIssuersJobKey)
.WithCronSchedule(MonthlyJobCronExpression, cron => cron.InTimeZone(TimeZoneInfo.Utc)));
}
}