Exemplo n.º 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();
                    }
                }
            }
        }
        /// <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();
                    }
                }
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Deletes the job.
        /// </summary>
        /// <param name="jobId">The job identifier.</param>
        public static void DeleteJob(int jobId)
        {
            using (var rockContext = new RockContext())
            {
                var jobService = new ServiceJobService(rockContext);
                var job        = jobService.Get(jobId);

                if (job != null)
                {
                    jobService.Delete(job);
                    rockContext.SaveChanges();
                    return;
                }
            }
        }
        /// <summary>
        /// Handles the Delete event of the grdScheduledJobs control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param>
        protected void gScheduledJobs_Delete( object sender, RowEventArgs e )
        {
            var rockContext = new RockContext();
            var jobService = new ServiceJobService( rockContext );
            ServiceJob job = jobService.Get( e.RowKeyId );

            string errorMessage;
            if ( !jobService.CanDelete( job, out errorMessage ) )
            {
                mdGridWarning.Show( errorMessage, ModalAlertType.Information );
                return;
            }

            jobService.Delete( job );
            rockContext.SaveChanges();

            BindGrid();
        }
        /// <summary>
        /// Deletes job history items more than maximum.
        /// </summary>
        /// <param name="serviceJobId">The service job identifier.</param>
        public void DeleteMoreThanMax(int serviceJobId)
        {
            int historyCount;
            ServiceJobService serviceJobService = new ServiceJobService((RockContext)this.Context);
            ServiceJob        serviceJob        = serviceJobService.Get(serviceJobId);

            historyCount = serviceJob.HistoryCount;

            historyCount = historyCount <= 0 ? historyCount = 100 : historyCount;
            var matchingServiceJobs    = this.AsNoFilter().Where(a => a.ServiceJobId == serviceJobId).OrderByDescending(a => a.StartDateTime);
            var serviceJobsMoreThanMax = matchingServiceJobs.Skip(historyCount).ToArray();

            for (int i = 0; i < serviceJobsMoreThanMax.Count(); i++)
            {
                this.Delete(serviceJobsMoreThanMax[i]);
            }

            this.Context.SaveChanges();
        }
Exemplo n.º 6
0
        /// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            ServiceJob job;
            ServiceJobService jobService = new ServiceJobService();

            int jobId = int.Parse( hfId.Value );

            if ( jobId == 0 )
            {
                job = new ServiceJob();
                jobService.Add( job, CurrentPersonId );
            }
            else
            {
                job = jobService.Get( jobId );
            }

            job.Name = tbName.Text;
            job.Description = tbDescription.Text;
            job.IsActive = cbActive.Checked;
            job.Assembly = tbAssembly.Text;
            job.Class = tbClass.Text;
            job.NotificationEmails = tbNotificationEmails.Text;
            job.NotificationStatus = (JobNotificationStatus)int.Parse( drpNotificationStatus.SelectedValue );
            job.CronExpression = tbCronExpression.Text;

            if ( !job.IsValid )
            {
                // Controls will render the error messages
                return;
            }

            RockTransactionScope.WrapTransaction( () =>
                {
                    jobService.Save( job, CurrentPersonId );
                } );

            BindGrid();
            pnlDetails.Visible = false;
            pnlGrid.Visible = true;
        }
Exemplo n.º 7
0
        /// <summary>
        /// Handles the Delete event of the grdScheduledJobs control.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="RowEventArgs" /> instance containing the event data.</param>
        protected void gScheduledJobs_Delete( object sender, RowEventArgs e )
        {
            RockTransactionScope.WrapTransaction( () =>
            {
                var jobService = new ServiceJobService();
                ServiceJob job = jobService.Get( (int)e.RowKeyValue );

                string errorMessage;
                if ( !jobService.CanDelete( job, out errorMessage ) )
                {
                    mdGridWarning.Show( errorMessage, ModalAlertType.Information );
                    return;
                }

                jobService.Delete( job, CurrentPersonId );
                jobService.Save( job, CurrentPersonId );
            } );

            BindGrid();
        }
Exemplo n.º 8
0
        /// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            try
            {
                ExpressionDescriptor.GetDescription( tbCronExpression.Text );
            }
            catch (Exception ex)
            {
                tbCronExpression.ShowErrorMessage( "Invalid Cron Expression: " + ex.Message );
                return;
            }

            ServiceJob job;
            var rockContext = new RockContext();
            ServiceJobService jobService = new ServiceJobService( rockContext );

            int jobId = int.Parse( hfId.Value );

            if ( jobId == 0 )
            {
                job = new ServiceJob();
                jobService.Add( job );
            }
            else
            {
                job = jobService.Get( jobId );
            }

            job.Name = tbName.Text;
            job.Description = tbDescription.Text;
            job.IsActive = cbActive.Checked;

            if (job.Class != ddlJobTypes.SelectedValue)
            {
                job.Class = ddlJobTypes.SelectedValue;

                //// if the Class has changed, the current Assembly value might not match,
                //// so set the Assembly to null to have Rock figure it out automatically
                job.Assembly = null;
            }

            job.NotificationEmails = tbNotificationEmails.Text;
            job.NotificationStatus = (JobNotificationStatus)int.Parse( ddlNotificationStatus.SelectedValue );
            job.CronExpression = tbCronExpression.Text;

            if ( !job.IsValid )
            {
                // Controls will render the error messages
                return;
            }

            rockContext.WrapTransaction( () =>
            {
                rockContext.SaveChanges();

                job.LoadAttributes( rockContext );
                Rock.Attribute.Helper.GetEditValues( phAttributes, job );
                job.SaveAttributeValues( rockContext );

            } );

            NavigateToParentPage();
        }
Exemplo n.º 9
0
        /// <summary>
        /// Handles the Click event of the btnSave 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 btnSave_Click( object sender, EventArgs e )
        {
            ServiceJob job;
            var rockContext = new RockContext();
            ServiceJobService jobService = new ServiceJobService( rockContext );

            int jobId = int.Parse( hfId.Value );

            if ( jobId == 0 )
            {
                job = new ServiceJob();
                jobService.Add( job );
            }
            else
            {
                job = jobService.Get( jobId );
            }

            job.Name = tbName.Text;
            job.Description = tbDescription.Text;
            job.IsActive = cbActive.Checked;
            job.Class = ddlJobTypes.SelectedValue;
            job.NotificationEmails = tbNotificationEmails.Text;
            job.NotificationStatus = (JobNotificationStatus)int.Parse( ddlNotificationStatus.SelectedValue );
            job.CronExpression = tbCronExpression.Text;

            if ( !job.IsValid )
            {
                // Controls will render the error messages
                return;
            }

            rockContext.WrapTransaction( () =>
            {
                rockContext.SaveChanges();

                job.LoadAttributes( rockContext );
                Rock.Attribute.Helper.GetEditValues( phAttributes, job );
                job.SaveAttributeValues( rockContext );

            } );

            NavigateToParentPage();
        }
Exemplo n.º 10
0
        /// <summary>
        /// Called by the <see cref="IScheduler"/> when a <see cref="IJobDetail"/>
        /// is about to be executed (an associated <see cref="ITrigger"/>
        /// has occurred).
        /// <para>
        /// This method will not be invoked if the execution of the Job was vetoed
        /// by a <see cref="ITriggerListener"/>.
        /// </para>
        /// </summary>
        /// <param name="context"></param>
        /// <seealso cref="JobExecutionVetoed(IJobExecutionContext)"/>
        public void JobToBeExecuted( IJobExecutionContext context )
        {
            StringBuilder message = new StringBuilder();

            // get job type id
            int jobId = context.JobDetail.Description.AsInteger();

            // load job
            var rockContext = new RockContext();
            var jobService = new ServiceJobService( rockContext );
            var job = jobService.Get( jobId );

            if (job != null && job.Guid != Rock.SystemGuid.ServiceJob.JOB_PULSE.AsGuid())
            {
                job.LastStatus = "Running";
                job.LastStatusMessage = "Started at " + RockDateTime.Now.ToString();
                rockContext.SaveChanges();
            }
        }
Exemplo n.º 11
0
        /// <summary>
        /// Called by the <see cref="IScheduler"/> after a <see cref="IJobDetail"/>
        /// has been executed, and before the associated <see cref="Quartz.Spi.IOperableTrigger"/>'s
        /// <see cref="Quartz.Spi.IOperableTrigger.Triggered"/> method has been called.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="jobException"></param>
        public void JobWasExecuted( IJobExecutionContext context, JobExecutionException jobException )
        {
            StringBuilder message = new StringBuilder();
            bool sendMessage = false;

            // get job type id
            int jobId = Convert.ToInt16( context.JobDetail.Description );

            // load job
            var rockContext = new RockContext();
            var jobService = new ServiceJobService( rockContext );
            var job = jobService.Get( jobId );

            // format the message
            message.Append( string.Format( "The job {0} ran for {1} seconds on {2}.  Below is the results:<p>", job.Name, context.JobRunTime.TotalSeconds, context.FireTimeUtc.Value.DateTime.ToLocalTime() ) );

            // if noticiation staus is all set flag to send message
            if ( job.NotificationStatus == JobNotificationStatus.All )
            {
                sendMessage = true;
            }

            // set last run date
            job.LastRunDateTime = RockDateTime.Now; // context.FireTimeUtc.Value.DateTime.ToLocalTime();

            // set run time
            job.LastRunDurationSeconds = Convert.ToInt32( context.JobRunTime.TotalSeconds );

            // set the scheduler name
            job.LastRunSchedulerName = context.Scheduler.SchedulerName;

            // determine if an error occured
            if ( jobException == null )
            {
                job.LastSuccessfulRunDateTime = job.LastRunDateTime;
                job.LastStatus = "Success";
                if ( context.Result is string )
                {
                    job.LastStatusMessage = context.Result as string;
                }

                message.Append( "Result: Success" );

                // determine if message should be sent
                if ( job.NotificationStatus == JobNotificationStatus.Success )
                {
                    sendMessage = true;
                }
            }
            else
            {
                Exception exceptionToLog = jobException;

                // drill down to the interesting exception
                while ( exceptionToLog is Quartz.SchedulerException && exceptionToLog.InnerException != null )
                {
                    exceptionToLog = exceptionToLog.InnerException;
                }

                // log the exception to the database
                ExceptionLogService.LogException( exceptionToLog, null );

                var summaryException = exceptionToLog;

                // put the exception into the status
                job.LastStatus = "Exception";

                AggregateException aggregateException = summaryException as AggregateException;
                if ( aggregateException != null && aggregateException.InnerExceptions != null && aggregateException.InnerExceptions.Count == 1 )
                {
                    // if it's an aggregate, but there is only one, convert it to a single exception
                    summaryException = aggregateException.InnerExceptions[0];
                    aggregateException = null;
                }

                if ( aggregateException != null )
                {
                    var firstException = aggregateException.InnerExceptions.First();
                    job.LastStatusMessage = "One or more exceptions occurred. First Exception: " + firstException.Message;
                    summaryException = firstException;
                }
                else
                {
                    job.LastStatusMessage = summaryException.Message;
                }

                message.Append( "Result: Exception<p>Message:<br>" + job.LastStatusMessage );

                if ( summaryException.InnerException != null )
                {
                    job.LastStatusMessage += " (" + summaryException.InnerException.Message + ")";
                    message.Append( "<p>Inner Exception:<br>" + summaryException.InnerException.Message );
                }

                if ( job.NotificationStatus == JobNotificationStatus.Error )
                {
                    sendMessage = true;
                }
            }

            rockContext.SaveChanges();

            // send notification
            if ( sendMessage )
            {
                // TODO: implement email send once it's available
            }
        }
Exemplo n.º 12
0
        /// <summary>
        /// Method that will be run at Rock startup
        /// </summary>
        public void OnStartup()
        {
            /* 10-01-2021 MDP
             *
             * In multi-server/cluster/web-farm Rock environments, only one of the servers should be running
             * these DataMigrationsStartups. To make sure that multiple servers don't run these, we'll
             * check if this is the server with RunJobsInIISContext enabled.
             *
             * If RunJobsInIISContext isn't enabled on this server, don't run these. However, if this
             * is a developer environment, we'll want to run these regardless of the RunJobsInIISContext setting.
             *
             */

            bool runJobsInContext = Convert.ToBoolean(ConfigurationManager.AppSettings["RunJobsInIISContext"]);

            if (!runJobsInContext)
            {
                // RunJobsInIISContext isn't enabled on this server, so don't run these DataMigrationsStartups unless
                // this is a developer environment
                if (!System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment)
                {
                    // RunJobsInIISContext isn't enabled, and this isn't a developer environment so exit without running DataMigrationsStartups.
                    return;
                }
            }

            List <Guid> runOnceJobGuids = new List <Guid>
            {
                SystemGuid.ServiceJob.DATA_MIGRATIONS_74.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_80.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_84.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_90_DISC.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_90.AsGuid(),
                        SystemGuid.ServiceJob.MIGRATE_HISTORY_SUMMARY_DATA.AsGuid(),
                        SystemGuid.ServiceJob.MIGRATE_ATTENDANCE_OCCURRENCE.AsGuid(),
                        SystemGuid.ServiceJob.MIGRATE_FAMILY_CHECKIN_IDS.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_90_SCHEDULEDTRANSACTIONNOTESTOHISTORY.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_100_ATTRIBUTEVALUE_VALUEASNUMERIC.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_100_SUNDAYDATE.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_103_SPIRITUAL_GIFTS.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_110_POPULATE_DATE_KEYS.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_110_COMMUNICATIONRECIPIENT_RESPONSECODE_INDEX.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_110_POPULATE_RELATED_DATAVIEW_ID.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_120_UPDATE_INTERACTION_INDEXES.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_120_ADD_COMMUNICATIONRECIPIENT_INDEX.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_120_ADD_COMMUNICATION_GET_QUEUED_INDEX.AsGuid(),

                /* MDP 07-22-2021
                 *
                 * NOTE: We intentionally are excluding SystemGuid.ServiceJob.DATA_MIGRATIONS_122_INTERACTION_PERSONAL_DEVICE_ID
                 * from DataMigrationStartup and will just wait for it to run at 2am.
                 * See https://app.asana.com/0/0/1199506067368201/f
                 *
                 */

                        SystemGuid.ServiceJob.DATA_MIGRATIONS_124_UPDATE_GROUP_SALUTATIONS.AsGuid(),
                        SystemGuid.ServiceJob.POST_INSTALL_DATA_MIGRATIONS.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_124_DECRYPT_FINANCIAL_PAYMENT_DETAILS.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_125_UPDATE_STEP_PROGRAM_COMPLETION.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_125_ADD_COMMUNICATION_SYSTEM_COMMUNICATION_ID_INDEX.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_127_REBUILD_GROUP_SALUTATIONS.AsGuid(),
                        SystemGuid.ServiceJob.DATA_MIGRATIONS_130_ADD_INTERACTION_INTERACTION_COMPONENT_ID_INDEX.AsGuid()
            };

            // run any of the above jobs if they still exist (they haven't run and deleted themselves)
            var runOnceJobIds = new Model.ServiceJobService(new Rock.Data.RockContext()).Queryable().Where(a => runOnceJobGuids.Contains(a.Guid)).Select(a => a.Id).ToList();

            // start a task that will run any incomplete RunOneJobs (one at a time)
            Task.Run(() =>
            {
                var rockContext = new Rock.Data.RockContext();
                var jobService  = new Rock.Model.ServiceJobService(rockContext);
                foreach (var runOnceJobId in runOnceJobIds)
                {
                    try
                    {
                        var job = jobService.Get(runOnceJobId);
                        jobService.RunNow(job, out _);
                    }
                    catch (Exception ex)
                    {
                        // this shouldn't happen since the jobService.RunNow catches and logs errors, but just in case
                        ExceptionLogService.LogException(ex);
                    }
                }
            });
        }
Exemplo n.º 13
0
        /// <summary>
        /// Called by the <see cref="IScheduler"/> after a <see cref="IJobDetail"/>
        /// has been executed, and before the associated <see cref="Quartz.Spi.IOperableTrigger"/>'s
        /// <see cref="Quartz.Spi.IOperableTrigger.Triggered"/> method has been called.
        /// </summary>
        /// <param name="context"></param>
        /// <param name="jobException"></param>
        public void JobWasExecuted( IJobExecutionContext context, JobExecutionException jobException )
        {
            StringBuilder message = new StringBuilder();
            bool sendMessage = false;
            
            // get job type id
            int jobId = Convert.ToInt16(context.JobDetail.Description);

            // load job
            ServiceJobService jobService = new ServiceJobService();
            ServiceJob job = jobService.Get(jobId);
            
            // format the message
            message.Append( String.Format( "The job {0} ran for {1} seconds on {2}.  Below is the results:<p>" , job.Name, context.JobRunTime.TotalSeconds, context.FireTimeUtc.Value.DateTime.ToLocalTime()) );

            // if noticiation staus is all set flag to send message
            if ( job.NotificationStatus == JobNotificationStatus.All )
                sendMessage = true;

            // set last run date
            job.LastRunDateTime = context.FireTimeUtc.Value.DateTime.ToLocalTime();

            // set run time
            job.LastRunDurationSeconds = Convert.ToInt32(context.JobRunTime.TotalSeconds);

            // set the scheduler name
            job.LastRunSchedulerName = context.Scheduler.SchedulerName;

            // determine if an error occured
            if ( jobException == null )
            {
                job.LastSuccessfulRunDateTime = job.LastRunDateTime;
                job.LastStatus = "Success";
                job.LastStatusMessage = "";
                
                message.Append( "Result: Success" );

                // determine if message should be sent
                if ( job.NotificationStatus == JobNotificationStatus.Success )
                    sendMessage = true;
            }
            else
            {
                // put the exception into the status
                job.LastStatus = "Exception";
                job.LastStatusMessage = jobException.Message;

                message.Append( "Result: Exception<p>Message:<br>" + jobException.Message );

                if ( jobException.InnerException != null ) {
                    job.LastStatusMessage += " Inner Exception: " + jobException.InnerException.Message;
                    message.Append( "<p>Inner Exception:<br>" + jobException.InnerException.Message );
                }

                if ( job.NotificationStatus == JobNotificationStatus.Error )
                    sendMessage = true;
            }

            jobService.Save( job, null );

            // send notification
            if ( sendMessage )
            {
                // TODO: implement email send once it's available 
            }


        }