Quartz.net with .net 6.0 - AdoJobStore using SQL Server not creating job records

91 Views Asked by At

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

0

There are 0 best solutions below