示例#1
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);

                ServiceJob job = jobService.Get(JobId);
                if (job != null)
                {
                    try
                    {
                        // create a scheduler specific for the job
                        var scheduleConfig      = new System.Collections.Specialized.NameValueCollection();
                        var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40);
                        scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName);
                        var schedulerFactory = new StdSchedulerFactory(scheduleConfig);
                        var sched            = new StdSchedulerFactory(scheduleConfig).GetScheduler();
                        if (sched.IsStarted)
                        {
                            // the job is currently running as a RunNow job
                            return;
                        }

                        // create the quartz job and trigger
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        var        jobTrigger = TriggerBuilder.Create()
                                                .WithIdentity(job.Guid.ToString(), job.Name)
                                                .StartNow()
                                                .Build();

                        // schedule the job
                        sched.ScheduleJob(jobDetail, jobTrigger);

                        // set up the listener to report back from the job when it completes
                        sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                        // start the scheduler
                        sched.Start();

                        // Wait 10secs to give job chance to start
                        Thread.Sleep(new TimeSpan(0, 0, 10));

                        // stop the scheduler when done with job
                        sched.Shutdown(true);
                    }

                    catch (Exception ex)
                    {
                        // create a friendly error message
                        ExceptionLogService.LogException(ex, null);
                        string message = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";
                        rockContext.SaveChanges();
                    }
                }
            }
        }
示例#2
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);

                ServiceJob job = jobService.Get(JobId);
                if (job != null)
                {
                    try
                    {
                        // create a scheduler
                        var scheduleConfig = new System.Collections.Specialized.NameValueCollection();
                        scheduleConfig.Add("org.quartz.scheduler.instanceName", "RunNow");
                        var sched = new StdSchedulerFactory(scheduleConfig).GetScheduler();

                        // create the quartz job and trigger
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        var        jobTrigger = TriggerBuilder.Create()
                                                .WithIdentity(job.Guid.ToString(), job.Name)
                                                .StartNow()
                                                .Build();

                        // schedule the job
                        sched.ScheduleJob(jobDetail, jobTrigger);

                        // set up the listener to report back from the job when it completes
                        sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                        // start the scheduler
                        sched.Start();

                        // Wait 10secs to give job chance to start
                        Thread.Sleep(new TimeSpan(0, 0, 10));

                        // stop the scheduler when done with job
                        sched.Shutdown(true);
                    }

                    catch (Exception ex)
                    {
                        // create a friendly error message
                        string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the websites App_Code directory. \n\n\n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";
                        rockContext.SaveChanges();
                    }
                }
            }
        }
示例#3
0
        protected override void OnStart(string[] args)
        {
            ISchedulerFactory sf;

            // create scheduler
            sf    = new StdSchedulerFactory();
            sched = sf.GetScheduler();

            // get list of active jobs
            ServiceJobService jobService = new ServiceJobService();

            foreach (ServiceJob job in jobService.GetActiveJobs().ToList())
            {
                try
                {
                    IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                    ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                    sched.ScheduleJob(jobDetail, jobTrigger);
                }
                catch (Exception ex)
                {
                    // get path to the services directory
                    String path = System.Reflection.Assembly.GetExecutingAssembly().Location;
                    path = System.IO.Path.GetDirectoryName(path);

                    // create a friendly error message
                    string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the services directory ({2}) of your server.", job.Name, job.Assembly, path);
                    message = message + "\n\n\n\n" + ex.Message;
                    //throw new JobLoadFailedException( message );
                    job.LastStatusMessage = message;
                    job.LastStatus        = "Error Loading Job";

                    jobService.Save(job, null);
                }
            }

            // set up the listener to report back from jobs as they complete
            sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

            // start the scheduler
            sched.Start();
        }
示例#4
0
        public void RunJob(Dictionary <string, string> jobDataMapDictionary, JobNotificationStatus jobNotificationStatus = JobNotificationStatus.None)
        {
            var job = GetAddTestJob(jobNotificationStatus);

            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);

                if (job != null)
                {
                    // create a scheduler specific for the job
                    var scheduleConfig      = new System.Collections.Specialized.NameValueCollection();
                    var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40);
                    scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName);
                    var schedulerFactory = new StdSchedulerFactory(scheduleConfig);
                    var sched            = new StdSchedulerFactory(scheduleConfig).GetScheduler();
                    if (sched.IsStarted)
                    {
                        // the job is currently running as a RunNow job
                        return;
                    }

                    // Check if another scheduler is running this job
                    try
                    {
                        var otherSchedulers = new Quartz.Impl.StdSchedulerFactory().AllSchedulers
                                              .Where(s => s.SchedulerName != runNowSchedulerName);

                        foreach (var scheduler in otherSchedulers)
                        {
                            if (scheduler.GetCurrentlyExecutingJobs().Where(j => j.JobDetail.Description == job.Id.ToString() &&
                                                                            j.JobDetail.ConcurrentExectionDisallowed).Any())
                            {
                                // A job with that Id is already running and ConcurrentExectionDisallowed is true
                                System.Diagnostics.Debug.WriteLine(RockDateTime.Now.ToString() + $" Scheduler '{scheduler.SchedulerName}' is already executing job Id '{job.Id}' (name: {job.Name})");
                                return;
                            }
                        }
                    }
                    catch { }

                    // create the quartz job and trigger
                    IJobDetail jobDetail = jobService.BuildQuartzJob(job);

                    if (jobDataMapDictionary != null)
                    {
                        // Force the <string, string> dictionary so that within Jobs, it is always okay to use
                        // JobDataMap.GetString(). This mimics Rock attributes always being stored as strings.
                        // If we allow non-strings, like integers, then JobDataMap.GetString() throws an exception.
                        jobDetail.JobDataMap.PutAll(jobDataMapDictionary.ToDictionary(kvp => kvp.Key, kvp => ( object )kvp.Value));
                    }

                    var jobTrigger = TriggerBuilder.Create()
                                     .WithIdentity(job.Guid.ToString(), job.Name)
                                     .StartNow()
                                     .Build();

                    // schedule the job
                    sched.ScheduleJob(jobDetail, jobTrigger);

                    // set up the listener to report back from the job when it completes
                    sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                    // start the scheduler
                    sched.Start();

                    // Wait 10secs to give job chance to start
                    System.Threading.Tasks.Task.Delay(new TimeSpan(0, 0, 10)).Wait();

                    // stop the scheduler when done with job
                    sched.Shutdown(true);
                }
            }
        }
        /// <summary>
        /// Starts the job scheduler.
        /// </summary>
        private static void StartJobScheduler()
        {
            using (var rockContext = new RockContext())
            {
                // create scheduler
                ISchedulerFactory schedulerFactory = new StdSchedulerFactory();
                QuartzScheduler = schedulerFactory.GetScheduler();

                // get list of active jobs
                ServiceJobService jobService = new ServiceJobService(rockContext);
                var activeJobList            = jobService.GetActiveJobs().OrderBy(a => a.Name).ToList();
                foreach (ServiceJob job in activeJobList)
                {
                    const string ErrorLoadingStatus = "Error Loading Job";

                    try
                    {
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                        // Schedule the job (unless the cron expression is set to never run for an on-demand job like rebuild streaks)
                        if (job.CronExpression != ServiceJob.NeverScheduledCronExpression)
                        {
                            QuartzScheduler.ScheduleJob(jobDetail, jobTrigger);
                        }

                        //// if the last status was an error, but we now loaded successful, clear the error
                        // also, if the last status was 'Running', clear that status because it would have stopped if the app restarted
                        if (job.LastStatus == ErrorLoadingStatus || job.LastStatus == "Running")
                        {
                            job.LastStatusMessage = string.Empty;
                            job.LastStatus        = string.Empty;
                            rockContext.SaveChanges();
                        }
                    }
                    catch (Exception exception)
                    {
                        // create a friendly error message
                        string message = $"Error loading the job: {job.Name}.\n\n{exception.Message}";

                        // log the error
                        var startupException = new RockStartupException(message, exception);

                        LogError(startupException, null);

                        job.LastStatusMessage = message;
                        job.LastStatus        = ErrorLoadingStatus;
                        job.LastStatus        = ErrorLoadingStatus;
                        rockContext.SaveChanges();

                        var jobHistoryService = new ServiceJobHistoryService(rockContext);
                        var jobHistory        = new ServiceJobHistory()
                        {
                            ServiceJobId  = job.Id,
                            StartDateTime = RockDateTime.Now,
                            StopDateTime  = RockDateTime.Now,
                            Status        = job.LastStatus,
                            StatusMessage = job.LastStatusMessage
                        };

                        jobHistoryService.Add(jobHistory);
                        rockContext.SaveChanges();
                    }
                }

                // set up the listener to report back from jobs as they complete
                QuartzScheduler.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                // set up a trigger listener that can prevent a job from running if another scheduler is
                // already running it (i.e., someone running it manually).
                QuartzScheduler.ListenerManager.AddTriggerListener(new RockTriggerListener(), EverythingMatcher <JobKey> .AllTriggers());

                // start the scheduler
                QuartzScheduler.Start();
            }
        }
示例#6
0
        /// <summary>
        /// Handles the Start event of the Application control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void Application_Start(object sender, EventArgs e)
        {
            try
            {
                var stopwatch = System.Diagnostics.Stopwatch.StartNew();
                LogMessage(APP_LOG_FILENAME, "Application Starting...");

                if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("Application_Start: {0}", RockDateTime.Now.ToString("hh:mm:ss.FFF")));
                }

                // Clear all cache
                RockMemoryCache.Clear();

                // Get a db context
                using (var rockContext = new RockContext())
                {
                    if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                    {
                        try
                        {
                            // default Initializer is CreateDatabaseIfNotExists, so set it to NULL so that nothing happens if there isn't a database yet
                            Database.SetInitializer <Rock.Data.RockContext>(null);
                            new AttributeService(rockContext).Get(0);
                            System.Diagnostics.Debug.WriteLine(string.Format("ConnectToDatabase {2}/{1} - {0} ms", stopwatch.Elapsed.TotalMilliseconds, rockContext.Database.Connection.Database, rockContext.Database.Connection.DataSource));
                        }
                        catch
                        {
                            // Intentionally Blank
                        }
                    }

                    //// Run any needed Rock and/or plugin migrations
                    //// NOTE: MigrateDatabase must be the first thing that touches the database to help prevent EF from creating empty tables for a new database
                    MigrateDatabase(rockContext);

                    // Preload the commonly used objects
                    stopwatch.Restart();
                    LoadCacheObjects(rockContext);

                    if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                    {
                        System.Diagnostics.Debug.WriteLine(string.Format("LoadCacheObjects - {0} ms", stopwatch.Elapsed.TotalMilliseconds));
                    }

                    // Run any plugin migrations
                    MigratePlugins(rockContext);

                    RegisterRoutes(rockContext, RouteTable.Routes);

                    // Configure Rock Rest API
                    stopwatch.Restart();
                    GlobalConfiguration.Configure(Rock.Rest.WebApiConfig.Register);
                    if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                    {
                        System.Diagnostics.Debug.WriteLine(string.Format("Configure WebApiConfig - {0} ms", stopwatch.Elapsed.TotalMilliseconds));
                        stopwatch.Restart();
                    }

                    // setup and launch the jobs infrastructure if running under IIS
                    bool runJobsInContext = Convert.ToBoolean(ConfigurationManager.AppSettings["RunJobsInIISContext"]);
                    if (runJobsInContext)
                    {
                        ISchedulerFactory sf;

                        // create scheduler
                        sf    = new StdSchedulerFactory();
                        sched = sf.GetScheduler();

                        // get list of active jobs
                        ServiceJobService jobService = new ServiceJobService(rockContext);
                        foreach (ServiceJob job in jobService.GetActiveJobs().ToList())
                        {
                            const string errorLoadingStatus = "Error Loading Job";
                            try
                            {
                                IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                                ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                                sched.ScheduleJob(jobDetail, jobTrigger);

                                //// if the last status was an error, but we now loaded successful, clear the error
                                // also, if the last status was 'Running', clear that status because it would have stopped if the app restarted
                                if (job.LastStatus == errorLoadingStatus || job.LastStatus == "Running")
                                {
                                    job.LastStatusMessage = string.Empty;
                                    job.LastStatus        = string.Empty;
                                    rockContext.SaveChanges();
                                }
                            }
                            catch (Exception ex)
                            {
                                // log the error
                                LogError(ex, null);

                                // create a friendly error message
                                string message = string.Format("Error loading the job: {0}.\n\n{2}", job.Name, job.Assembly, ex.Message);
                                job.LastStatusMessage = message;
                                job.LastStatus        = errorLoadingStatus;
                                rockContext.SaveChanges();
                            }
                        }

                        // set up the listener to report back from jobs as they complete
                        sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                        // start the scheduler
                        sched.Start();
                    }

                    // Force the static Liquid class to get instantiated so that the standard filters are loaded prior
                    // to the custom RockFilter.  This is to allow the custom 'Date' filter to replace the standard
                    // Date filter.
                    Liquid.UseRubyDateFormat = false;

                    //// NOTE: This means that template filters will also use CSharpNamingConvention
                    //// For example the dotliquid documentation says to do this for formatting dates:
                    //// {{ some_date_value | date:"MMM dd, yyyy" }}
                    //// However, if CSharpNamingConvention is enabled, it needs to be:
                    //// {{ some_date_value | Date:"MMM dd, yyyy" }}
                    Template.NamingConvention = new DotLiquid.NamingConventions.CSharpNamingConvention();
                    Template.FileSystem       = new RockWeb.LavaFileSystem();
                    Template.RegisterSafeType(typeof(Enum), o => o.ToString());
                    Template.RegisterFilter(typeof(Rock.Lava.RockFilters));

                    // add call back to keep IIS process awake at night and to provide a timer for the queued transactions
                    AddCallBack();

                    Rock.Security.Authorization.Load();
                }

                EntityTypeService.RegisterEntityTypes(Server.MapPath("~"));
                FieldTypeService.RegisterFieldTypes(Server.MapPath("~"));

                BundleConfig.RegisterBundles(BundleTable.Bundles);

                // mark any user login stored as 'IsOnline' in the database as offline
                MarkOnlineUsersOffline();

                SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~"));

                LogMessage(APP_LOG_FILENAME, "Application Started Successfully");
                if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("Application_Started_Successfully: {0}", RockDateTime.Now.ToString("hh:mm:ss.FFF")));
                }
            }
            catch (Exception ex)
            {
                SetError66();
                throw (new Exception("Error occurred during application startup", ex));
            }
        }
示例#7
0
        /// <summary>
        /// Handles the Start event of the Application control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void Application_Start(object sender, EventArgs e)
        {
            if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
            {
                HttpInternals.RockWebFileChangeMonitor();
            }

            // Check if database should be auto-migrated for the core and plugins
            bool autoMigrate = true;

            if (!Boolean.TryParse(ConfigurationManager.AppSettings["AutoMigrateDatabase"], out autoMigrate))
            {
                autoMigrate = true;
            }

            if (autoMigrate)
            {
                try
                {
                    Database.SetInitializer(new MigrateDatabaseToLatestVersion <Rock.Data.RockContext, Rock.Migrations.Configuration>());

                    // explictly check if the database exists, and force create it if doesn't exist
                    Rock.Data.RockContext rockContext = new Rock.Data.RockContext();
                    if (!rockContext.Database.Exists())
                    {
                        rockContext.Database.Initialize(true);
                    }
                    else
                    {
                        var migrator = new System.Data.Entity.Migrations.DbMigrator(new Rock.Migrations.Configuration());
                        migrator.Update();
                    }

                    // Migrate any plugins that have pending migrations
                    List <Type> configurationTypeList = Rock.Reflection.FindTypes(typeof(System.Data.Entity.Migrations.DbMigrationsConfiguration)).Select(a => a.Value).ToList();

                    foreach (var configType in configurationTypeList)
                    {
                        if (configType != typeof(Rock.Migrations.Configuration))
                        {
                            var config = Activator.CreateInstance(configType) as System.Data.Entity.Migrations.DbMigrationsConfiguration;
                            System.Data.Entity.Migrations.DbMigrator pluginMigrator = Activator.CreateInstance(typeof(System.Data.Entity.Migrations.DbMigrator), config) as System.Data.Entity.Migrations.DbMigrator;
                            pluginMigrator.Update();
                        }
                    }
                }
                catch (Exception ex)
                {
                    // if migrations fail, log error and attempt to continue
                    LogError(ex, -1, string.Empty, HttpContext.Current);
                }
            }
            else
            {
                // default Initializer is CreateDatabaseIfNotExists, but we don't want that to happen if automigrate is false, so set it to NULL so that nothing happens
                Database.SetInitializer <Rock.Data.RockContext>(null);
            }

            // Preload the commonly used objects
            LoadCacheObjects();

            // setup and launch the jobs infrastructure if running under IIS
            bool runJobsInContext = Convert.ToBoolean(ConfigurationManager.AppSettings["RunJobsInIISContext"]);

            if (runJobsInContext)
            {
                ISchedulerFactory sf;

                // create scheduler
                sf    = new StdSchedulerFactory();
                sched = sf.GetScheduler();

                // get list of active jobs
                ServiceJobService jobService = new ServiceJobService();
                foreach (ServiceJob job in jobService.GetActiveJobs().ToList())
                {
                    try
                    {
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                        sched.ScheduleJob(jobDetail, jobTrigger);
                    }
                    catch (Exception ex)
                    {
                        // create a friendly error message
                        string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the websites App_Code directory. \n\n\n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";

                        jobService.Save(job, null);
                    }
                }

                // set up the listener to report back from jobs as they complete
                sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                // start the scheduler
                sched.Start();
            }

            // add call back to keep IIS process awake at night and to provide a timer for the queued transactions
            AddCallBack();

            RegisterFilters(GlobalConfiguration.Configuration.Filters);

            RegisterRoutes(RouteTable.Routes);

            Rock.Security.Authorization.Load();

            AddEventHandlers();

            new EntityTypeService().RegisterEntityTypes(Server.MapPath("~"));
            new FieldTypeService().RegisterFieldTypes(Server.MapPath("~"));

            BundleConfig.RegisterBundles(BundleTable.Bundles);
        }
示例#8
0
        /// <summary>
        /// Updates the scheduled jobs.
        /// </summary>
        /// <param name="context">The context.</param>
        private void UpdateScheduledJobs(IJobExecutionContext context)
        {
            var scheduler           = context.Scheduler;
            int jobsDeleted         = 0;
            int jobsScheduleUpdated = 0;

            var rockContext = new Rock.Data.RockContext();
            ServiceJobService    jobService          = new ServiceJobService(rockContext);
            List <ServiceJob>    activeJobList       = jobService.GetActiveJobs().ToList();
            List <Quartz.JobKey> scheduledQuartzJobs = scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith(string.Empty)).ToList();

            // delete any jobs that are no longer exist (are are not set to active) in the database
            var quartsJobsToDelete = scheduledQuartzJobs.Where(a => !activeJobList.Any(j => j.Guid.Equals(a.Name.AsGuid())));

            foreach (JobKey jobKey in quartsJobsToDelete)
            {
                scheduler.DeleteJob(jobKey);
                jobsDeleted++;
            }

            // add any jobs that are not yet scheduled
            var newActiveJobs = activeJobList.Where(a => !scheduledQuartzJobs.Any(q => q.Name.AsGuid().Equals(a.Guid)));

            foreach (Rock.Model.ServiceJob job in newActiveJobs)
            {
                const string errorSchedulingStatus = "Error scheduling Job";
                try
                {
                    IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                    ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                    scheduler.ScheduleJob(jobDetail, jobTrigger);
                    jobsScheduleUpdated++;

                    if (job.LastStatus == errorSchedulingStatus)
                    {
                        job.LastStatusMessage = string.Empty;
                        job.LastStatus        = string.Empty;
                        rockContext.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    ExceptionLogService.LogException(ex, null);

                    // create a friendly error message
                    string message = string.Format("Error scheduling the job: {0}.\n\n{2}", job.Name, job.Assembly, ex.Message);
                    job.LastStatusMessage = message;
                    job.LastStatus        = errorSchedulingStatus;
                }
            }

            rockContext.SaveChanges();

            // reload the jobs in case any where added/removed
            scheduledQuartzJobs = scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith(string.Empty)).ToList();

            // update schedule if the schedule has changed
            foreach (var jobKey in scheduledQuartzJobs)
            {
                var jobCronTrigger = scheduler.GetTriggersOfJob(jobKey).OfType <ICronTrigger>().FirstOrDefault();
                if (jobCronTrigger != null)
                {
                    var activeJob = activeJobList.FirstOrDefault(a => a.Guid.Equals(jobKey.Name.AsGuid()));
                    if (activeJob != null)
                    {
                        bool rescheduleJob = false;

                        // fix up the schedule if it has changed
                        if (activeJob.CronExpression != jobCronTrigger.CronExpressionString)
                        {
                            rescheduleJob = true;
                        }

                        // update the job detail if it has changed
                        var scheduledJobDetail = scheduler.GetJobDetail(jobKey);
                        var jobDetail          = jobService.BuildQuartzJob(activeJob);

                        if (scheduledJobDetail != null && jobDetail != null)
                        {
                            if (scheduledJobDetail.JobType != jobDetail.JobType)
                            {
                                rescheduleJob = true;
                            }

                            if (scheduledJobDetail.JobDataMap.ToJson() != jobDetail.JobDataMap.ToJson())
                            {
                                rescheduleJob = true;
                            }
                        }

                        if (rescheduleJob)
                        {
                            const string errorReschedulingStatus = "Error re-scheduling Job";
                            try
                            {
                                ITrigger newJobTrigger       = jobService.BuildQuartzTrigger(activeJob);
                                bool     deletedSuccessfully = scheduler.DeleteJob(jobKey);
                                scheduler.ScheduleJob(jobDetail, newJobTrigger);
                                jobsScheduleUpdated++;

                                if (activeJob.LastStatus == errorReschedulingStatus)
                                {
                                    activeJob.LastStatusMessage = string.Empty;
                                    activeJob.LastStatus        = string.Empty;
                                    rockContext.SaveChanges();
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionLogService.LogException(ex, null);

                                // create a friendly error message
                                string message = string.Format("Error re-scheduling the job: {0}.\n\n{2}", activeJob.Name, activeJob.Assembly, ex.Message);
                                activeJob.LastStatusMessage = message;
                                activeJob.LastStatus        = errorReschedulingStatus;
                            }
                        }
                    }
                }
            }

            context.Result = string.Empty;

            if (jobsDeleted > 0)
            {
                context.Result += string.Format("Deleted {0} job schedule(s)", jobsDeleted);
            }

            if (jobsScheduleUpdated > 0)
            {
                context.Result += (string.IsNullOrEmpty(context.Result as string) ? "" : " and ") + string.Format("Updated {0} schedule(s)", jobsScheduleUpdated);
            }
        }
示例#9
0
        /// <summary>
        /// Starts the job scheduler.
        /// </summary>
        public void StartJobScheduler()
        {
            if (!System.IO.File.Exists("web.connectionstrings.config"))
            {
                // Write an eventlog about web.connectionstring.config not found
                this.EventLog.WriteEntry("Unable to find web.connectionstrings.config", EventLogEntryType.Error);
            }

            ISchedulerFactory sf;

            // create scheduler
            sf    = new StdSchedulerFactory();
            sched = sf.GetScheduler();

            var rockContext = new RockContext();

            // get list of active jobs
            ServiceJobService jobService = new ServiceJobService(rockContext);
            List <ServiceJob> activeJobs = null;

            try
            {
                // make sure that we can connect to the database and get the jobs list.  Write a good EventLog message and exit the app if we can't
                this.EventLog.WriteEntry(string.Format("Connecting to database {0}:{1}", rockContext.Database.Connection.DataSource, rockContext.Database.Connection.Database), EventLogEntryType.Information);
                rockContext.Database.Connection.Open();
                activeJobs = jobService.GetActiveJobs().ToList();
            }
            catch (Exception ex)
            {
                this.EventLog.WriteEntry("Unable load active jobs list. " + ex.Message, EventLogEntryType.Error);
                throw ex;
            }

            foreach (ServiceJob job in activeJobs)
            {
                try
                {
                    IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                    ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                    sched.ScheduleJob(jobDetail, jobTrigger);
                }
                catch (Exception ex)
                {
                    // get path to the services directory
                    string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
                    path = System.IO.Path.GetDirectoryName(path);

                    // create a friendly error message
                    string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the services directory ({2}) of your server.", job.Name, job.Assembly, path);
                    message = message + "\n\n\n\n" + ex.Message;
                    //throw new JobLoadFailedException( message );
                    job.LastStatusMessage = message;
                    job.LastStatus        = "Error Loading Job";

                    rockContext.SaveChanges();
                }
            }

            // set up the listener to report back from jobs as they complete
            sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

            // start the scheduler
            sched.Start();
        }
示例#10
0
        /// <summary>
        /// Handles the Start event of the Application control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void Application_Start(object sender, EventArgs e)
        {
            try
            {
                if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("Application_Start: {0}", RockDateTime.Now.ToString("hh:mm:ss.FFF")));
                }

                // Run any needed Rock and/or plugin migrations
                MigrateDatabase();

                // Get a db context
                var rockContext = new RockContext();

                RegisterRoutes(rockContext, RouteTable.Routes);

                if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                {
                    new AttributeService(rockContext).Get(0);
                    System.Diagnostics.Debug.WriteLine(string.Format("ConnectToDatabase - Connected: {0}", RockDateTime.Now.ToString("hh:mm:ss.FFF")));
                }

                // Preload the commonly used objects
                LoadCacheObjects(rockContext);
                if (System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                {
                    System.Diagnostics.Debug.WriteLine(string.Format("LoadCacheObjects - Done: {0}", RockDateTime.Now.ToString("hh:mm:ss.FFF")));
                }

                // setup and launch the jobs infrastructure if running under IIS
                bool runJobsInContext = Convert.ToBoolean(ConfigurationManager.AppSettings["RunJobsInIISContext"]);
                if (runJobsInContext)
                {
                    ISchedulerFactory sf;

                    // create scheduler
                    sf    = new StdSchedulerFactory();
                    sched = sf.GetScheduler();

                    // get list of active jobs
                    ServiceJobService jobService = new ServiceJobService(rockContext);
                    foreach (ServiceJob job in jobService.GetActiveJobs().ToList())
                    {
                        try
                        {
                            IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                            ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                            sched.ScheduleJob(jobDetail, jobTrigger);
                        }
                        catch (Exception ex)
                        {
                            // create a friendly error message
                            string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the websites App_Code directory. \n\n\n\n{2}", job.Name, job.Assembly, ex.Message);
                            job.LastStatusMessage = message;
                            job.LastStatus        = "Error Loading Job";
                            rockContext.SaveChanges();
                        }
                    }

                    // set up the listener to report back from jobs as they complete
                    sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                    // start the scheduler
                    sched.Start();
                }

                // add call back to keep IIS process awake at night and to provide a timer for the queued transactions
                AddCallBack();

                RegisterFilters(GlobalConfiguration.Configuration.Filters);

                Rock.Security.Authorization.Load(rockContext);

                EntityTypeService.RegisterEntityTypes(Server.MapPath("~"));
                FieldTypeService.RegisterFieldTypes(Server.MapPath("~"));

                BundleConfig.RegisterBundles(BundleTable.Bundles);

                // mark any user login stored as 'IsOnline' in the database as offline
                MarkOnlineUsersOffline();

                SqlServerTypes.Utilities.LoadNativeAssemblies(Server.MapPath("~"));
            }
            catch (Exception ex)
            {
                Error66(ex);
            }
        }
示例#11
0
        /// <summary>
        /// Updates the scheduled jobs.
        /// </summary>
        /// <param name="context">The context.</param>
        private void UpdateScheduledJobs(IJobExecutionContext context)
        {
            var scheduler = context.Scheduler;

            var rockContext = new Rock.Data.RockContext();
            ServiceJobService    jobService          = new ServiceJobService(rockContext);
            List <ServiceJob>    activeJobList       = jobService.GetActiveJobs().ToList();
            List <Quartz.JobKey> scheduledQuartzJobs = scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith(string.Empty)).ToList();

            // delete any jobs that are no longer exist (are are not set to active) in the database
            var quartsJobsToDelete = scheduledQuartzJobs.Where(a => !activeJobList.Any(j => j.Guid.Equals(a.Name.AsGuid())));

            foreach (JobKey jobKey in quartsJobsToDelete)
            {
                scheduler.DeleteJob(jobKey);
            }

            // add any jobs that are not yet scheduled
            var newActiveJobs = activeJobList.Where(a => !scheduledQuartzJobs.Any(q => q.Name.AsGuid().Equals(a.Guid)));

            foreach (Rock.Model.ServiceJob job in newActiveJobs)
            {
                try
                {
                    IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                    ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                    scheduler.ScheduleJob(jobDetail, jobTrigger);
                }
                catch (Exception ex)
                {
                    // create a friendly error message
                    string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the websites App_Code directory. \n\n\n\n{2}", job.Name, job.Assembly, ex.Message);
                    job.LastStatusMessage = message;
                    job.LastStatus        = "Error Loading Job";
                }
            }

            rockContext.SaveChanges();

            // reload the jobs in case any where added/removed
            scheduledQuartzJobs = scheduler.GetJobKeys(GroupMatcher <JobKey> .GroupStartsWith(string.Empty)).ToList();

            // update schedule if the schedule has changed
            foreach (var jobKey in scheduledQuartzJobs)
            {
                var jobCronTrigger = scheduler.GetTriggersOfJob(jobKey).OfType <ICronTrigger>().FirstOrDefault();
                if (jobCronTrigger != null)
                {
                    var activeJob = activeJobList.FirstOrDefault(a => a.Guid.Equals(jobKey.Name.AsGuid()));
                    if (activeJob != null)
                    {
                        bool rescheduleJob = false;

                        // fix up the schedule if it has changed
                        if (activeJob.CronExpression != jobCronTrigger.CronExpressionString)
                        {
                            rescheduleJob = true;
                        }

                        // update the job detail if it has changed
                        var scheduledJobDetail = scheduler.GetJobDetail(jobKey);
                        var jobDetail          = jobService.BuildQuartzJob(activeJob);

                        if (scheduledJobDetail != null && jobDetail != null)
                        {
                            if (scheduledJobDetail.JobType != jobDetail.JobType)
                            {
                                rescheduleJob = true;
                            }

                            if (scheduledJobDetail.JobDataMap.ToJson() != jobDetail.JobDataMap.ToJson())
                            {
                                rescheduleJob = true;
                            }
                        }

                        if (rescheduleJob)
                        {
                            ITrigger newJobTrigger = jobService.BuildQuartzTrigger(activeJob);
                            scheduler.DeleteJob(jobKey);
                            scheduler.ScheduleJob(jobDetail, newJobTrigger);
                        }
                    }
                }
            }
        }
示例#12
0
        /// <summary>
        /// Handles the Start event of the Application control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="EventArgs" /> instance containing the event data.</param>
        protected void Application_Start(object sender, EventArgs e)
        {
            // Check if database should be auto-migrated
            bool autoMigrate = true;

            if (!Boolean.TryParse(ConfigurationManager.AppSettings["AutoMigrateDatabase"], out autoMigrate))
            {
                autoMigrate = true;
            }
            if (autoMigrate)
            {
                Database.SetInitializer(new MigrateDatabaseToLatestVersion <Rock.Data.RockContext, Rock.Migrations.Configuration>());
            }

            // Preload the commonly used objects
            LoadCacheObjects();

            // setup and launch the jobs infrastructure if running under IIS
            bool runJobsInContext = Convert.ToBoolean(ConfigurationManager.AppSettings["RunJobsInIISContext"]);

            if (runJobsInContext)
            {
                ISchedulerFactory sf;

                // create scheduler
                sf    = new StdSchedulerFactory();
                sched = sf.GetScheduler();

                // get list of active jobs
                ServiceJobService jobService = new ServiceJobService();
                foreach (ServiceJob job in jobService.GetActiveJobs().ToList())
                {
                    try
                    {
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                        sched.ScheduleJob(jobDetail, jobTrigger);
                    }
                    catch (Exception ex)
                    {
                        // create a friendly error message
                        string message = string.Format("Error loading the job: {0}.  Ensure that the correct version of the job's assembly ({1}.dll) in the websites App_Code directory. \n\n\n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";

                        jobService.Save(job, null);
                    }
                }

                // set up the listener to report back from jobs as they complete
                sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                // start the scheduler
                sched.Start();
            }

            // add call back to keep IIS process awake at night and to provide a timer for the queued transactions
            AddCallBack();

            RegisterFilters(GlobalConfiguration.Configuration.Filters);

            RegisterRoutes(RouteTable.Routes);

            Rock.Security.Authorization.Load();

            AddEventHandlers();
        }
示例#13
0
        /// <summary>
        /// Starts the job scheduler.
        /// </summary>
        public void StartJobScheduler()
        {
            if (!System.IO.File.Exists("web.connectionstrings.config"))
            {
                // Write an eventlog about web.connectionstring.config not found
                this.EventLog.WriteEntry("Unable to find web.connectionstrings.config", EventLogEntryType.Error);
            }

            ISchedulerFactory sf;

            // create scheduler
            sf    = new StdSchedulerFactory();
            sched = sf.GetScheduler();

            var rockContext = new RockContext();

            // get list of active jobs
            ServiceJobService jobService = new ServiceJobService(rockContext);
            List <ServiceJob> activeJobs = null;

            try
            {
                // make sure that we can connect to the database and get the jobs list.  Write a good EventLog message and exit the app if we can't
                this.EventLog.WriteEntry(string.Format("Connecting to database {0}:{1}", rockContext.Database.Connection.DataSource, rockContext.Database.Connection.Database), EventLogEntryType.Information);
                rockContext.Database.Connection.Open();
                activeJobs = jobService.GetActiveJobs().ToList();
            }
            catch (Exception ex)
            {
                this.EventLog.WriteEntry("Unable load active jobs list. " + ex.Message, EventLogEntryType.Error);
                throw ex;
            }

            foreach (ServiceJob job in activeJobs)
            {
                const string errorLoadingStatus = "Error Loading Job";
                try
                {
                    IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                    ITrigger   jobTrigger = jobService.BuildQuartzTrigger(job);

                    sched.ScheduleJob(jobDetail, jobTrigger);

                    //// if the last status was an error, but we now loaded successful, clear the error
                    // also, if the last status was 'Running', clear that status because it would have stopped if the app restarted
                    if (job.LastStatus == errorLoadingStatus || job.LastStatus == "Running")
                    {
                        job.LastStatusMessage = string.Empty;
                        job.LastStatus        = string.Empty;
                        rockContext.SaveChanges();
                    }
                }
                catch (Exception ex)
                {
                    ExceptionLogService.LogException(ex, null);

                    // get path to the services directory
                    string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
                    path = System.IO.Path.GetDirectoryName(path);

                    // create the error message
                    string message = string.Format("Error loading the job: {0}.\n\n{1}\n\n Job Assembly: {2}, Path: {3}", job.Name, ex.Message, job.Assembly, path);
                    job.LastStatusMessage = message;
                    job.LastStatus        = errorLoadingStatus;
                    rockContext.SaveChanges();
                }

                // set up the listener to report back from jobs as they complete
                sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                // start the scheduler
                sched.Start();
            }

            // set up the listener to report back from jobs as they complete
            sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

            // start the scheduler
            sched.Start();
        }
示例#14
0
        /// <summary>
        /// Executes this instance.
        /// </summary>
        public void Execute()
        {
            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);

                ServiceJob job = jobService.Get(JobId);
                if (job != null)
                {
                    try
                    {
                        // create a scheduler specific for the job
                        var scheduleConfig      = new System.Collections.Specialized.NameValueCollection();
                        var runNowSchedulerName = ("RunNow:" + job.Guid.ToString("N")).Truncate(40);
                        scheduleConfig.Add(StdSchedulerFactory.PropertySchedulerInstanceName, runNowSchedulerName);
                        var schedulerFactory = new StdSchedulerFactory(scheduleConfig);
                        var sched            = new StdSchedulerFactory(scheduleConfig).GetScheduler();
                        if (sched.IsStarted)
                        {
                            // the job is currently running as a RunNow job
                            return;
                        }

                        // Check if another scheduler is running this job
                        try
                        {
                            var otherSchedulers = new Quartz.Impl.StdSchedulerFactory().AllSchedulers
                                                  .Where(s => s.SchedulerName != runNowSchedulerName);

                            foreach (var scheduler in otherSchedulers)
                            {
                                if (scheduler.GetCurrentlyExecutingJobs().Where(j => j.JobDetail.Description == JobId.ToString() &&
                                                                                j.JobDetail.ConcurrentExectionDisallowed).Any())
                                {
                                    // A job with that Id is already running and ConcurrentExectionDisallowed is true
                                    return;
                                }
                            }
                        }
                        catch { }

                        // create the quartz job and trigger
                        IJobDetail jobDetail  = jobService.BuildQuartzJob(job);
                        var        jobTrigger = TriggerBuilder.Create()
                                                .WithIdentity(job.Guid.ToString(), job.Name)
                                                .StartNow()
                                                .Build();

                        // schedule the job
                        sched.ScheduleJob(jobDetail, jobTrigger);

                        // set up the listener to report back from the job when it completes
                        sched.ListenerManager.AddJobListener(new RockJobListener(), EverythingMatcher <JobKey> .AllJobs());

                        // start the scheduler
                        sched.Start();

                        // Wait 10secs to give job chance to start
                        System.Threading.Tasks.Task.Delay(new TimeSpan(0, 0, 10)).Wait();

                        // stop the scheduler when done with job
                        sched.Shutdown(true);
                    }

                    catch (Exception ex)
                    {
                        // create a friendly error message
                        ExceptionLogService.LogException(ex, null);
                        string message = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message);
                        job.LastStatusMessage = message;
                        job.LastStatus        = "Error Loading Job";
                        rockContext.SaveChanges();

                        var jobHistoryService = new ServiceJobHistoryService(rockContext);
                        var jobHistory        = new ServiceJobHistory()
                        {
                            ServiceJobId  = job.Id,
                            StartDateTime = RockDateTime.Now,
                            StopDateTime  = RockDateTime.Now,
                            Status        = job.LastStatus,
                            StatusMessage = job.LastStatusMessage
                        };
                        jobHistoryService.Add(jobHistory);
                        rockContext.SaveChanges();
                    }
                }
            }
        }