I am using .net6 with my api project having quartz.net references. Basically trying to send scheduled email notifications using .net core 6 and quartz.net. The code works OK if I use 'UseInMemoryStore', but wanted to use sql server with 'AdoJobStore'.
There is no data going into the job quartz tables created (example : JOB_DETAILS). What amI missing ?
Here are the code I used along with appsettings.json.
program.cs
builder.Services.Configure<QuartzOptions>(builder.Configuration.GetSection("Quartz"));
builder.Services.AddQuartz();
builder.Services.AddQuartzHostedService(options =>
{
// when shutting down we want jobs to complete gracefully
options.WaitForJobsToComplete = true;
});
// Add Quartz services
builder.Services.AddSingleton<ISchedulerFactory, StdSchedulerFactory>();
builder.Services.AddSingleton<SchedulerManager>();
builder.Services.AddHostedService<SchedulerManager>();
**appsettings.json**
"Quartz": {
"quartz.jobStore.useProperties": "true",
"quartz.scheduler.instanceName": "MySchedulerLocal",
"quartz.scheduler.instanceId": "AUTO",
"quartz.scheduler.idleWaitTime": "300000",
"quartz.scheduler.interruptJobsOnShutdown": "true",
"quartz.scheduler.interruptJobsOnShutdownWithWait": "true",
"quartz.jobStore.type": "Quartz.Impl.AdoJobStore.JobStoreTX, Quartz",
"quartz.jobStore.driverDelegateType":"Quartz.Impl.....,Quartz",
"quartz.jobStore.misfireThreshold": "420000",
"quartz.jobStore.tablePrefix": "tbl_sched_",
"quartz.jobStore.clustered": "false",
"quartz.dataSource.quartzDataSource.provider": "SqlServer",
"quartz.jobStore.dataSource": "quartzDataSource",
"quartz.dataSource.quartzDataSource.connectionString":"
}
**SchedulerManager**
public class SchedulerManager : IHostedService
{
private readonly ISchedulerFactory _schedulerFactory;
private readonly IJobFactory _jobFactory;
private readonly IEnumerable<JobSchedule> _jobSchedules;
private readonly ILogger<SchedulerManager> _logger;
public SchedulerManager(
ISchedulerFactory schedulerFactory,
IJobFactory jobFactory,
IEnumerable<JobSchedule> jobSchedules
, ILogger<SchedulerManager> logger)
{
_schedulerFactory = schedulerFactory;
_jobSchedules = jobSchedules;
_jobFactory = jobFactory;
_logger = logger;
}
public IScheduler Scheduler { get; set; }
public async Task CreateJobTrigger<T>(string jobName, string groupName, string jobDescription, string triggerName, string cronExpression, Dictionary<string, string> jobMap, bool storeDurably = true) where T : BaseJobMgr
{
IJobDetail? quartzJob = null;
try
{
var Sched = await _schedulerFactory.GetScheduler(CancellationToken.None);
if (Sched == null || Sched.IsShutdown)
{
throw new Exception("Scheduler is null or shutdown.");
}
var jobKey = new JobKey(jobName, groupName);
quartzJob = JobBuilder.Create<T>()
.WithIdentity(jobKey)
.StoreDurably(storeDurably)
.WithDescription(jobDescription)
.Build();
if (jobMap != null)
{
foreach (KeyValuePair<string, string> entry in jobMap)
{
quartzJob.JobDataMap[entry.Key] = entry.Value;
}
}
//Check for current triggers
var existingTrigger = Sched.GetTrigger(new TriggerKey(triggerName!, groupName!)).Result;
// Delete trigger if blank config
if (existingTrigger != null && string.IsNullOrWhiteSpace(cronExpression))
{
Sched.UnscheduleJob(new TriggerKey(triggerName!, groupName!)).Wait();
}
// Reschedule trigger if different
else if (existingTrigger != null && !string.IsNullOrWhiteSpace(cronExpression) && ((Quartz.Impl.Triggers.CronTriggerImpl)existingTrigger).CronExpressionString != cronExpression) //TODO
{
ITrigger quartzTrigger = TriggerBuilder.Create()
.WithIdentity(triggerName!, groupName!)
.WithCronSchedule(cronExpression)
//.ForJob("myJob", "group1")
.Build();
await Sched.ScheduleJob(quartzJob!, quartzTrigger);
}
// Create trigger if not exists
else if (existingTrigger == null && !string.IsNullOrWhiteSpace(cronExpression))
{
ITrigger quartzTrigger = TriggerBuilder.Create()
.WithIdentity(triggerName!, groupName!)
.WithCronSchedule(cronExpression)
.Build();
await Sched.ScheduleJob(quartzJob!, quartzTrigger);
}
}
catch (Exception ex)
{
_logger.LogError("Error- error while creating job {0} : ",ex);
throw ex;
}
}
public async Task StartAsync(CancellationToken cancellationToken)
{
_logger.LogInformation("StartAsync() started...");
Scheduler = await _schedulerFactory.GetScheduler(cancellationToken);
Scheduler.JobFactory = _jobFactory;
await Scheduler.Start(cancellationToken);
}
private static ITrigger Trigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.StartNow()
.WithDescription("")
.Build();
}
public async Task StopAsync(CancellationToken cancellationToken)
{
await Scheduler?.Shutdown(cancellationToken);
}
private static IJobDetail CreateJob(JobSchedule schedule)
{
var jobType = schedule.JobType;
return JobBuilder
.Create(jobType)
.WithIdentity(jobType.FullName)
.WithDescription(jobType.Name)
.Build();
}
private static ITrigger CreateTrigger(JobSchedule schedule)
{
return TriggerBuilder
.Create()
.WithIdentity($"{schedule.JobType.FullName}.trigger")
.WithCronSchedule(schedule.CronExpression)
.WithDescription(schedule.CronExpression)
.Build();
}
}
thanks g