public void ApplicationCoordinatorRefreshAdd() { ApplicationElement element1 = new ApplicationElement() { ApplicationPath = ApplicationUtils.CreateValidExampleApplication(), Framework = Framework }; ApplicationElement element2 = new ApplicationElement() { ApplicationPath = ApplicationUtils.CreateValidExampleApplication(), Framework = Framework }; ApplicationElement element3 = new ApplicationElement() { ApplicationPath = ApplicationUtils.CreateValidExampleApplication(), Framework = Framework }; using (ApplicationCoordinator coordinator = new ApplicationCoordinator(Logger, Path.GetFullPath("Collar.exe"))) { coordinator.StartAndRefresh(new ApplicationElement[] { element1, element2 }); Assert.IsTrue(coordinator.IsRunning); var paths = coordinator.GetCoordinatedApplicationPaths(); Assert.AreEqual(2, coordinator.Count); Assert.IsTrue(paths.Contains(element1.ApplicationPath)); Assert.IsTrue(paths.Contains(element2.ApplicationPath)); coordinator.StartAndRefresh(new ApplicationElement[] { element1, element2, element3 }); Assert.IsTrue(coordinator.IsRunning); paths = coordinator.GetCoordinatedApplicationPaths(); Assert.AreEqual(3, coordinator.Count); Assert.IsTrue(paths.Contains(element1.ApplicationPath)); Assert.IsTrue(paths.Contains(element2.ApplicationPath)); Assert.IsTrue(paths.Contains(element3.ApplicationPath)); } }
/// <summary> /// Gets a collection of application elements from the configuration. /// </summary> /// <returns>A collection of application elements.</returns> private static IEnumerable <ApplicationElement> GetApplicationElements() { IEnumerable <ApplicationElement> applications; try { BlueCollarServiceSection.Refresh(); applications = BlueCollarServiceSection.Section.Applications; } catch (ConfigurationErrorsException ex) { Logger.ErrorException("The configuration file is invalid. Please edit the configuration and re-save the file in order to load updated configuration information.", ex); applications = new ApplicationElement[0]; } return(applications); }
/// <summary> /// Sets the given application's configurable properties from the given configuration element. /// </summary> /// <param name="application">The application to initialize.</param> /// <param name="element">The configuration element to initialize the application from.</param> /// <returns>True if the application was initialized successfully, false otherwise.</returns> private bool SetApplicationProperties(ApplicationProcess application, ApplicationElement element) { bool success = true; application.Force32Bit = element.Force32Bit; try { application.ConfigPath = element.ApplicationConfigPath; } catch (ArgumentException ex) { success = false; this.logger.Error( new ConfigurationErrorsException( "The value for 'configPath' contains invalid characters.", ex, element.ElementInformation.Source, element.ElementInformation.LineNumber)); } try { application.FrameworkVersion = element.Framework; } catch (ArgumentException ex) { success = false; this.logger.Error( new ConfigurationErrorsException( "The value for 'framework' must be one of: '3.5', '4.0'.", ex, element.ElementInformation.Source, element.ElementInformation.LineNumber)); } return(success); }
private void CreateRefreshAndPruneApplications(IEnumerable <ApplicationElement> elements) { List <ApplicationProcess> pruning = this.applications .Where(a => !elements.Any(e => a.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase))) .ToList(); List <ApplicationProcess> existing = this.applications .Where(a => elements.Any(e => a.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase))) .ToList(); List <ApplicationElement> creating = elements .Where(e => !this.applications.Any(a => e.ApplicationPath.Equals(a.Path, StringComparison.OrdinalIgnoreCase))) .ToList(); // Prune removed applications. foreach (ApplicationProcess application in pruning) { application.Exited -= new EventHandler(this.ApplicationExited); application.Stop(true); application.Dispose(); } // Stop and re-initialize changed applications. foreach (ApplicationProcess application in existing) { ApplicationElement element = elements.Where(e => application.Path.Equals(e.ApplicationPath, StringComparison.OrdinalIgnoreCase)).First(); if (!(application.ConfigPath ?? string.Empty).Equals(element.ApplicationConfigPath, StringComparison.OrdinalIgnoreCase) || application.Force32Bit != element.Force32Bit || application.FrameworkVersion != element.Framework) { if (this.SetApplicationProperties(application, element)) { application.Stop(true); } } } // Create added applications. foreach (ApplicationElement element in creating) { ApplicationProcess application = null; try { try { application = new ApplicationProcess(this.logger, element.ApplicationPath, this.exePath); } catch (ArgumentException ex) { this.logger.Error( new ConfigurationErrorsException( "The value for 'path' contains invalid characters.", ex, element.ElementInformation.Source, element.ElementInformation.LineNumber)); } if (application != null) { application.Exited += new EventHandler(this.ApplicationExited); if (this.SetApplicationProperties(application, element)) { existing.Add(application); } } } catch { if (application != null) { application.Dispose(); } throw; } } lock (this.locker) { this.applications = existing; } }
/// <summary> /// Sets the given application's configurable properties from the given configuration element. /// </summary> /// <param name="application">The application to initialize.</param> /// <param name="element">The configuration element to initialize the application from.</param> /// <returns>True if the application was initialized successfully, false otherwise.</returns> private bool SetApplicationProperties(ApplicationProcess application, ApplicationElement element) { bool success = true; application.Force32Bit = element.Force32Bit; try { application.ConfigPath = element.ApplicationConfigPath; } catch (ArgumentException ex) { success = false; this.logger.Error( new ConfigurationErrorsException( "The value for 'configPath' contains invalid characters.", ex, element.ElementInformation.Source, element.ElementInformation.LineNumber)); } try { application.FrameworkVersion = element.Framework; } catch (ArgumentException ex) { success = false; this.logger.Error( new ConfigurationErrorsException( "The value for 'framework' must be one of: '3.5', '4.0'.", ex, element.ElementInformation.Source, element.ElementInformation.LineNumber)); } return success; }
/// <summary> /// Gets a collection of application elements from the configuration. /// </summary> /// <returns>A collection of application elements.</returns> private static IEnumerable<ApplicationElement> GetApplicationElements() { IEnumerable<ApplicationElement> applications; try { BlueCollarServiceSection.Refresh(); applications = BlueCollarServiceSection.Section.Applications; } catch (ConfigurationErrorsException ex) { Logger.ErrorException("The configuration file is invalid. Please edit the configuration and re-save the file in order to load updated configuration information.", ex); applications = new ApplicationElement[0]; } return applications; }
/// <summary> /// Resolves the running jobs persistence path to use for the given application. /// </summary> /// <param name="element">The application element to resolve the running jobs persistence path for.</param> /// <returns>A resolved persistence path.</returns> private static string ResolvePersistencePath(ApplicationElement element) { return Path.GetFullPath(Path.Combine(Path.Combine(CurrentDirectory, "Persistence"), String.Concat(FileNameExpression.Replace(element.Name, String.Empty), ".bin"))); }
/// <summary> /// Resolves the log path for the application identified by the given configuration element. /// </summary> /// <param name="element">The configuration element to resolve the log path for.</param> /// <returns>A resolved log path.</returns> private static string ResolveLogPath(ApplicationElement element) { string path = element.LogFile; if (!String.IsNullOrEmpty(path)) { if (!Path.IsPathRooted(path)) { path = Path.Combine(CurrentDirectory, path); } } else { path = Path.Combine(Path.Combine(CurrentDirectory, "Logs"), String.Concat(FileNameExpression.Replace(element.Name, String.Empty), ".log")); } return Path.GetFullPath(path); }