Wasyster
Wasyster

Reputation: 2535

ASP.NET Core Quartz error on app start: DataSource name not set

I am trying to configure and start Quartz in my ASP.NET Core 8.0 project. In this project I configured Quartz like this:

public static class QuartzConfiguration
{
    public static void AddQuartzConfiguration(this WebApplicationBuilder builder)
    {
        var serviceProvider = builder.Services.BuildServiceProvider();
        
        var notificationCronExpression = serviceProvider.GetService<IOptions<NotificationCronJobExpressionSettings>>();
        var checkTaskStatusCronExpression = serviceProvider.GetService<IOptions<CheckStatusIntervalExpressionSettings>>();
        var legislativeCronExpression = serviceProvider.GetService<IOptions<LegislativeUpdatesRefreshCronExpressionSettings>>();
        var payRunTasksToAutoCompleteCronExpression = serviceProvider.GetService<IOptions<PayRunTYDmcVEzKLbAqWEQ4iXCPYVshvCf5tW9zAtings>>();

        builder.Services.AddQuartz(quartzConfigurator =>
        {
            quartzConfigurator.UseJobAutoInterrupt(options => options.DefaultMaxRunTime = TimeSpan.FromMinutes(10));
            quartzConfigurator.UseDefaultThreadPool(maxConcurrency: 1);
            quartzConfigurator.UseTimeZoneConverter();
            quartzConfigurator.UsePersistentStore(store =>
            {
                store.UseNewtonsoftJsonSerializer();
            });
            
            quartzConfigurator.AddQuartzJob<GenerateTaskStatusPollerFactory>(checkTaskStatusCronExpression.Value.Value, "CheckTaskStatus", "Test", "CheckTaskStatusTrigger", "GenerateTaskStatusPollerFactory");
            quartzConfigurator.AddQuartzJob<GenerateNotificationsPollerFactory>(notificationCronExpression.Value.Value, "GenerateNotifications", "Test", "GenerateNotificationsTrigger", "GenerateNotificationsPollerFactory");
            quartzConfigurator.AddQuartzJob<LegislativeUpdatePollerFactory>(legislativeCronExpression.Value.Value, "PollLegislativeUpdates", "Test", "PollLegislativeUpdatesTrigger", "LegislativeUpdatePollerFactory");
            quartzConfigurator.AddQuartzJob<PayRunTaskStatusPollerFactory>(payRunTasksToAutoCompleteCronExpression.Value.Value, "AutoCompletePayRunTasks", "Test", "AutoCompletePayRunTasksTrigger", "PayRunTaskStatusPollerFactory");
        });

        builder.Services.AddQuartzServer(options =>
        {
            // when shutting down we want jobs to complete gracefully
            options.WaitForJobsToComplete = true;
        });
    }

To simplify adding a job, I created an extension method:

public static class QuartzConfiguratorExtensions
{
    public static void AddQuartzJob<T>(this IServiceCollectionQuartzConfigurator quartzConfigurator,
                                      string cronExpression,
                                      string key, string group,
                                      string triggerName, string triggerGroup) where T: IJob
    {
        bool isCronExpressionValid = CronExpression.IsValidExpression(cronExpression);

        if(!isCronExpressionValid)
        {
            throw new Exception ($"{cronExpression} is not a valid cron expression for Quartz job {key}");
        }

        quartzConfigurator.AddJob<T>(jobConfigurator => jobConfigurator.WithIdentity(key, group));

        quartzConfigurator.AddTrigger(triggerConfigurator => triggerConfigurator
                          .ForJob(key)
                          .WithIdentity(triggerName, triggerGroup)
                          .WithCronSchedule(cronExpression));
    }
}

When I start my app, I got an error in Program.cs at line

app.Run();

and the error says:

DataSource name not set

Stack trace:

at   Quartz.Impl.AdoJobStore.JobStoreSupport.<Initialize>d__143.MoveNext()
at Quartz.Impl.AdoJobStore.JobStoreTX.<Initialize>d__0.MoveNext()
at Quartz.Impl.StdSchedulerFactory.<Instantiate>d__67.MoveNext()
at Quartz.Impl.StdSchedulerFactory.<Instantiate>d__67.MoveNext()
at Quartz.Impl.StdSchedulerFactory.<GetScheduler>d__73.MoveNext()
at Quartz.ServiceCollectionSchedulerFactory.<GetScheduler>d__6.MoveNext()
at Quartz.QuartzHostedService.<StartAsync>d__7.MoveNext()
at Microsoft.Extensions.Hosting.Internal.Host.<<StartAsync>b__15_1>d.MoveNext()
at Microsoft.Extensions.Hosting.Internal.Host.<ForeachService>d__18`1.MoveNext()
at Microsoft.Extensions.Hosting.Internal.Host.<StartAsync>d__15.MoveNext()
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.<RunAsync>d__4.MoveNext()
at Microsoft.Extensions.Hosting.HostingAbstractionsHostExtensions.Run(IHost host)
at Program.<Main>$(String[] args) in C:\_PROJECTS_\PPM\IIPay.PPM.Api\Program.cs:line 62

I tried to read all kind of stuff, but not found the solution.

Thanks

Upvotes: 0

Views: 84

Answers (1)

Wasyster
Wasyster

Reputation: 2535

So I found the way to set up the RAMJobStore. Even if the documentation says, that that is the default store, it's not. After setting the store like bellow, it started to work.

store.SetProperty("quartz.jobStore.type", "Quartz.Simpl.RAMJobStore, Quartz");

If you want to use some DB as a store you can define it like bellow (example for MS SQL server):

store.UseSqlServer(coonectionString);
store.PerformSchemaValidation = true;

Upvotes: 0

Related Questions