Beispiel #1
0
 /// <summary>
 /// Copies the properties from another ServiceJob object to this ServiceJob object
 /// </summary>
 /// <param name="target">The target.</param>
 /// <param name="source">The source.</param>
 public static void CopyPropertiesFrom(this ServiceJob target, ServiceJob source)
 {
     target.Id                        = source.Id;
     target.Assembly                  = source.Assembly;
     target.Class                     = source.Class;
     target.CronExpression            = source.CronExpression;
     target.Description               = source.Description;
     target.EnableHistory             = source.EnableHistory;
     target.ForeignGuid               = source.ForeignGuid;
     target.ForeignKey                = source.ForeignKey;
     target.HistoryCount              = source.HistoryCount;
     target.IsActive                  = source.IsActive;
     target.IsSystem                  = source.IsSystem;
     target.LastRunDateTime           = source.LastRunDateTime;
     target.LastRunDurationSeconds    = source.LastRunDurationSeconds;
     target.LastRunSchedulerName      = source.LastRunSchedulerName;
     target.LastStatus                = source.LastStatus;
     target.LastStatusMessage         = source.LastStatusMessage;
     target.LastSuccessfulRunDateTime = source.LastSuccessfulRunDateTime;
     target.Name                      = source.Name;
     target.NotificationEmails        = source.NotificationEmails;
     target.NotificationStatus        = source.NotificationStatus;
     target.CreatedDateTime           = source.CreatedDateTime;
     target.ModifiedDateTime          = source.ModifiedDateTime;
     target.CreatedByPersonAliasId    = source.CreatedByPersonAliasId;
     target.ModifiedByPersonAliasId   = source.ModifiedByPersonAliasId;
     target.Guid                      = source.Guid;
     target.ForeignId                 = source.ForeignId;
 }
Beispiel #2
0
        /// <summary>
        /// Builds a Quartz Job for a specified <see cref="Rock.Model.ServiceJob">Job</see>
        /// </summary>
        /// <param name="job">The <see cref="Rock.Model.ServiceJob"/> to create a Quarts Job for.</param>
        /// <returns>A object that implements the <see cref="Quartz.IJobDetail"/> interface</returns>
        public IJobDetail BuildQuartzJob(ServiceJob job)
        {
            // build the type object, will depend if the class is in an assembly or the App_Code folder
            Type type = null;

            if (job.Assembly == string.Empty || job.Assembly == null)
            {
                type = BuildManager.GetType(job.Class, false);
            }
            else
            {
                string thetype = string.Format("{0}, {1}", job.Class, job.Assembly);
                type = Type.GetType(thetype);
            }

            // load up job attributes (parameters)
            job.LoadAttributes();

            JobDataMap map = new JobDataMap();

            foreach (KeyValuePair <string, List <Rock.Model.AttributeValue> > attrib in job.AttributeValues)
            {
                map.Add(attrib.Key, attrib.Value[0].Value);
            }

            // create the quartz job object
            IJobDetail jobDetail = JobBuilder.Create(type)
                                   .WithDescription(job.Id.ToString())
                                   .WithIdentity(new Guid().ToString(), job.Name)
                                   .UsingJobData(map)
                                   .Build();

            return(jobDetail);
        }
Beispiel #3
0
        /// <summary>
        /// To the model.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <returns></returns>
        public static ServiceJob ToModel(this ServiceJobDto value)
        {
            ServiceJob result = new ServiceJob();

            value.CopyToModel(result);
            return(result);
        }
Beispiel #4
0
        /// <summary>
        /// Builds a Quartz schedule trigger
        /// </summary>
        /// <param name="job">The <see cref="Rock.Model.ServiceJob">Job</see> to create a <see cref="Quartz.ITrigger"/> compatible Trigger.</param>
        /// <returns>A Quartz trigger that implements <see cref="Quartz.ITrigger"/> for the specified job.</returns>
        public ITrigger BuildQuartzTrigger(ServiceJob job)
        {
            // create quartz trigger
            ITrigger trigger = ( ICronTrigger )TriggerBuilder.Create()
                               .WithIdentity(new Guid().ToString(), job.Name)
                               .WithCronSchedule(job.CronExpression)
                               .StartNow()
                               .Build();

            return(trigger);
        }
Beispiel #5
0
 /// <summary>
 /// Clones this ServiceJob object to a new ServiceJob object
 /// </summary>
 /// <param name="source">The source.</param>
 /// <param name="deepCopy">if set to <c>true</c> a deep copy is made. If false, only the basic entity properties are copied.</param>
 /// <returns></returns>
 public static ServiceJob Clone(this ServiceJob source, bool deepCopy)
 {
     if (deepCopy)
     {
         return(source.Clone() as ServiceJob);
     }
     else
     {
         var target = new ServiceJob();
         target.CopyPropertiesFrom(source);
         return(target);
     }
 }
Beispiel #6
0
        /// <summary>
        /// Builds a Quartz schedule trigger
        /// </summary>
        /// <param name="job">The <see cref="Rock.Model.ServiceJob">Job</see> to create a <see cref="Quartz.ITrigger"/> compatible Trigger.</param>
        /// <returns>A Quartz trigger that implements <see cref="Quartz.ITrigger"/> for the specified job.</returns>
        public ITrigger BuildQuartzTrigger(ServiceJob job)
        {
            // create quartz trigger
            ITrigger trigger = (ICronTrigger)TriggerBuilder.Create()
                               .WithIdentity(job.Guid.ToString(), job.Name)
                               .WithCronSchedule(job.CronExpression, x => {
                x.InTimeZone(RockDateTime.OrgTimeZoneInfo);
                x.WithMisfireHandlingInstructionDoNothing();
            })
                               .StartNow()
                               .Build();

            return(trigger);
        }
Beispiel #7
0
        /// <summary>
        /// Builds a Quartz Job for a specified <see cref="Rock.Model.ServiceJob">Job</see>
        /// </summary>
        /// <param name="job">The <see cref="Rock.Model.ServiceJob"/> to create a Quarts Job for.</param>
        /// <returns>A object that implements the <see cref="Quartz.IJobDetail"/> interface</returns>
        public IJobDetail BuildQuartzJob(ServiceJob job)
        {
            // build the type object, will depend if the class is in an assembly or the App_Code folder
            Type type = null;

            if (string.IsNullOrWhiteSpace(job.Assembly))
            {
                // first, if no assembly is known, look in all the dlls for it
                type = Rock.Reflection.FindType(typeof(Quartz.IJob), job.Class);

                if (type == null)
                {
                    // if it can't be found in dlls, look in App_Code using BuildManager
                    type = BuildManager.GetType(job.Class, false);
                }
            }
            else
            {
                // if an assembly is specified, load the type from that
                string thetype = string.Format("{0}, {1}", job.Class, job.Assembly);
                type = Type.GetType(thetype);
            }

            int?jobEntityTypeId = Rock.Web.Cache.EntityTypeCache.Get("Rock.Model.ServiceJob").Id;

            Rock.Attribute.Helper.UpdateAttributes(type, jobEntityTypeId, "Class", type.FullName);

            // load up job attributes (parameters)
            job.LoadAttributes();

            JobDataMap map = new JobDataMap();

            foreach (var attrib in job.AttributeValues)
            {
                map.Add(attrib.Key, attrib.Value.Value);
            }

            // create the quartz job object
            IJobDetail jobDetail = JobBuilder.Create(type)
                                   .WithDescription(job.Id.ToString())
                                   .WithIdentity(job.Guid.ToString(), job.Name)
                                   .UsingJobData(map)
                                   .Build();

            return(jobDetail);
        }
        /// <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();
        }
Beispiel #9
0
        /// <summary>
        /// Builds a Quartz Job for a specified <see cref="Rock.Model.ServiceJob">Job</see>
        /// </summary>
        /// <param name="job">The <see cref="Rock.Model.ServiceJob"/> to create a Quarts Job for.</param>
        /// <returns>A object that implements the <see cref="Quartz.IJobDetail"/> interface</returns>
        public IJobDetail BuildQuartzJob(ServiceJob job)
        {
            // build the type object, will depend if the class is in an assembly or the App_Code folder
            Type type = null;

            if (string.IsNullOrWhiteSpace(job.Assembly))
            {
                // first try to load the job type from the App_Code folder
                type = BuildManager.GetType(job.Class, false);

                if (type == null)
                {
                    // if it couldn't be loaded from the app_code folder, look in Rock.dll
                    string thetype = string.Format("{0}, {1}", job.Class, this.GetType().Assembly.FullName);
                    type = Type.GetType(thetype);
                }
            }
            else
            {
                // if an assembly is specified, load the type from that
                string thetype = string.Format("{0}, {1}", job.Class, job.Assembly);
                type = Type.GetType(thetype);
            }

            // load up job attributes (parameters)
            job.LoadAttributes();

            JobDataMap map = new JobDataMap();

            foreach (var attrib in job.AttributeValues)
            {
                map.Add(attrib.Key, attrib.Value.Value);
            }

            // create the quartz job object
            IJobDetail jobDetail = JobBuilder.Create(type)
                                   .WithDescription(job.Id.ToString())
                                   .WithIdentity(job.Guid.ToString(), job.Name)
                                   .UsingJobData(map)
                                   .Build();

            return(jobDetail);
        }
Beispiel #10
0
 /// <summary>
 /// Copies the properties from another ServiceJob object to this ServiceJob object
 /// </summary>
 /// <param name="target">The target.</param>
 /// <param name="source">The source.</param>
 public static void CopyPropertiesFrom(this ServiceJob target, ServiceJob source)
 {
     target.IsSystem                  = source.IsSystem;
     target.IsActive                  = source.IsActive;
     target.Name                      = source.Name;
     target.Description               = source.Description;
     target.Assembly                  = source.Assembly;
     target.Class                     = source.Class;
     target.CronExpression            = source.CronExpression;
     target.LastSuccessfulRunDateTime = source.LastSuccessfulRunDateTime;
     target.LastRunDateTime           = source.LastRunDateTime;
     target.LastRunDurationSeconds    = source.LastRunDurationSeconds;
     target.LastStatus                = source.LastStatus;
     target.LastStatusMessage         = source.LastStatusMessage;
     target.LastRunSchedulerName      = source.LastRunSchedulerName;
     target.NotificationEmails        = source.NotificationEmails;
     target.NotificationStatus        = source.NotificationStatus;
     target.Id   = source.Id;
     target.Guid = source.Guid;
 }
        /// <summary>
        /// Schedules the Job to run immediately using the Quartz Scheduler
        /// and waits for the job to finish.
        /// Returns <c>false</c> with an <c>out</c> <paramref name="errorMessage"/> if the job is already running as a RunNow job or if an exception occurs.
        /// NOTE: This will take at least 10 seconds to ensure the Quartz scheduler successfully started the job, plus any additional time that might
        /// still be needed to complete the job.
        /// </summary>
        /// <param name="job">The job.</param>
        /// <param name="errorMessage">The error message.</param>
        /// <returns></returns>
        public bool RunNow(ServiceJob job, out string errorMessage)
        {
            // use a new RockContext instead of using this.Context so we can SaveChanges without affecting other RockContext's with pending changes.
            var rockContext = new RockContext();

            errorMessage = string.Empty;
            try
            {
                // create a scheduler specific for the job
                var scheduleConfig = new NameValueCollection();

                var jobId = job.Id;

                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
                    errorMessage = "Job already running as a RunNow job";
                    return(false);
                }

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

                    foreach (var scheduler in otherSchedulers)
                    {
                        var isAlreadyRunning = scheduler.GetCurrentlyExecutingJobs()
                                               .Where(j =>
                                                      j.JobDetail.Description == jobId.ToString() &&
                                                      j.JobDetail.ConcurrentExectionDisallowed)
                                               .Any();

                        if (isAlreadyRunning)
                        {
                            // A job with that Id is already running and ConcurrentExectionDisallowed is true
                            errorMessage = $" Scheduler '{scheduler.SchedulerName}' is already executing job Id '{jobId}' (name: {job.Name})";
                            System.Diagnostics.Debug.WriteLine($"{RockDateTime.Now.ToString()} {errorMessage}");
                            return(false);
                        }
                    }
                }
                catch
                {
                    // Was blank in the RunJobNowTransaction (intentional?)
                }

                // create the quartz job and trigger
                var jobDetail  = new ServiceJobService(rockContext).BuildQuartzJob(job);
                var jobDataMap = jobDetail.JobDataMap;

                if (jobDataMap != 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(jobDataMap.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 scheduler to start the job.
                // If we don't do this, the scheduler might Shutdown thinking there are no running jobs
                Task.Delay(10 * 1000).Wait();

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

                return(true);
            }
            catch (Exception ex)
            {
                // create a friendly error message
                ExceptionLogService.LogException(ex, null);
                errorMessage          = string.Format("Error doing a 'Run Now' on job: {0}. \n\n{2}", job.Name, job.Assembly, ex.Message);
                job.LastStatusMessage = errorMessage;
                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();

                return(false);
            }
        }
Beispiel #12
0
 /// <summary>
 /// To the dto.
 /// </summary>
 /// <param name="value">The value.</param>
 /// <returns></returns>
 public static ServiceJobDto ToDto(this ServiceJob value)
 {
     return(new ServiceJobDto(value));
 }
Beispiel #13
0
 /// <summary>
 /// Instantiates a new DTO object from the entity
 /// </summary>
 /// <param name="serviceJob"></param>
 public ServiceJobDto(ServiceJob serviceJob)
 {
     CopyFromModel(serviceJob);
 }