public void RemoveSchedule(Schedule schedule)
 {
     var triggerKey = new TriggerKey(schedule.Id.ToString(), schedule.CommandId.ToString());
     var jobKey = new JobKey(schedule.Id.ToString(), schedule.CommandId.ToString());
     scheduler.UnscheduleJob(triggerKey);
     scheduler.DeleteJob(jobKey);
 }
Beispiel #2
0
 public JobInfo(JobKey id, JobDetailImpl job)
 {
     Id = id;
     Job = job;
     Triggers = new TriggerInfo[0];
     TriggerCount = 0;
 }
        public void ShouldDisposeScopeAfterJobCompletion()
        {
            var key = new JobKey("disposable", "grp2");
            var job1 = JobBuilder.Create<SampleJob>().WithIdentity(key).StoreDurably(true)
                .Build();
            var trigger =
                TriggerBuilder.Create().WithSimpleSchedule(s => s.WithIntervalInSeconds(1).WithRepeatCount(1)).Build();

            var scopesCreated = 0;
            var scopesDisposed = 0;
            DisposableDependency dependency = null;

            _lifetimeScope.ChildLifetimeScopeBeginning += (sender, args) =>
            {
                scopesCreated++;
                dependency = args.LifetimeScope.Resolve<DisposableDependency>();
                args.LifetimeScope.CurrentScopeEnding += (o, eventArgs) => { scopesDisposed++; };
            };

            _scheduler.ScheduleJob(job1, trigger);
            _scheduler.Start();

            Thread.Sleep(3.Seconds());

            _jobFactory.RunningJobs.Should().BeEmpty("Scope was not disposed after job completion");
            dependency.Disposed.Should().BeTrue("Dependency must be disposed");
            scopesDisposed.Should().Be(scopesCreated, "All scopes must be disposed");
        }
 public static void ScheduleJob(this IScheduler scheduler, JobKey jobKey, string scheduleText, TimeZoneInfo timeZone)
 {
     TextToScheduleFactory factory = new TextToScheduleFactory();
     var english = factory.CreateEnglishParser();
     var results = english.Parse(scheduleText, timeZone);
     results.ScheduleWithJobKey(scheduler, jobKey);
 }
Beispiel #5
0
            public JobSchedule GetSchedule()
            {
                var jobKey = new JobKey(JobName, JobGroup);

                var trigger = Instance.GetTriggersOfJob(jobKey).FirstOrDefault();

                var js = new JobSchedule();

                if (trigger != null)
                {
                    js.Name = trigger.Key.Name;
                    js.Group = trigger.Key.Group;
                    js.Description = trigger.Description;
                    js.Priority = trigger.Priority;
                    js.TriggerType = trigger.GetType().Name;
                    js.TriggerState = Instance.GetTriggerState(trigger.Key).ToString();

                    DateTimeOffset? startTime = trigger.StartTimeUtc;
                    js.StartTime = TimeZone.CurrentTimeZone.ToLocalTime(startTime.Value.DateTime);

                    var nextFireTime = trigger.GetNextFireTimeUtc();
                    if (nextFireTime.HasValue)
                    {
                        js.NextFire = TimeZone.CurrentTimeZone.ToLocalTime(nextFireTime.Value.DateTime);
                    }

                    var previousFireTime = trigger.GetPreviousFireTimeUtc();
                    if (previousFireTime.HasValue)
                    {
                        js.LastFire = TimeZone.CurrentTimeZone.ToLocalTime(previousFireTime.Value.DateTime);
                    }
                }

                return js;
            }
        public void ExceptionPolicyNoRestartImmediately()
        {
            sched.Start();
            JobKey jobKey = new JobKey("ExceptionPolicyNoRestartJob", "ExceptionPolicyNoRestartGroup");
            JobDetailImpl exceptionJob = new JobDetailImpl(jobKey.Name, jobKey.Group, typeof (ExceptionJob));
            exceptionJob.Durable = true;
            sched.AddJob(exceptionJob, false);

            ExceptionJob.ThrowsException = true;
            ExceptionJob.Refire = false;
            ExceptionJob.UnscheduleAllTriggers = false;
            ExceptionJob.UnscheduleFiringTrigger = false;
            ExceptionJob.LaunchCount = 0;
            sched.TriggerJob(jobKey);

            int i = 10;
            while ((i > 0) && (ExceptionJob.LaunchCount <= 1))
            {
                i--;
                Thread.Sleep(200);
                if (ExceptionJob.LaunchCount > 1)
                {
                    break;
                }
            }
            sched.DeleteJob(jobKey);
            Assert.AreEqual(1, ExceptionJob.LaunchCount, "The job should NOT have been refired after exception");
        }
 public void JobDeleted(JobKey jobKey)
 {
     foreach (ISchedulerListener listener in listeners)
     {
         listener.JobDeleted(jobKey);
     }
 }
Beispiel #8
0
        public void AddRepeatingJob(Type aType, string aName, string aGroup, int aSecondsToSleep, params JobItem[] aItems)
        {
            JobKey key = new JobKey(aName, aGroup);
            if (Scheduler.GetJobDetail(key) != null)
            {
                Log.Error("AddRepeatingJob(" + aType.Name + ", " + aName + ", " + aGroup + ") already exists");
                return;
            }
            Log.Info("AddRepeatingJob(" + aType.Name + ", " + aName + ", " + aGroup + ", " + aSecondsToSleep + ")");

            _scheduledJobs.Add(key);

            var data = new JobDataMap();
            foreach (JobItem item in aItems)
            {
                data.Add(item.Key, item.Value);
            }

            IJobDetail job = JobBuilder.Create(aType)
                .WithIdentity(key)
                .UsingJobData(data)
                .Build();

            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity(aName, aGroup)
                .WithSimpleSchedule(x => x.WithIntervalInSeconds(aSecondsToSleep).RepeatForever())
                .Build();

            Scheduler.ScheduleJob(job, trigger);
        }
        public JobDetailsData GetJobDetailsData(JobKey jobKey)
        {
            var scheduler = _schedulerProvider.Scheduler;

            if (scheduler.IsShutdown)
            {
                return null;
            }

            var job = scheduler.GetJobDetail(jobKey);
            if (job == null)
            {
                return null;
            }

            var detailsData = new JobDetailsData
            {
                PrimaryData = GetJobData(scheduler, jobKey)
            };

            foreach (var key in job.JobDataMap.Keys)
            {
                detailsData.JobDataMap.Add(key, job.JobDataMap[key]);
            }

            detailsData.JobProperties.Add("Description", job.Description);
            detailsData.JobProperties.Add("Full name", job.Key.Name);
            detailsData.JobProperties.Add("Job type", job.JobType);
            detailsData.JobProperties.Add("Durable", job.Durable);
            //detailsData.JobProperties.Add("Volatile", job.);

            return detailsData;
        }
        public object Deserialize(global::MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
        {
            if (nominalType != typeof(JobKey) || actualType != typeof(JobKey))
            {
                var message = string.Format("Can't deserialize a {0} from {1}.", nominalType.FullName, this.GetType().Name);
                throw new BsonSerializationException(message);
            }

            var bsonType = bsonReader.CurrentBsonType;
            if (bsonType == BsonType.Document)
            {
                JobKey item;
                
                bsonReader.ReadStartDocument();
                item = new JobKey(
                    bsonReader.ReadString("Name"),
                    bsonReader.ReadString("Group"));
                bsonReader.ReadEndDocument();

                return item;
            }
            else if (bsonType == BsonType.Null)
            {
                bsonReader.ReadNull();
                return null;
            }
            else
            {
                var message = string.Format("Can't deserialize a {0} from BsonType {1}.", nominalType.FullName, bsonType);
                throw new BsonSerializationException(message);
            }
        }
        public HttpResponseMessage PostTriggerJob(string id)
        {
            JobKey jobKey = new JobKey(id);

            _scheduler.TriggerJob(jobKey);

            return new HttpResponseMessage();
        }
 private static IEnumerable<TriggerWithState> GetTriggers(ISchedulerWrapper scheduler, JobKey jobKey) {
     var triggers = scheduler.GetTriggersOfJob(jobKey);
     if (triggers == null)
         return null;
     return triggers.Select(t => {
         var state = scheduler.GetTriggerState(t.Key);
         return new TriggerWithState(t, state);
     });
 }
        public JobModel(IScheduler scheduler, JobKey jobKey)
        {
            foreach (ITrigger trigger in scheduler.GetTriggersOfJob(jobKey))
            {
                _triggersForJob.Add(new TriggerModel(trigger));
            }

            MapValuesFromJobDetail(scheduler.GetJobDetail(jobKey));
        }
        private bool IsBelongsToGroup(JobKey jobKey)
        {
            var jobDetail = _scheduler.GetJobDetail(jobKey);
            if (jobDetail.JobDataMap == null || !jobDetail.JobDataMap.Contains("data"))
                return false;

            var data = JsonConvert.DeserializeObject<SendCreativePackagesWithIntervalTask.Data>((string) jobDetail.JobDataMap["data"]);
            return data.Group == Group;
        }
Beispiel #15
0
 /// <summary>
 /// 删除现有任务
 /// </summary>
 /// <param name="JobKey"></param>
 public static void DeleteJob(string JobKey)
 {
     JobKey jk = new JobKey(JobKey);
     if (scheduler.CheckExists(jk))
     {
         //任务已经存在则删除
         scheduler.DeleteJob(jk);
         LogHelper.WriteLog(string.Format("任务“{0}”已经删除", JobKey));
     }
 }
        private static ICronTrigger CreateTrigger(DepotSchedule depotSchedule, Depot depot, JobKey jobKey)
        {
            var expression = CronExpressionConverter.ConvertToCronExpression(depotSchedule.DaysOfTheWeek, depotSchedule.Hour, depotSchedule.Minutes);
            //This is for debugging purposes
            //var result = CronExpression.IsValidExpression(expression);

            var timezone = TimeZoneInfo.GetSystemTimeZones().Single(tz => tz.Id == depot.TimeZoneId);

            var cronScheduleBuilder = CronScheduleBuilder.CronSchedule(expression).InTimeZone(timezone).WithMisfireHandlingInstructionFireAndProceed();
            return (ICronTrigger) TriggerBuilder.Create().ForJob(jobKey).WithSchedule(cronScheduleBuilder).Build();
        }
 public static Response Execute(RelativeUri url, Func<ISchedulerWrapper> getScheduler) {
     var scheduler = getScheduler();
     var querystring = url.ParseQueryString();
     var highlight = querystring["highlight"];
     var group = querystring["group"];
     var job = querystring["job"];
     var jobKey = new JobKey(job, group);
     var triggers = GetTriggers(scheduler, jobKey);
     var m = new TriggersByJobModel(triggers, url.PathAndQuery, group, job, highlight);
     return new Response.XDocumentResponse(Helpers.XHTML(Views.Views.TriggersByJob(m)));
 }
        /// <summary>
        /// Schedules the Triggers with a given job key.
        /// </summary>
        /// <param name="sched">The sched.</param>
        /// <param name="jobKey">The job key.</param>
        public void ScheduleWithJobKey(IScheduler sched, JobKey jobKey)
        {
            RegisterCalendars(sched);

            foreach (var group in RegisterGroups)
            {
                group.TriggerBuilder.ForJob(jobKey);

                ITrigger trigger = group.TriggerBuilder.Build();
                sched.ScheduleJob(trigger);
            }
        }
 public static void Execute(HttpContextBase context, Func<ISchedulerWrapper> getScheduler)
 {
     var scheduler = getScheduler();
     var highlight = context.Request.QueryString["highlight"];
     var group = context.Request.QueryString["group"];
     var job = context.Request.QueryString["job"];
     var jobKey = new JobKey(job, group);
     var triggers = GetTriggers(scheduler, jobKey);
     var thisUrl = context.Request.RawUrl;
     var m = new TriggersByJobModel(triggers, thisUrl, group, job, highlight);
     context.Response.Html(Helpers.XHTML(Views.Views.TriggersByJob(m)));
 }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="scheduler"></param>
        /// <param name="dellist"></param>
        public static void deleteJob(Quartz.IScheduler scheduler, List<Config> dellist)
        {
            IList<JobKey> jlist = new List<Quartz.JobKey>();

            foreach (var it in dellist)
            {
                JobKey key = new JobKey(it.jobname, it.groupname);
                jlist.Add(key);

            }

            scheduler.DeleteJobs(jlist);
        }
        /// <summary>
        /// Add a chain mapping - when the Job identified by the first key completes
        /// the job identified by the second key will be triggered.
        /// </summary>
        /// <param name="firstJob">a JobKey with the name and group of the first job</param>
        /// <param name="secondJob">a JobKey with the name and group of the follow-up job</param>
        public void AddJobChainLink(JobKey firstJob, JobKey secondJob)
        {
            if (firstJob == null || secondJob == null)
            {
                throw new ArgumentException("Key cannot be null!");
            }
            if (firstJob.Name == null || secondJob.Name == null)
            {
                throw new ArgumentException("Key cannot have a null name!");
            }

            chainLinks.Add(firstJob, secondJob);
        }
        private void ScheduleGreetingJob()
        {
            var key = new JobKey("GreetingJob");

            var jobDetail = JobBuilder.Create<IGreetingJob>()
                .WithIdentity(key)
                .Build();

            var trigger = TriggerBuilder.Create()
                .WithIdentity("GreetingTrigger")
                .StartAt(new DateTimeOffset(new DateTime(2016, 5, 5, 7, 45, 0)))
                .ForJob(jobDetail)
                .Build();

            scheduler.ScheduleJob(jobDetail, trigger);
        }
 public static void Execute(HttpContextBase context, Func<IScheduler> getScheduler)
 {
     var scheduler = getScheduler();
     var group = context.Request.QueryString["group"];
     var job = context.Request.QueryString["job"];
     var jobKey = new JobKey(job, group);
     var thisUrl = context.Request.RawUrl;
     var triggers = scheduler.GetTriggersOfJob(jobKey)
         .Select(t => {
             var state = scheduler.GetTriggerState(t.Key);
             return new TriggerWithState(t, state);
         });
     var highlight = context.Request.QueryString["highlight"];
     var m = new TriggersByJobModel(triggers, thisUrl, group, job, highlight);
     context.Response.Html(Helpers.XHTML(Views.Views.TriggersByJob(m)));
 }
        private void ScheduleAwardFinesFromReactionJob()
        {
            var key = new JobKey("AwardFinesFromReactionJob");

            var jobDetail = JobBuilder.Create<IAwardFinesFromReactionJob>()
                .WithIdentity(key)
                .Build();

            var trigger = TriggerBuilder.Create()
                .WithIdentity("AwardFinesFromReactionTrigger")
                //.StartNow()
                .StartAt(DateBuilder.TodayAt(18, 0, 0))
                .WithSimpleSchedule(x => x
                    .WithIntervalInHours(24)
                    .RepeatForever())
                .Build();

            scheduler.ScheduleJob(jobDetail, trigger);
        }
        /// <summary>
        /// 修改
        /// </summary>
        /// <param name="scheduler"></param>
        /// <param name="modilist"></param>
        public static void modiJob(Quartz.IScheduler scheduler, List<Config> modilist)
        {
            //   scheduler.GetTrigger(new TriggerKey(

            foreach (var item in modilist)
            {

                //var old = scheduler.GetTrigger(new TriggerKey(item.jobname + "trigger", "触发器组"));
                //if (old == null)
                //    return;

                //var newtrigger = addTriger(item).Build();
                //scheduler.RescheduleJob(old.Key, newtrigger);

                JobKey key = new JobKey(item.jobname, item.groupname);
                scheduler.DeleteJob(key);
                addjob(scheduler, item);

            }
        }
        public void Start()
        {
            using (var context = new QuartzDbContext())
            {
                var depots = context.Depots.ToList();
                var schedules = context.DepotSchedules.ToList();

                foreach (var depot in depots)
                {
                    var schedule = schedules.Single(s => s.DepotId == depot.Id);

                    var jobKey = new JobKey(depot.Id.ToString(), "Depot Supply Schedule");
                    var jobDetail = JobBuilder.Create<CustomJob>().WithIdentity(jobKey).Build();
                    var trigger = CreateTrigger(schedule, depot, jobKey);

                    scheduler.ScheduleJob(jobDetail, trigger);
                }
            }
            Console.WriteLine("Job Has been Setup");
        }
Beispiel #27
0
        public object ExecuteJob(JobKey jobKey)
        {
            IJobDetail detail = Scheduler.GetJobDetail(jobKey);

            if (detail == null)
            {
                return null;
            }

            try
            {
                using (var instance = (CronshopJob) Activator.CreateInstance(detail.JobType))
                {
                    return instance.ExecuteJob(null);
                }
            }
            catch
            {
                return null;
            }
        }
Beispiel #28
0
        public void ExceptionPolicyRestartImmediately()
        {
            sched.Start();
            JobKey jobKey = new JobKey("ExceptionPolicyRestartJob", "ExceptionPolicyRestartGroup");
            IJobDetail exceptionJob = JobBuilder.Create<ExceptionJob>()
                .WithIdentity(jobKey)
                .StoreDurably()
                .Build();

            sched.AddJob(exceptionJob, false);

            ExceptionJob.ThrowsException = true;
            ExceptionJob.Refire = true;
            ExceptionJob.UnscheduleAllTriggers = false;
            ExceptionJob.UnscheduleFiringTrigger = false;
            ExceptionJob.LaunchCount = 0;
            sched.TriggerJob(jobKey);

            int i = 10;
            while ((i > 0) && (ExceptionJob.LaunchCount <= 1))
            {
                i--;
                Thread.Sleep(200);
                if (ExceptionJob.LaunchCount > 1)
                {
                    break;
                }
            }
            // to ensure job will not be refired in consequent tests
            // in fact, it would be better to have a separate class
            ExceptionJob.ThrowsException = false;

            Thread.Sleep(1000); 
            sched.DeleteJob(jobKey);
            Thread.Sleep(1000);
            Assert.Greater(ExceptionJob.LaunchCount, 1, "The job should have been refired after exception");
        }
        /// <summary>
        /// Called by the <see cref="IScheduler" /> when a <see cref="ITrigger" />
        /// fires that is associated with the <see cref="IJob" />.
        /// </summary>
        public virtual void Execute(IJobExecutionContext context)
        {
            jobKey = context.JobDetail.Key;
            log.InfoFormat("---- {0} executing at {1}", jobKey, DateTime.Now.ToString("r"));

            try
            {
                // main job loop... see the JavaDOC for InterruptableJob for discussion...
                // do some work... in this example we are 'simulating' work by sleeping... :)

                for (int i = 0; i < 4; i++)
                {
                    try
                    {
                        Thread.Sleep(10 * 1000);
                    }
                    catch (Exception ignore)
                    {
                        Console.WriteLine(ignore.StackTrace);
                    }

                    // periodically check if we've been interrupted...
                    if (interrupted)
                    {
                        log.InfoFormat("--- {0}  -- Interrupted... bailing out!", jobKey);
                        return ; // could also choose to throw a JobExecutionException
                        // if that made for sense based on the particular
                        // job's responsibilities/behaviors
                    }
                }
            }
            finally
            {
                log.InfoFormat("---- {0} completed at {1}", jobKey, DateTime.Now.ToString("r"));
            }
        }
Beispiel #30
0
 /// <summary>
 /// Calls the equivalent method on the 'proxied' <see cref="QuartzScheduler" />.
 /// </summary>
 public virtual Task <IReadOnlyList <ITrigger> > GetTriggersOfJob(JobKey jobKey)
 {
     return(CallInGuard(x => x.GetTriggersOfJob(jobKey)));
 }
Beispiel #31
0
        /// <summary>
        /// 添加一个工作调度
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task <ResultValue> AddScheduleJobAsync(ScheduleEntity entity)
        {
            var result = new ResultValue();

            try
            {
                //检查任务是否已存在
                var jobKey = new JobKey(entity.JobName, entity.JobGroup);
                if (await Scheduler.CheckExists(jobKey))
                {
                    result.MsgCode = 3;
                    result.Msg     = "任务已存在";
                    return(result);
                }

                ////加载程序集(dll文件地址),使用Assembly类
                //var asstypes = Assembly.Load("BusDataExchan").GetTypes()
                //    .Where(t => t.GetInterfaces().Contains(typeof(IJob)))
                //    .ToArray();

                if (entity.TargetCall.IndexOf(",") < 0)
                {
                    result.MsgCode = 3;
                    result.Msg     = "对象名称格式不符合Job-Type";
                    return(result);
                }
                var    Assemblys = entity.TargetCall.Split(',');
                string dllname   = Assemblys[1];
                string jobname   = Assemblys[0];

                //获取类型,参数(名称空间+类)
                Type _ijob = null;
                try
                {
                    _ijob = Assembly.Load(dllname).GetType(jobname);
                }
                catch (Exception err)
                {
                    //日志err
                    result.MsgCode = 3;
                    result.Msg     = "未找到描述的对象";
                    return(result);
                }

                //配置
                var DataDir = new Dictionary <string, string>()
                {
                    { Constant.TARGETCALL, entity.TargetCall },
                    { Constant.TARGETTYPE, entity.TargetType },
                    //{ Constant.MAILMESSAGE, ((int)entity.MailMessage).ToString()},
                };
                if (_ijob == null)
                {
                    result.MsgCode = 3;
                    result.Msg     = "未找到调度器";
                    return(result);
                }

                // 定义这个工作,并将其绑定到我们的IJob实现类
                IJobDetail job = JobBuilder.Create(_ijob)
                                 .SetJobData(new JobDataMap(DataDir))
                                 .WithDescription(entity.Description)
                                 .WithIdentity(entity.JobName, entity.JobGroup)
                                 .Build();
                // 创建触发器
                ITrigger trigger;

                entity.TriggerType = TriggerTypeEnum.Cron;

                //校验是否正确的执行周期表达式
                if (entity.TriggerType == TriggerTypeEnum.Cron)//CronExpression.IsValidExpression(entity.Cron))
                {
                    trigger = CreateCronTrigger(entity);
                }
                else
                {
                    trigger = CreateSimpleTrigger(entity);
                }

                // 告诉Quartz使用我们的触发器来安排作业
                await Scheduler.ScheduleJob(job, trigger);

                result.MsgCode = 1;
                result.Msg     = "添加成功";
            }
            catch (Exception ex)
            {
                result.MsgCode = 3;
                result.Msg     = ex.Message;
            }
            return(result);
        }
Beispiel #32
0
 public override void JobDeleted(JobKey jobKey)
 {
 }
Beispiel #33
0
 /// <summary>
 /// Calls the equivalent method on the 'proxied' <see cref="QuartzScheduler" />.
 /// </summary>
 public virtual Task <bool> CheckExists(JobKey jobKey)
 {
     return(CallInGuard(x => x.CheckExists(jobKey)));
 }
Beispiel #34
0
 /// <summary>
 /// Pause the <see cref="T:Quartz.IJobDetail"/> with the given
 ///             key - by pausing all of its current <see cref="T:Quartz.ITrigger"/>s.
 /// </summary>
 public void PauseJob(JobKey jobKey)
 {
     _scheduler.PauseJob(jobKey);
 }
Beispiel #35
0
 /// <summary>
 /// Trigger the identified <see cref="T:Quartz.IJobDetail"/>
 ///             (Execute it now).
 /// </summary>
 public void TriggerJob(JobKey jobKey)
 {
     _scheduler.TriggerJob(jobKey);
 }
Beispiel #36
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging(builder =>
            {
                builder.AddFile(opts => opts.LogDirectory = LogFolderPath);
            });

            services.AddOptions();
            services.AddHealthChecks().AddCheck <DasBlogHealthChecks>("health_check");
            services.AddMemoryCache();

            services.Configure <TimeZoneProviderOptions>(Configuration);
            services.Configure <SiteConfig>(Configuration);
            services.Configure <MetaTags>(Configuration);
            services.AddSingleton <AppVersionInfo>();

            services.Configure <ConfigFilePathsDataOption>(options =>
            {
                options.SiteConfigFilePath     = Path.Combine(hostingEnvironment.ContentRootPath, SiteConfigPath);
                options.MetaConfigFilePath     = Path.Combine(hostingEnvironment.ContentRootPath, MetaConfigPath);
                options.SecurityConfigFilePath = Path.Combine(hostingEnvironment.ContentRootPath, SiteSecurityConfigPath);
                options.IISUrlRewriteFilePath  = Path.Combine(hostingEnvironment.ContentRootPath, IISUrlRewriteConfigPath);
                options.ThemesFolder           = ThemeFolderPath;
                options.BinaryFolder           = BinariesPath;
                options.BinaryUrlRelative      = string.Format("{0}/", BinariesUrlRelativePath);
            });

            services.Configure <ActivityRepoOptions>(options
                                                     => options.Path = LogFolderPath);

            //Important if you're using Azure, hosting on Nginx, or behind any reverse proxy
            services.Configure <ForwardedHeadersOptions>(options =>
            {
                options.ForwardedHeaders = ForwardedHeaders.All;
                options.AllowedHosts     = Configuration.GetValue <string>("AllowedHosts")?.Split(';').ToList <string>();
            });

            // Add identity types
            services
            .AddIdentity <DasBlogUser, DasBlogRole>()
            .AddDefaultTokenProviders();

            services.Configure <IdentityOptions>(options =>
            {
                // Password settings
                options.Password.RequireDigit           = true;
                options.Password.RequiredLength         = 8;
                options.Password.RequireNonAlphanumeric = false;
                options.Password.RequireUppercase       = true;
                options.Password.RequireLowercase       = false;
                options.Password.RequiredUniqueChars    = 6;

                // Lockout settings
                options.Lockout.DefaultLockoutTimeSpan  = TimeSpan.FromMinutes(30);
                options.Lockout.MaxFailedAccessAttempts = 10;
                options.Lockout.AllowedForNewUsers      = true;

                // User settings
                options.User.RequireUniqueEmail = true;
            });

            services.ConfigureApplicationCookie(options =>
            {
                options.LoginPath         = "/account/login";         // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
                options.LogoutPath        = "/account/logout";        // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
                options.AccessDeniedPath  = "/account/accessdenied";  // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
                options.SlidingExpiration = true;
                options.ExpireTimeSpan    = TimeSpan.FromSeconds(10000);
                options.Cookie            = new CookieBuilder
                {
                    HttpOnly = true
                };
            });

            services.AddResponseCaching();

            services.Configure <RazorViewEngineOptions>(rveo =>
            {
                rveo.ViewLocationExpanders.Add(new DasBlogLocationExpander(Configuration.GetSection("Theme").Value));
            });

            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromSeconds(1000);
            });

            services
            .AddHttpContextAccessor();

            services
            .AddTransient <IDasBlogSettings, DasBlogSettings>()
            .AddTransient <IUserStore <DasBlogUser>, DasBlogUserStore>()
            .AddTransient <IRoleStore <DasBlogRole>, DasBlogUserRoleStore>()
            .AddTransient <IPrincipal>(provider => provider.GetService <IHttpContextAccessor>().HttpContext.User)
            .AddTransient <ISiteRepairer, SiteRepairer>();

            services.AddScoped <IRichEditBuilder>(SelectRichEditor)
            .AddScoped <IBlogPostViewModelCreator, BlogPostViewModelCreator>();

            services
            .AddSingleton(hostingEnvironment.ContentRootFileProvider)
            .AddSingleton <IBlogManager, BlogManager>()
            .AddSingleton <IArchiveManager, ArchiveManager>()
            .AddSingleton <ICategoryManager, CategoryManager>()
            .AddSingleton <ISiteSecurityManager, SiteSecurityManager>()
            .AddSingleton <IXmlRpcManager, XmlRpcManager>()
            .AddSingleton <ISiteManager, SiteManager>()
            .AddSingleton <IHttpContextAccessor, HttpContextAccessor>()
            .AddSingleton <IFileSystemBinaryManager, FileSystemBinaryManager>()
            .AddSingleton <IUserDataRepo, UserDataRepo>()
            .AddSingleton <ISiteSecurityConfig, SiteSecurityConfig>()
            .AddSingleton <IUserService, UserService>()
            .AddSingleton <IActivityService, ActivityService>()
            .AddSingleton <IActivityRepoFactory, ActivityRepoFactory>()
            .AddSingleton <IEventLineParser, EventLineParser>()
            .AddSingleton <ITimeZoneProvider, TimeZoneProvider>()
            .AddSingleton <ISubscriptionManager, SubscriptionManager>()
            .AddSingleton <IConfigFileService <MetaTags>, MetaConfigFileService>()
            .AddSingleton <IConfigFileService <SiteConfig>, SiteConfigFileService>()
            .AddSingleton <IConfigFileService <SiteSecurityConfigData>, SiteSecurityConfigFileService>();

            services
            .AddAutoMapper((serviceProvider, mapperConfig) =>
            {
                mapperConfig.AddProfile(new ProfilePost(serviceProvider.GetService <IDasBlogSettings>()));
                mapperConfig.AddProfile(new ProfileDasBlogUser(serviceProvider.GetService <ISiteSecurityManager>()));
                mapperConfig.AddProfile(new ProfileSettings());
            })
            .AddMvc()
            .AddXmlSerializerFormatters();

            services
            .AddControllersWithViews()
            .AddRazorRuntimeCompilation();

            services.AddRecaptcha(options =>
            {
                options.SiteKey   = RecaptchaSiteKey;
                options.SecretKey = RecaptchaSecretKey;
            });

            services.Configure <CookiePolicyOptions>(options =>
            {
                bool.TryParse(Configuration.GetSection("CookieConsentEnabled").Value, out var flag);

                options.CheckConsentNeeded    = context => flag;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddQuartz(q =>
            {
                q.SchedulerId = "Scheduler-Core";

                q.UseMicrosoftDependencyInjectionJobFactory(options =>
                {
                    // if we don't have the job in DI, allow fallback to configure via default constructor
                    options.AllowDefaultConstructor = true;
                });

                q.UseSimpleTypeLoader();
                q.UseInMemoryStore();
                q.UseDefaultThreadPool(tp =>
                {
                    tp.MaxConcurrency = 10;
                });

                var jobKey = new JobKey("key1", "main-group");

                q.AddJob <SiteEmailReport>(j => j
                                           .StoreDurably()
                                           .WithIdentity(jobKey)
                                           .WithDescription("Site report job")
                                           );

                q.AddTrigger(t => t
                             .WithIdentity("Simple Trigger")
                             .ForJob(jobKey)
                             .StartNow()
                             .WithSchedule(CronScheduleBuilder.DailyAtHourAndMinute(23, 45))
                             .WithDescription("my awesome simple trigger")

                             );
            });

            services.AddQuartzServer(options =>
            {
                options.WaitForJobsToComplete = true;
            });
        }
Beispiel #37
0
 /// <summary>
 /// Get all <see cref="T:Quartz.ITrigger"/> s that are associated with the
 ///             identified <see cref="T:Quartz.IJobDetail"/>.
 /// </summary>
 /// <remarks>
 /// The returned Trigger objects will be snap-shots of the actual stored
 ///             triggers.  If you wish to modify a trigger, you must re-store the
 ///             trigger afterward (e.g. see <see cref="M:Quartz.IScheduler.RescheduleJob(Quartz.TriggerKey,Quartz.ITrigger)"/>).
 /// </remarks>
 public IList <ITrigger> GetTriggersOfJob(JobKey jobKey)
 {
     return(_scheduler.GetTriggersOfJob(jobKey));
 }
Beispiel #38
0
        /// <summary>
        /// 立即执行
        /// </summary>
        /// <param name="jobKey"></param>
        /// <returns></returns>
        public async Task <bool> TriggerJobAsync(JobKey jobKey)
        {
            await Scheduler.TriggerJob(jobKey);

            return(true);
        }
Beispiel #39
0
 public Task JobDeleted(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Task.WhenAll(listeners.Select(l => l.JobDeleted(jobKey, cancellationToken))));
 }
Beispiel #40
0
        /// <summary>
        /// 获取job日志
        /// </summary>
        /// <param name="jobKey"></param>
        /// <returns></returns>
        public async Task <List <string> > GetJobLogsAsync(JobKey jobKey)
        {
            var jobDetail = await Scheduler.GetJobDetail(jobKey);

            return(jobDetail.JobDataMap[Constant.LOGLIST] as List <string>);
        }
        /// <summary>
        /// 添加一个计划任务(映射程序集指定IJob实现类)
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tasksQz"></param>
        /// <returns></returns>
        public async Task <MessageModel <string> > AddScheduleJobAsync(TasksQz tasksQz)
        {
            var result = new MessageModel <string>();

            if (tasksQz != null)
            {
                try
                {
                    JobKey jobKey = new JobKey(tasksQz.Id.ToString(), tasksQz.JobGroup);
                    if (await _scheduler.Result.CheckExists(jobKey))
                    {
                        result.success = false;
                        result.msg     = $"该任务计划已经在执行:【{tasksQz.Name}】,请勿重复启动!";
                        return(result);
                    }
                    #region 设置开始时间和结束时间

                    if (tasksQz.BeginTime == null)
                    {
                        tasksQz.BeginTime = DateTime.Now;
                    }
                    DateTimeOffset starRunTime = DateBuilder.NextGivenSecondDate(tasksQz.BeginTime, 1);//设置开始时间
                    if (tasksQz.EndTime == null)
                    {
                        tasksQz.EndTime = DateTime.MaxValue.AddDays(-1);
                    }
                    DateTimeOffset endRunTime = DateBuilder.NextGivenSecondDate(tasksQz.EndTime, 1);//设置暂停时间

                    #endregion

                    #region 通过反射获取程序集类型和类

                    Assembly assembly = Assembly.Load(new AssemblyName(tasksQz.AssemblyName));
                    Type     jobType  = assembly.GetType(tasksQz.AssemblyName + "." + tasksQz.ClassName);

                    #endregion
                    //判断任务调度是否开启
                    if (!_scheduler.Result.IsStarted)
                    {
                        await StartScheduleAsync();
                    }

                    //传入反射出来的执行程序集
                    IJobDetail job = new JobDetailImpl(tasksQz.Id.ToString(), tasksQz.JobGroup, jobType);
                    job.JobDataMap.Add("JobParam", tasksQz.JobParams);
                    ITrigger trigger;

                    #region 泛型传递
                    //IJobDetail job = JobBuilder.Create<T>()
                    //    .WithIdentity(sysSchedule.Name, sysSchedule.JobGroup)
                    //    .Build();
                    #endregion

                    if (tasksQz.Cron != null && CronExpression.IsValidExpression(tasksQz.Cron) && tasksQz.TriggerType > 0)
                    {
                        trigger = CreateCronTrigger(tasksQz);

                        ((CronTriggerImpl)trigger).MisfireInstruction = MisfireInstruction.CronTrigger.DoNothing;
                    }
                    else
                    {
                        trigger = CreateSimpleTrigger(tasksQz);
                    }

                    // 告诉Quartz使用我们的触发器来安排作业
                    await _scheduler.Result.ScheduleJob(job, trigger);

                    //await Task.Delay(TimeSpan.FromSeconds(120));
                    //await Console.Out.WriteLineAsync("关闭了调度器!");
                    //await _scheduler.Result.Shutdown();
                    result.success = true;
                    result.msg     = $"启动任务:【{tasksQz.Name}】成功";
                    return(result);
                }
                catch (Exception ex)
                {
                    result.success = false;
                    result.msg     = $"任务计划异常:【{ex.Message}】";
                    return(result);
                }
            }
            else
            {
                result.success = false;
                result.msg     = $"任务计划不存在:【{tasksQz?.Name}】";
                return(result);
            }
        }
        /// <summary>
        /// 添加任务
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="start">是否立即启动</param>
        /// <returns></returns>
        private async Task <IResultModel> AddJob(TaskEntity entity, bool start = false)
        {
            var jobClassType = Type.GetType(entity.ClassName);

            if (jobClassType == null)
            {
                return(ResultModel.Failed($"任务类({entity.ClassName})不存在"));
            }

            var jobKey = new JobKey(entity.TaskCode, entity.Group);
            var job    = JobBuilder.Create(jobClassType).WithIdentity(jobKey)
                         .UsingJobData("id", entity.Id.ToString()).Build();

            var triggerBuilder = TriggerBuilder.Create().WithIdentity(entity.TaskCode, entity.Group)
                                 .EndAt(entity.EndDate.ToUniversalTime())
                                 .WithDescription(entity.TaskName);

            //如果开始日期小于等于当前日期则立即启动
            if (entity.BeginDate <= DateTime.Now)
            {
                triggerBuilder.StartNow();
            }
            else
            {
                triggerBuilder.StartAt(entity.BeginDate.ToUniversalTime());
            }

            if (entity.TriggerType == 1)
            {
                //简单任务
                triggerBuilder.WithSimpleSchedule(builder =>
                {
                    builder.WithIntervalInSeconds(entity.IntervalInSeconds);
                    if (entity.RepeatCount > 0)
                    {
                        builder.WithRepeatCount(entity.RepeatCount - 1);
                    }
                    else
                    {
                        builder.RepeatForever();
                    }
                });
            }
            else
            {
                if (!CronExpression.IsValidExpression(entity.Cron))
                {
                    return(ResultModel.Failed("CRON表达式无效"));
                }

                //CRON任务
                triggerBuilder.WithCronSchedule(entity.Cron);
            }

            var trigger = triggerBuilder.Build();

            try
            {
                await _quartzServer.AddJob(job, trigger);

                if (!start)
                {
                    //先暂停
                    await _quartzServer.PauseJob(jobKey);
                }

                return(ResultModel.Success());
            }
            catch (Exception ex)
            {
                _logger.LogError("任务调度添加任务失败{@ex}", ex);
            }

            return(ResultModel.Failed());
        }
Beispiel #43
0
 /// <summary>
 /// Request the interruption, within this Scheduler instance, of all
 ///             currently executing instances of the identified <see cref="T:Quartz.IJob"/>, which
 ///             must be an implementor of the <see cref="T:Quartz.IInterruptableJob"/> interface.
 /// </summary>
 /// <remarks>
 /// <para>
 /// If more than one instance of the identified job is currently executing,
 ///             the <see cref="M:Quartz.IInterruptableJob.Interrupt"/> method will be called on
 ///             each instance.  However, there is a limitation that in the case that
 ///             <see cref="M:Quartz.IScheduler.Interrupt(Quartz.JobKey)"/> on one instances throws an exception, all
 ///             remaining  instances (that have not yet been interrupted) will not have
 ///             their <see cref="M:Quartz.IScheduler.Interrupt(Quartz.JobKey)"/> method called.
 /// </para>
 /// <para>
 /// If you wish to interrupt a specific instance of a job (when more than
 ///             one is executing) you can do so by calling
 ///             <see cref="M:Quartz.IScheduler.GetCurrentlyExecutingJobs"/> to obtain a handle
 ///             to the job instance, and then invoke <see cref="M:Quartz.IScheduler.Interrupt(Quartz.JobKey)"/> on it
 ///             yourself.
 /// </para>
 /// <para>
 /// This method is not cluster aware.  That is, it will only interrupt
 ///             instances of the identified InterruptableJob currently executing in this
 ///             Scheduler instance, not across the entire cluster.
 /// </para>
 /// </remarks>
 /// <returns>
 /// true is at least one instance of the identified job was found and interrupted.
 /// </returns>
 /// <seealso cref="T:Quartz.IInterruptableJob"/><seealso cref="M:Quartz.IScheduler.GetCurrentlyExecutingJobs"/>
 public bool Interrupt(JobKey jobKey)
 {
     return(_scheduler.Interrupt(jobKey));
 }
Beispiel #44
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddLogging(loggingBuilder =>
            {
                loggingBuilder.ClearProviders();
                loggingBuilder.AddSerilog(dispose: true);
            });

            services.AddRazorPages();

            // base configuration for DI
            services.AddQuartz(q =>
            {
                // handy when part of cluster or you want to otherwise identify multiple schedulers
                q.SchedulerId = "Scheduler-Core";

                // we take this from appsettings.json, just show it's possible
                // q.SchedulerName = "Quartz ASP.NET Core Sample Scheduler";

                // hooks LibLog to Microsoft logging without allowing it to detect concrete implementation
                // if you are using NLog, SeriLog or log4net you shouldn't need this
                // LibLog will be removed in Quartz 4 and Microsoft Logging will become the default
                q.UseMicrosoftLogging();

                // we could leave DI configuration intact and then jobs need to have public no-arg constructor

                // the MS DI is expected to produce transient job instances
                q.UseMicrosoftDependencyInjectionJobFactory(options =>
                {
                    // if we don't have the job in DI, allow fallback to configure via default constructor
                    options.AllowDefaultConstructor = true;
                });

                // or
                // q.UseMicrosoftDependencyInjectionScopedJobFactory();

                // these are the defaults
                q.UseSimpleTypeLoader();
                q.UseInMemoryStore();
                q.UseDefaultThreadPool(tp =>
                {
                    tp.ThreadCount = 10;
                });

                // configure jobs with code
                var jobKey = new JobKey("awesome job", "awesome group");
                q.AddJob <ExampleJob>(j => j
                                      .StoreDurably()
                                      .WithIdentity(jobKey)
                                      .WithDescription("my awesome job")
                                      );

                q.AddTrigger(t => t
                             .WithIdentity("Simple Trigger")
                             .ForJob(jobKey)
                             .StartNow()
                             .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(10)).RepeatForever())
                             .WithDescription("my awesome simple trigger")
                             );

                q.AddTrigger(t => t
                             .WithIdentity("Cron Trigger")
                             .ForJob(jobKey)
                             .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3)))
                             .WithCronSchedule("0/3 * * * * ?")
                             .WithDescription("my awesome cron trigger")
                             );

                q.AddTrigger(t => t
                             .WithIdentity("Daily Trigger")
                             .ForJob(jobKey)
                             .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
                             .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
                             .WithDescription("my awesome daily time interval trigger")
                             );

                // also add XML configuration and poll it for changes
                q.UseXmlSchedulingConfiguration(x =>
                {
                    x.Files                 = new[] { "~/quartz_jobs.config" };
                    x.ScanInterval          = TimeSpan.FromSeconds(2);
                    x.FailOnFileNotFound    = true;
                    x.FailOnSchedulingError = true;
                });

                // convert time zones using converter that can handle Windows/Linux differences
                q.UseTimeZoneConverter();

                // add some listeners
                q.AddSchedulerListener <SampleSchedulerListener>();
                q.AddJobListener <SampleJobListener>(GroupMatcher <JobKey> .GroupEquals(jobKey.Group));
                q.AddTriggerListener <SampleTriggerListener>();

                // example of persistent job store using JSON serializer as an example

                /*
                 * q.UsePersistentStore(s =>
                 * {
                 *  s.UseProperties = true;
                 *  s.RetryInterval = TimeSpan.FromSeconds(15);
                 *  s.UseSqlServer(sqlServer =>
                 *  {
                 *      sqlServer.ConnectionString = "some connection string";
                 *      // this is the default
                 *      sqlServer.TablePrefix = "QRTZ_";
                 *  });
                 *  s.UseJsonSerializer();
                 *  s.UseClustering(c =>
                 *  {
                 *      c.CheckinMisfireThreshold = TimeSpan.FromSeconds(20);
                 *      c.CheckinInterval = TimeSpan.FromSeconds(10);
                 *  });
                 * });
                 */
            });

            // ASP.NET Core hosting
            services.AddQuartzServer(options =>
            {
                // when shutting down we want jobs to complete gracefully
                options.WaitForJobsToComplete = true;
            });

            services
            .AddHealthChecksUI()
            .AddInMemoryStorage();
        }
Beispiel #45
0
 /// <summary>
 /// Get the <see cref="T:Quartz.IJobDetail"/> for the <see cref="T:Quartz.IJob"/>
 ///             instance with the given key .
 /// </summary>
 /// <remarks>
 /// The returned JobDetail object will be a snap-shot of the actual stored
 ///             JobDetail.  If you wish to modify the JobDetail, you must re-store the
 ///             JobDetail afterward (e.g. see <see cref="M:Quartz.IScheduler.AddJob(Quartz.IJobDetail,System.Boolean)"/>).
 /// </remarks>
 public IJobDetail GetJobDetail(JobKey jobKey)
 {
     return(_scheduler.GetJobDetail(jobKey));
 }
Beispiel #46
0
 public async Task <ResultValue> JobDelete([FromBody] JobKey job)
 {
     return(await scheduler.StopOrDelScheduleJobAsync(job.Group, job.Name, true));
 }
Beispiel #47
0
 /// <summary>
 /// Resume (un-pause) the <see cref="T:Quartz.IJobDetail"/> with
 ///             the given key.
 /// </summary>
 /// <remarks>
 /// If any of the <see cref="T:Quartz.IJob"/>'s<see cref="T:Quartz.ITrigger"/> s missed one
 ///             or more fire-times, then the <see cref="T:Quartz.ITrigger"/>'s misfire
 ///             instruction will be applied.
 /// </remarks>
 public void ResumeJob(JobKey jobKey)
 {
     _scheduler.ResumeJob(jobKey);
 }
Beispiel #48
0
 public async Task <ResultValue> ResumeJob([FromBody] JobKey job)
 {
     return(await scheduler.ResumeJobAsync(job.Group, job.Name));
 }
Beispiel #49
0
 /// <summary>
 /// Trigger the identified <see cref="T:Quartz.IJobDetail"/> (Execute it now).
 /// </summary>
 /// <param name="data">the (possibly <see langword="null"/>) JobDataMap to be
 ///             associated with the trigger that fires the job immediately.
 ///             </param><param name="jobKey">The <see cref="T:Quartz.JobKey"/> of the <see cref="T:Quartz.IJob"/> to be executed.
 ///             </param>
 public void TriggerJob(JobKey jobKey, JobDataMap data)
 {
     _scheduler.TriggerJob(jobKey, data);
 }
Beispiel #50
0
        public async Task <bool> TriggerJob([FromBody] JobKey job)
        {
            await scheduler.TriggerJobAsync(job);

            return(true);
        }
Beispiel #51
0
 /// <summary>
 /// Delete the identified <see cref="T:Quartz.IJob"/> from the Scheduler - and any
 ///             associated <see cref="T:Quartz.ITrigger"/>s.
 /// </summary>
 /// <returns>
 /// true if the Job was found and deleted.
 /// </returns>
 public bool DeleteJob(JobKey jobKey)
 {
     return(_scheduler.DeleteJob(jobKey));
 }
 public Task JobResumed(JobKey jobKey, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Task.Run(() => LogsAppendersManager.Instance.Debug(this.GetType(), MethodBase.GetCurrentMethod(), jobKey.Name)));
 }
        public void Test(IScheduler scheduler, bool clearJobs, bool scheduleJobs)
        {
            try
            {
                if (clearJobs)
                {
                    scheduler.Clear();
                }

                if (scheduleJobs)
                {
                    ICalendar cronCalendar    = new CronCalendar("0/5 * * * * ?");
                    ICalendar holidayCalendar = new HolidayCalendar();

                    // QRTZNET-86
                    ITrigger t = scheduler.GetTrigger(new TriggerKey("NonExistingTrigger", "NonExistingGroup"));
                    Assert.IsNull(t);

                    AnnualCalendar cal = new AnnualCalendar();
                    scheduler.AddCalendar("annualCalendar", cal, false, true);

                    IOperableTrigger calendarsTrigger = new SimpleTriggerImpl("calendarsTrigger", "test", 20, TimeSpan.FromMilliseconds(5));
                    calendarsTrigger.CalendarName = "annualCalendar";

                    JobDetailImpl jd = new JobDetailImpl("testJob", "test", typeof(NoOpJob));
                    scheduler.ScheduleJob(jd, calendarsTrigger);

                    // QRTZNET-93
                    scheduler.AddCalendar("annualCalendar", cal, true, true);

                    scheduler.AddCalendar("baseCalendar", new BaseCalendar(), false, true);
                    scheduler.AddCalendar("cronCalendar", cronCalendar, false, true);
                    scheduler.AddCalendar("dailyCalendar", new DailyCalendar(DateTime.Now.Date, DateTime.Now.AddMinutes(1)), false, true);
                    scheduler.AddCalendar("holidayCalendar", holidayCalendar, false, true);
                    scheduler.AddCalendar("monthlyCalendar", new MonthlyCalendar(), false, true);
                    scheduler.AddCalendar("weeklyCalendar", new WeeklyCalendar(), false, true);

                    scheduler.AddCalendar("cronCalendar", cronCalendar, true, true);
                    scheduler.AddCalendar("holidayCalendar", holidayCalendar, true, true);

                    Assert.IsNotNull(scheduler.GetCalendar("annualCalendar"));

                    JobDetailImpl lonelyJob = new JobDetailImpl("lonelyJob", "lonelyGroup", typeof(SimpleRecoveryJob));
                    lonelyJob.Durable          = true;
                    lonelyJob.RequestsRecovery = true;
                    scheduler.AddJob(lonelyJob, false);
                    scheduler.AddJob(lonelyJob, true);

                    string schedId = scheduler.SchedulerInstanceId;

                    int count = 1;

                    JobDetailImpl job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));

                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = true;
                    IOperableTrigger trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5));
                    trigger.JobDataMap.Add("key", "value");
                    trigger.EndTimeUtc = DateTime.UtcNow.AddYears(10);

                    trigger.StartTimeUtc = DateTime.Now.AddMilliseconds(1000L);
                    scheduler.ScheduleJob(job, trigger);

                    // check that trigger was stored
                    ITrigger persisted = scheduler.GetTrigger(new TriggerKey("trig_" + count, schedId));
                    Assert.IsNotNull(persisted);
                    Assert.IsTrue(persisted is SimpleTriggerImpl);

                    count++;
                    job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));
                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = (true);
                    trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(5));

                    trigger.StartTimeUtc = (DateTime.Now.AddMilliseconds(2000L));
                    scheduler.ScheduleJob(job, trigger);

                    count++;
                    job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryStatefulJob));
                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = (true);
                    trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(3));

                    trigger.StartTimeUtc = (DateTime.Now.AddMilliseconds(1000L));
                    scheduler.ScheduleJob(job, trigger);

                    count++;
                    job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));
                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = (true);
                    trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromSeconds(4));

                    trigger.StartTimeUtc = (DateTime.Now.AddMilliseconds(1000L));
                    scheduler.ScheduleJob(job, trigger);

                    count++;
                    job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));
                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = (true);
                    trigger = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500));
                    scheduler.ScheduleJob(job, trigger);

                    count++;
                    job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));
                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = (true);
                    IOperableTrigger ct = new CronTriggerImpl("cron_trig_" + count, schedId, "0/10 * * * * ?");
                    ct.JobDataMap.Add("key", "value");
                    ct.StartTimeUtc = DateTime.Now.AddMilliseconds(1000);

                    scheduler.ScheduleJob(job, ct);

                    count++;
                    job = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));
                    // ask scheduler to re-Execute this job if it was in progress when
                    // the scheduler went down...
                    job.RequestsRecovery = (true);

                    var timeZone1 = TimeZoneUtil.FindTimeZoneById("Central European Standard Time");
                    var timeZone2 = TimeZoneUtil.FindTimeZoneById("Mountain Standard Time");

                    DailyTimeIntervalTriggerImpl nt = new DailyTimeIntervalTriggerImpl("nth_trig_" + count, schedId, new TimeOfDay(1, 1, 1), new TimeOfDay(23, 30, 0), IntervalUnit.Hour, 1);
                    nt.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000);
                    nt.TimeZone     = timeZone1;

                    scheduler.ScheduleJob(job, nt);

                    var loadedNt = (IDailyTimeIntervalTrigger)scheduler.GetTrigger(nt.Key);
                    Assert.That(loadedNt.TimeZone.Id, Is.EqualTo(timeZone1.Id));

                    nt.TimeZone = timeZone2;
                    scheduler.RescheduleJob(nt.Key, nt);

                    loadedNt = (IDailyTimeIntervalTrigger)scheduler.GetTrigger(nt.Key);
                    Assert.That(loadedNt.TimeZone.Id, Is.EqualTo(timeZone2.Id));

                    DailyTimeIntervalTriggerImpl nt2 = new DailyTimeIntervalTriggerImpl();
                    nt2.Key          = new TriggerKey("nth_trig2_" + count, schedId);
                    nt2.StartTimeUtc = DateTime.Now.Date.AddMilliseconds(1000);
                    nt2.JobKey       = job.Key;
                    scheduler.ScheduleJob(nt2);

                    // GitHub issue #92
                    scheduler.GetTrigger(nt2.Key);

                    // GitHub issue #98
                    nt2.StartTimeOfDay = new TimeOfDay(1, 2, 3);
                    nt2.EndTimeOfDay   = new TimeOfDay(2, 3, 4);

                    scheduler.UnscheduleJob(nt2.Key);
                    scheduler.ScheduleJob(nt2);

                    var triggerFromDb = (IDailyTimeIntervalTrigger)scheduler.GetTrigger(nt2.Key);
                    Assert.That(triggerFromDb.StartTimeOfDay.Hour, Is.EqualTo(1));
                    Assert.That(triggerFromDb.StartTimeOfDay.Minute, Is.EqualTo(2));
                    Assert.That(triggerFromDb.StartTimeOfDay.Second, Is.EqualTo(3));

                    Assert.That(triggerFromDb.EndTimeOfDay.Hour, Is.EqualTo(2));
                    Assert.That(triggerFromDb.EndTimeOfDay.Minute, Is.EqualTo(3));
                    Assert.That(triggerFromDb.EndTimeOfDay.Second, Is.EqualTo(4));

                    job.RequestsRecovery = (true);
                    CalendarIntervalTriggerImpl intervalTrigger = new CalendarIntervalTriggerImpl(
                        "calint_trig_" + count,
                        schedId,
                        DateTime.UtcNow.AddMilliseconds(300),
                        DateTime.UtcNow.AddMinutes(1),
                        IntervalUnit.Second,
                        8);
                    intervalTrigger.JobKey = job.Key;

                    scheduler.ScheduleJob(intervalTrigger);

                    // custom time zone
                    const string CustomTimeZoneId = "Custom TimeZone";
                    var          webTimezone      = TimeZoneInfo.CreateCustomTimeZone(
                        CustomTimeZoneId,
                        TimeSpan.FromMinutes(22),
                        null,
                        null);

                    TimeZoneUtil.CustomResolver = id =>
                    {
                        if (id == CustomTimeZoneId)
                        {
                            return(webTimezone);
                        }
                        return(null);
                    };

                    var customTimeZoneTrigger = TriggerBuilder.Create()
                                                .WithIdentity("customTimeZoneTrigger")
                                                .WithCronSchedule("0/5 * * * * ?", x => x.InTimeZone(webTimezone))
                                                .StartNow()
                                                .ForJob(job)
                                                .Build();

                    scheduler.ScheduleJob(customTimeZoneTrigger);
                    var loadedCustomTimeZoneTrigger = (ICronTrigger)scheduler.GetTrigger(customTimeZoneTrigger.Key);
                    Assert.That(loadedCustomTimeZoneTrigger.TimeZone.BaseUtcOffset, Is.EqualTo(TimeSpan.FromMinutes(22)));

                    // bulk operations
                    var        info     = new Dictionary <IJobDetail, Collection.ISet <ITrigger> >();
                    IJobDetail detail   = new JobDetailImpl("job_" + count, schedId, typeof(SimpleRecoveryJob));
                    ITrigger   simple   = new SimpleTriggerImpl("trig_" + count, schedId, 20, TimeSpan.FromMilliseconds(4500));
                    var        triggers = new Collection.HashSet <ITrigger>();
                    triggers.Add(simple);
                    info[detail] = triggers;

                    scheduler.ScheduleJobs(info, true);

                    Assert.IsTrue(scheduler.CheckExists(detail.Key));
                    Assert.IsTrue(scheduler.CheckExists(simple.Key));

                    // QRTZNET-243
                    scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupContains("a").DeepClone());
                    scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEndsWith("a").DeepClone());
                    scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith("a").DeepClone());
                    scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals("a").DeepClone());

                    scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupContains("a").DeepClone());
                    scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEndsWith("a").DeepClone());
                    scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupStartsWith("a").DeepClone());
                    scheduler.GetTriggerKeys(GroupMatcher <TriggerKey> .GroupEquals("a").DeepClone());

                    scheduler.Start();

                    Thread.Sleep(TimeSpan.FromSeconds(3));

                    scheduler.PauseAll();

                    scheduler.ResumeAll();

                    scheduler.PauseJob(new JobKey("job_1", schedId));

                    scheduler.ResumeJob(new JobKey("job_1", schedId));

                    scheduler.PauseJobs(GroupMatcher <JobKey> .GroupEquals(schedId));

                    Thread.Sleep(TimeSpan.FromSeconds(1));

                    scheduler.ResumeJobs(GroupMatcher <JobKey> .GroupEquals(schedId));

                    scheduler.PauseTrigger(new TriggerKey("trig_2", schedId));
                    scheduler.ResumeTrigger(new TriggerKey("trig_2", schedId));

                    scheduler.PauseTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId));

                    Assert.AreEqual(1, scheduler.GetPausedTriggerGroups().Count);

                    Thread.Sleep(TimeSpan.FromSeconds(3));
                    scheduler.ResumeTriggers(GroupMatcher <TriggerKey> .GroupEquals(schedId));

                    Assert.IsNotNull(scheduler.GetTrigger(new TriggerKey("trig_2", schedId)));
                    Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_1", schedId)));
                    Assert.IsNotNull(scheduler.GetMetaData());
                    Assert.IsNotNull(scheduler.GetCalendar("weeklyCalendar"));

                    var genericjobKey = new JobKey("genericJob", "genericGroup");
                    var genericJob    = JobBuilder.Create <GenericJobType <string> >()
                                        .WithIdentity(genericjobKey)
                                        .StoreDurably()
                                        .Build();

                    scheduler.AddJob(genericJob, false);

                    genericJob = scheduler.GetJobDetail(genericjobKey);
                    Assert.That(genericJob, Is.Not.Null);
                    scheduler.TriggerJob(genericjobKey);

                    Thread.Sleep(TimeSpan.FromSeconds(20));

                    Assert.That(GenericJobType <string> .TriggeredCount, Is.EqualTo(1));
                    scheduler.Standby();

                    CollectionAssert.IsNotEmpty(scheduler.GetCalendarNames());
                    CollectionAssert.IsNotEmpty(scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupEquals(schedId)));

                    CollectionAssert.IsNotEmpty(scheduler.GetTriggersOfJob(new JobKey("job_2", schedId)));
                    Assert.IsNotNull(scheduler.GetJobDetail(new JobKey("job_2", schedId)));

                    scheduler.DeleteCalendar("cronCalendar");
                    scheduler.DeleteCalendar("holidayCalendar");
                    scheduler.DeleteJob(new JobKey("lonelyJob", "lonelyGroup"));
                    scheduler.DeleteJob(job.Key);

                    scheduler.GetJobGroupNames();
                    scheduler.GetCalendarNames();
                    scheduler.GetTriggerGroupNames();

                    TestMatchers(scheduler);
                }
            }
            finally
            {
                scheduler.Shutdown(false);
            }
        }
Beispiel #54
0
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            #region Logging

            // make sure you configure logging and open telemetry before quartz services
            services.AddLogging(loggingBuilder =>
            {
                loggingBuilder.ClearProviders();
                loggingBuilder.AddSerilog(dispose: true);
            });

            services.AddRazorPages();

            #endregion Logging

            #region Quartz

            // base configuration for DI
            services.Configure <QuartzOptions>(Configuration.GetSection("Quartz"));
            services.AddQuartz(q =>
            {
                // handy when part of cluster or you want to otherwise identify multiple schedulers
                q.SchedulerId = "Scheduler-Core";

                #region DI Job Factory

                // this is default configuration if you don't alter it
                q.UseMicrosoftDependencyInjectionJobFactory(options =>
                {
                    // if we don't have the job in DI, allow fallback to configure via default constructor
                    options.AllowDefaultConstructor = true;

                    // set to true if you want to inject scoped services like Entity Framework's DbContext
                    options.CreateScope = false;
                });

                #endregion DI Job Factory

                #region Default Config -- For InMemory Store -- Comment if uses Persist Store -- Commented

                // these are the defaults
                //q.UseSimpleTypeLoader();
                //q.UseInMemoryStore();
                //q.UseDefaultThreadPool(tp =>
                //{
                //    tp.MaxConcurrency = 10;
                //});

                #endregion Default Config -- For InMemory Store -- Comment if uses Persist Store -- Commented

                #region Simple Trigger

                //// Create a job with Single Trigger
                //q.ScheduleJob<FirstSample>(trigger => trigger
                //    .WithIdentity("SomeTrigger")
                //    .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
                //    .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
                //    .WithDescription("Say somethign Trigger configured for a SaySomethingJob with single call")
                //    );

                #endregion Simple Trigger

                #region Configure Individual Jobs And Trigger -- Commented

                // you can also configure individual jobs and triggers with code
                // this allows you to associated multiple triggers with same job
                // (if you want to have different job data map per trigger for example)
                //q.AddJob<ExampleJob>(j => j
                //    .StoreDurably() // we need to store durably if no trigger is associated
                //    .WithDescription("my awesome job")
                //);

                #endregion Configure Individual Jobs And Trigger -- Commented

                #region Second Sample Job with SampleTrigger and CronTrigger

                var secondSampleJobKey = new JobKey("Second Sample Job", "Sample Job Group");
                q.AddJob <SecondSample>(secondSampleJobKey, j => j.WithDescription("My Second Sample Job"));

                // Sample Trigger for Second Sample Job
                q.AddTrigger(trigger => trigger
                             .WithIdentity("SecondSample Sample Trigger")
                             .ForJob(secondSampleJobKey)
                             .StartNow()
                             .WithSimpleSchedule(x => x.WithInterval(TimeSpan.FromSeconds(7)).RepeatForever())
                             .WithDescription("My Second Sample Trigger")
                             );

                // Cron Trigger for Second Sample Job
                q.AddTrigger(trigger => trigger
                             .WithIdentity("My Second Sample Cron Trigger")
                             .ForJob(secondSampleJobKey)
                             .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3)))
                             .WithCronSchedule("0/17 * * * * ?")
                             .WithDescription("My Second Cron Trigger")
                             );

                #endregion Second Sample Job with SampleTrigger and CronTrigger

                #region TimeConverter

                q.UseTimeZoneConverter();

                #endregion TimeConverter

                #region Sample Listener

                // Add Second Sample Listener
                q.AddJobListener <SecondSampleJobListener>(GroupMatcher <JobKey> .GroupEquals(secondSampleJobKey.Group));
                q.AddTriggerListener <SecondSampleTriggerListener>();
                q.AddSchedulerListener <SecondSampleSchedulerListener>();

                #endregion Sample Listener

                #region Job Using Data

                var dataJobKey = new JobKey("AuthorInfo", "Using Data Group");
                q.AddJob <UsingDataJob>(options =>
                                        options.WithIdentity(dataJobKey)
                                        .UsingJobData("Name", "Nguyen Minh Van")
                                        .UsingJobData("Age", "24")
                                        .UsingJobData("Address", "District 12, Ho Chi Minh City")
                                        );

                q.AddTrigger(options =>
                             options.ForJob(dataJobKey)
                             .WithIdentity("DataJob-Trigger")
                             .WithCronSchedule("0/5 * * * * ?"));

                #endregion Job Using Data

                #region Calender

                //const string calendarName = "myHolidayCalendar";
                //q.AddCalendar<HolidayCalendar>(
                //    name: calendarName,
                //    replace: true,
                //    updateTriggers: true,
                //    x => x.AddExcludedDate(new DateTime(2020, 5, 15))
                //);

                //q.AddTrigger(t => t
                //    .WithIdentity("Daily Trigger")
                //    .ForJob(jobKey)
                //    .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(5)))
                //    .WithDailyTimeIntervalSchedule(x => x.WithInterval(10, IntervalUnit.Second))
                //    .WithDescription("my awesome daily time interval trigger")
                //    .ModifiedByCalendar(calendarName)
                //);

                // convert time zones using converter that can handle Windows/Linux differences
                //q.UseTimeZoneConverter();

                #endregion Calender
            });

            #endregion Quartz

            #region Quartz Options

            // we can use options pattern to support hooking your own configuration with Quartz's
            // because we don't use service registration api, we need to manally ensure the job is present in DI
            //services.AddTransient<ExampleJob>();

            //services.Configure<SampleOptions>(Configuration.GetSection("Sample"));
            //services.AddOptions<QuartzOptions>()
            //    .Configure<IOptions<SampleOptions>>((options, dep) =>
            //    {
            //        if (!string.IsNullOrWhiteSpace(dep.Value.CronSchedule))
            //        {
            //            var jobKey = new JobKey("options-custom-job", "custom");
            //            options.AddJob<ExampleJob>(j => j.WithIdentity(jobKey));
            //            options.AddTrigger(trigger => trigger
            //                .WithIdentity("options-custom-trigger", "custom")
            //                .ForJob(jobKey)
            //                .WithCronSchedule(dep.Value.CronSchedule));
            //        }
            //    });

            #endregion Quartz Options

            #region Quartz Server

            // ASP.NET Core hosting
            services.AddQuartzServer(options =>
            {
                // when shutting down we want jobs to complete gracefully
                options.WaitForJobsToComplete = true;
            });

            #endregion Quartz Server

            #region Other Services

            services
            .AddHealthChecksUI()
            .AddInMemoryStorage();

            #endregion Other Services
        }
Beispiel #55
0
 /// <summary>
 /// Calls the equivalent method on the 'proxied' <see cref="QuartzScheduler" />.
 /// </summary>
 public virtual Task <IJobDetail> GetJobDetail(JobKey jobKey)
 {
     return(CallInGuard(x => x.GetJobDetail(jobKey)));
 }
Beispiel #56
0
 /// <summary>
 /// Determine whether a <see cref="T:Quartz.IJob"/> with the given identifier already
 ///             exists within the scheduler.
 /// </summary>
 /// <param name="jobKey">the identifier to check for</param>
 /// <returns>
 /// true if a Job exists with the given identifier
 /// </returns>
 public bool CheckExists(JobKey jobKey)
 {
     return(_scheduler.CheckExists(jobKey));
 }
 public Task JobInterrupted(JobKey jobKey, CancellationToken cancellationToken = new CancellationToken())
 {
     return(Task.FromResult(true));
 }
Beispiel #58
0
        /// <summary>
        /// 触发新增、删除、修改、暂停、启用、立即执行事件
        /// </summary>
        /// <param name="schedulerFactory"></param>
        /// <param name="taskName"></param>
        /// <param name="groupName"></param>
        /// <param name="action"></param>
        /// <param name="taskOptions"></param>
        /// <returns></returns>
        public async Task TriggerAction(string taskName, string groupName, JobAction action, AddScheduleInput scheduleInput = null)
        {
            if (string.IsNullOrEmpty(taskName) || string.IsNullOrEmpty(groupName))
            {
                throw new BusinessException($"任务名或组名不能为空");
            }
            var scheduler  = _scheduler;
            var jobKey     = new JobKey(taskName, groupName);
            var triggerKey = new TriggerKey(taskName, groupName);

            if (!await scheduler.CheckExists(jobKey))
            {
                throw new BusinessException($"未发现任务");
            }
            if (!await scheduler.CheckExists(triggerKey))
            {
                throw new BusinessException($"未发现触发器");
            }

            switch (action)
            {
            case JobAction.除:
            case JobAction.修改:
                await scheduler.PauseTrigger(triggerKey);

                await scheduler.UnscheduleJob(triggerKey);    // 移除触发器

                await scheduler.DeleteJob(jobKey);

                if (action == JobAction.修改)
                {
                    await AddJobAsync(scheduleInput);

                    $">>>>{triggerKey}修改成功".WriteSuccessLine();
                }
                break;

            case JobAction.暂停:
                await scheduler.PauseTrigger(triggerKey);

                $">>>>{triggerKey}暂停".WriteSuccessLine();
                break;

            case JobAction.停止:
                await scheduler.Shutdown();

                $">>>>{triggerKey}停止".WriteSuccessLine();
                break;

            case JobAction.开启:
                await scheduler.ResumeTrigger(triggerKey);

                $">>>>{triggerKey}开启".WriteSuccessLine();
                break;

            case JobAction.立即执行:
                await scheduler.TriggerJob(jobKey);

                $">>>>{triggerKey}立即执行".WriteSuccessLine();
                break;
            }
        }
Beispiel #59
0
 /// <summary>
 /// Set the identity of the Job which should be fired by the produced
 /// Trigger, by extracting the JobKey from the given job.
 /// </summary>
 /// <remarks>
 /// </remarks>
 /// <param name="jobDetail">the Job to fire.</param>
 /// <returns>the updated TriggerBuilder</returns>
 /// <seealso cref="ITrigger.JobKey" />
 public TriggerBuilder ForJob(IJobDetail jobDetail)
 {
     JobKey k = jobDetail.Key;
     if (k.Name == null)
     {
         throw new ArgumentException("The given job has not yet had a name assigned to it.");
     }
     jobKey = k;
     return this;
 }
 public Task JobResumed(JobKey jobKey, CancellationToken cancellationToken)
 {
     return(Task.FromResult(true));
 }