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(); }
/// <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 ) { if ( activeJob.CronExpression != jobCronTrigger.CronExpressionString ) { ITrigger newJobTrigger = jobService.BuildQuartzTrigger( activeJob ); scheduler.RescheduleJob( jobCronTrigger.Key, newJobTrigger ); } } } } }
/// <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 ) { System.Diagnostics.Debug.WriteLine( string.Format( "Application_Start: {0}", DateTime.Now.ToString("hh:mm:ss.FFF" ) )); } // 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, null ); } } 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 ); } if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { new AttributeService().Get( 0 ); System.Diagnostics.Debug.WriteLine( string.Format( "ConnectToDatabase - Connected: {0}", DateTime.Now.ToString( "hh:mm:ss.FFF" ) ) ); } // Preload the commonly used objects LoadCacheObjects(); if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { System.Diagnostics.Debug.WriteLine( string.Format( "LoadCacheObjects - Done: {0}", DateTime.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(); 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 ); }
/// <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(); }
/// <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 ); } }
/// <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(); }
/// <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 { DateTime startDateTime = RockDateTime.Now; if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { System.Diagnostics.Debug.WriteLine( string.Format( "Application_Start: {0}", RockDateTime.Now.ToString( "hh:mm:ss.FFF" ) ) ); } // Temporary code for v1.0.9 to delete payflowpro files in old location (The current update is not able to delete them, but 1.0.9 installs a fix for that) // This should be removed after 1.0.9 try { string physicalFile = System.Web.HttpContext.Current.Server.MapPath( @"~\Plugins\Payflow_dotNET.dll" ); if ( System.IO.File.Exists( physicalFile ) ) { System.IO.File.Delete( physicalFile ); } physicalFile = System.Web.HttpContext.Current.Server.MapPath( @"~\Plugins\Rock.PayFlowPro.dll" ); if ( System.IO.File.Exists( physicalFile ) ) { System.IO.File.Delete( physicalFile ); } } catch { // Intentionally Blank } // Get a db context var rockContext = new RockContext(); //// 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 ); if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { try { new AttributeService( rockContext ).Get( 0 ); System.Diagnostics.Debug.WriteLine( string.Format( "ConnectToDatabase - {0} ms", ( RockDateTime.Now - startDateTime ).TotalMilliseconds ) ); startDateTime = RockDateTime.Now; } catch { // Intentionally Blank } } RegisterRoutes( rockContext, RouteTable.Routes ); // Preload the commonly used objects LoadCacheObjects( rockContext ); if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { System.Diagnostics.Debug.WriteLine( string.Format( "LoadCacheObjects - {0} ms", ( RockDateTime.Now - startDateTime ).TotalMilliseconds ) ); startDateTime = RockDateTime.Now; } // 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(); GlobalConfiguration.Configuration.EnableCors( new Rock.Rest.EnableCorsFromOriginAttribute() ); 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 ); } }
/// <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 { LogMessage( APP_LOG_FILENAME, "Application Starting..." ); DateTime startDateTime = RockDateTime.Now; 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() ) { //// 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 LoadCacheObjects( rockContext ); // Run any plugin migrations MigratePlugins( rockContext ); if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { try { new AttributeService( rockContext ).Get( 0 ); System.Diagnostics.Debug.WriteLine( string.Format( "ConnectToDatabase - {0} ms", ( RockDateTime.Now - startDateTime ).TotalMilliseconds ) ); startDateTime = RockDateTime.Now; } catch { // Intentionally Blank } } RegisterRoutes( rockContext, RouteTable.Routes ); // Configure Rock Rest API GlobalConfiguration.Configure( Rock.Rest.WebApiConfig.Register ); if ( System.Web.Hosting.HostingEnvironment.IsDevelopmentEnvironment ) { System.Diagnostics.Debug.WriteLine( string.Format( "LoadCacheObjects - {0} ms", ( RockDateTime.Now - startDateTime ).TotalMilliseconds ) ); startDateTime = RockDateTime.Now; } // 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(); } // 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 Succesfully" ); } catch (Exception ex) { SetError66(); throw ( new Exception( "Error occurred during application startup", ex ) ); } }
/// <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 ); } }
/// <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(); }
/// <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(); // If not migrating, set up view cache to speed up startup (Not supported when running migrations). var fileInfo = new FileInfo( Server.MapPath( "~/App_Data/Run.Migration" ) ); if ( !fileInfo.Exists ) { RockInteractiveViews.SetViewFactory( Server.MapPath( "~/App_Data/RockModelViews.xml" ) ); } // 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(); } // set the encryption protocols that are permissible for external SSL connections System.Net.ServicePointManager.SecurityProtocol = System.Net.SecurityProtocolType.Tls | System.Net.SecurityProtocolType.Tls11 | System.Net.SecurityProtocolType.Tls12; // 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 ) ); } // Update attributes for new workflow actions new Thread( () => { Rock.Workflow.ActionContainer.Instance.UpdateAttributes(); } ).Start(); // compile less files new Thread( () => { Thread.CurrentThread.IsBackground = true; RockTheme.CompileAll(); } ).Start(); }