예제 #1
0
        protected SharedServiceControlEditorViewModelValidator()
        {
            ServiceControlInstances = InstanceFinder.ServiceControlInstances();

            RuleFor(x => x.InstanceName)
            .NotEmpty()
            .MustNotContainWhitespace()
            .When(x => x.SubmitAttempted);

            RuleFor(x => x.HostName)
            .NotEmpty().When(x => x.SubmitAttempted);

            RuleFor(x => x.PortNumber)
            .NotEmpty()
            .ValidPort()
            .MustNotBeIn(x => UsedPorts(x.InstanceName))
            .WithMessage(Validations.MSG_MUST_BE_UNIQUE, "Ports")
            .When(x => x.SubmitAttempted);

            RuleFor(x => x.LogPath)
            .NotEmpty()
            .ValidPath()
            .MustNotBeIn(x => UsedPaths(x.InstanceName))
            .WithMessage(Validations.MSG_MUST_BE_UNIQUE, "Paths")
            .When(x => x.SubmitAttempted);
        }
예제 #2
0
        public static List <string> UsedPorts(string instanceName = null)
        {
            var monitoringInstances          = InstanceFinder.MonitoringInstances();
            var serviceControlAuditInstances = InstanceFinder.ServiceControlAuditInstances();
            var serviceControlInstances      = InstanceFinder.ServiceControlInstances();
            var result = new List <string>();

            result.AddRange(monitoringInstances
                            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                            .Select(p => p.Port.ToString()));

            result.AddRange(serviceControlInstances
                            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                            .SelectMany(p => new[]
            {
                p.Port.ToString(),
                p.DatabaseMaintenancePort.ToString()
            }));

            result.AddRange(serviceControlAuditInstances
                            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                            .SelectMany(p => new[]
            {
                p.Port.ToString(),
                p.DatabaseMaintenancePort.ToString()
            }));

            return(result.Distinct().ToList());
        }
예제 #3
0
        public static List <string> UsedPaths(string instanceName = null)
        {
            var monitoringInstances          = InstanceFinder.MonitoringInstances();
            var serviceControlAuditInstances = InstanceFinder.ServiceControlAuditInstances();
            var serviceControlInstances      = InstanceFinder.ServiceControlInstances();
            var result = new List <string>();

            result.AddRange(monitoringInstances
                            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                            .SelectMany(p => new[]
            {
                p.LogPath,
                p.InstallPath
            }));

            result.AddRange(serviceControlAuditInstances
                            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                            .SelectMany(p => new[]
            {
                p.LogPath,
                p.DBPath,
                p.InstallPath
            }));

            result.AddRange(serviceControlInstances
                            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                            .SelectMany(p => new[]
            {
                p.LogPath,
                p.DBPath,
                p.InstallPath
            }));

            return(result.Distinct().ToList());
        }
예제 #4
0
        public void ChangeConfigTests()
        {
            var logger    = new TestLogger();
            var installer = new UnattendServiceControlInstaller(logger, DeploymentCache);

            logger.Info("Deleting instances");
            DeleteInstance();

            logger.Info("Removing the test queue instances");
            RemoveAltMSMQQueues();

            logger.Info("Recreating the MSMQ instance");
            CreateInstanceMSMQ();

            logger.Info("Changing the URLACL");
            var msmqTestInstance = InstanceFinder.ServiceControlInstances().First(p => p.Name.Equals("Test.ServiceControl.MSMQ", StringComparison.OrdinalIgnoreCase));

            msmqTestInstance.HostName = Environment.MachineName;
            msmqTestInstance.Port     = 33338;
            installer.Update(msmqTestInstance, true);
            Assert.IsTrue(msmqTestInstance.Service.Status == ServiceControllerStatus.Running, "Update URL change failed");

            logger.Info("Changing LogPath");
            msmqTestInstance         = InstanceFinder.ServiceControlInstances().First(p => p.Name.Equals("Test.ServiceControl.MSMQ", StringComparison.OrdinalIgnoreCase));
            msmqTestInstance.LogPath = @"c:\temp\testloggingchange";
            installer.Update(msmqTestInstance, true);
            Assert.IsTrue(msmqTestInstance.Service.Status == ServiceControllerStatus.Running, "Update Logging changed failed");

            logger.Info("Updating Queue paths");
            msmqTestInstance            = InstanceFinder.ServiceControlInstances().First(p => p.Name.Equals("Test.ServiceControl.MSMQ", StringComparison.OrdinalIgnoreCase));
            msmqTestInstance.AuditQueue = "alternateAudit";
            msmqTestInstance.ErrorQueue = "alternateError";
            installer.Update(msmqTestInstance, true);
            Assert.IsTrue(msmqTestInstance.Service.Status == ServiceControllerStatus.Running, "Update Queues changed failed");
        }
예제 #5
0
        public static ActionResult ServiceControlInstanceCount(Session session)
        {
            var instanceCount = InstanceFinder.ServiceControlInstances().Count +
                                InstanceFinder.MonitoringInstances().Count;

            session["SCINSTANCECOUNT"] = instanceCount.ToString();
            return(ActionResult.Success);
        }
예제 #6
0
        public static void Validate(ServiceControlInstance instance)
        {
            var validator = new ServiceControlQueueNameValidator(instance)
            {
                Instances = InstanceFinder.ServiceControlInstances().Where(p => p.Name != instance.Name & p.TransportPackage.Equals(instance.TransportPackage, StringComparison.OrdinalIgnoreCase)).AsEnumerable <IServiceControlTransportConfig>().ToList()
            };

            validator.RunValidation();
        }
예제 #7
0
        public void DeleteInstance()
        {
            var installer = new UnattendServiceControlInstaller(new TestLogger(), DeploymentCache);

            foreach (var instance in InstanceFinder.ServiceControlInstances().Where(p => p.Name.StartsWith("Test.ServiceControl", StringComparison.OrdinalIgnoreCase)))
            {
                installer.Delete(instance.Name, true, true);
            }
        }
        public static void Validate(IServiceControlAuditInstance instance)
        {
            var validator = new QueueNameValidator(instance)
            {
                SCInstances    = InstanceFinder.ServiceControlInstances().Where(p => p.Name != instance.Name & p.TransportPackage.Equals(instance.TransportPackage)).AsEnumerable <IServiceControlInstance>().ToList(),
                AuditInstances = InstanceFinder.ServiceControlAuditInstances().Where(p => p.Name != instance.Name & p.TransportPackage.Equals(instance.TransportPackage)).AsEnumerable <IServiceControlAuditInstance>().ToList(),
            };

            validator.RunValidation();
        }
            public MaintenancePortValidator()
            {
                ServiceControlInstances = InstanceFinder.ServiceControlInstances();

                RuleFor(x => x.Value)
                .NotEmpty()
                .ValidPort()
                .MustNotBeIn(x => UsedPorts())
                .WithMessage(Validations.MSG_MUST_BE_UNIQUE, "Ports");
            }
예제 #10
0
        public void UpgradeInstance()
        {
            var installer = new UnattendServiceControlInstaller(new TestLogger(), DeploymentCache);

            foreach (var instance in InstanceFinder.ServiceControlInstances().Where(p => p.Name.StartsWith("Test.ServiceControl", StringComparison.OrdinalIgnoreCase)))
            {
                installer.Upgrade(instance, new ServiceControlUpgradeOptions {
                    AuditRetentionPeriod = TimeSpan.FromDays(30), ErrorRetentionPeriod = TimeSpan.FromDays(15), OverrideEnableErrorForwarding = true
                });
            }
        }
예제 #11
0
 // We need this to ignore the instance that represents the edit screen
 protected List <string> UsedPorts(string instanceName = null)
 {
     return(InstanceFinder.ServiceControlInstances()
            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
            .SelectMany(p => new[]
     {
         p.Port.ToString(),
         p.DatabaseMaintenancePort.ToString()
     })
            .Distinct()
            .ToList());
 }
예제 #12
0
 // We need this to ignore the instance that represents the edit screen
 protected List <string> UsedPaths(string instanceName = null)
 {
     return(InstanceFinder.ServiceControlInstances()
            .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
            .SelectMany(p => new[]
     {
         p.DBPath,
         p.LogPath,
         p.InstallPath
     })
            .Distinct()
            .ToList());
 }
예제 #13
0
        // We need this to ignore the instance that represents the edit screen
        public static List <string> UsedErrorQueueNames(TransportInfo transportInfo = null, string instanceName = null, string connectionString = null)
        {
            var serviceControlInstances = InstanceFinder.ServiceControlInstances();
            var instancesByTransport    = serviceControlInstances.Where(p => p.TransportPackage.Equals(transportInfo) &&
                                                                        string.Equals(p.ConnectionString, connectionString, StringComparison.OrdinalIgnoreCase)).ToList();

            return(instancesByTransport
                   .Where(p => string.IsNullOrWhiteSpace(instanceName) || p.Name != instanceName)
                   .SelectMany(p => new[]
            {
                p.ErrorLogQueue,
                p.ErrorQueue
            }).Where(queuename => string.Compare(queuename, "!disable", StringComparison.OrdinalIgnoreCase) != 0 &&
                     string.Compare(queuename, "!disable.log", StringComparison.OrdinalIgnoreCase) != 0)
                   .Distinct()
                   .ToList());
        }
        protected int GetInstalledInstancesCount()
        {
            var serviceControlInstances = InstanceFinder.ServiceControlInstances();

            if (!serviceControlInstances.Any())
            {
                return(0);
            }

            var i = 0;

            while (true)
            {
                i++;
                if (!serviceControlInstances.Any(p => p.Name.Equals(InstanceName, StringComparison.OrdinalIgnoreCase)))
                {
                    return(i);
                }
            }
        }
        public void CreateAService()
        {
            var s = new WindowsServiceDetails
            {
                ImagePath         = @"C:\Program Files (x86)\Particular Software\ServiceControl\ServiceControl.exe  --serviceName=Test.SC",
                DisplayName       = "Test SC",
                Name              = "Test.SC",
                ServiceAccount    = @"NT Authority\NetworkService",
                ServiceAccountPwd = null
            };

            var existing = InstanceFinder.ServiceControlInstances().FirstOrDefault(p => p.Name == s.Name);

            if (existing != null)
            {
                InstanceFinder.ServiceControlInstances().First(p => p.Name == s.Name).Service.Delete();
            }
            WindowsServiceController.RegisterNewService(s);
            InstanceFinder.ServiceControlInstances().First(p => p.Name == s.Name).Service.Delete();
        }
예제 #16
0
        public ServiceControlAddViewModel()
        {
            DisplayName = "ADD SERVICECONTROL INSTANCE";

            SelectDestinationPath = new SelectPathCommand(p => DestinationPath = p, isFolderPicker: true, defaultPath: DestinationPath);
            SelectDatabasePath    = new SelectPathCommand(p => DatabasePath = p, isFolderPicker: true, defaultPath: DatabasePath);
            SelectLogPath         = new SelectPathCommand(p => LogPath = p, isFolderPicker: true, defaultPath: LogPath);

            var serviceControlInstances = InstanceFinder.ServiceControlInstances();

            if (!serviceControlInstances.Any())
            {
                InstanceName = "Particular.ServiceControl";
                PortNumber   = "33333";
                DatabaseMaintenancePortNumber = "33334";
            }
            else
            {
                var i = 0;
                while (true)
                {
                    InstanceName = $"Particular.ServiceControl.{++i}";
                    if (!serviceControlInstances.Any(p => p.Name.Equals(InstanceName, StringComparison.OrdinalIgnoreCase)))
                    {
                        break;
                    }
                }
            }

            AuditRetention           = SettingConstants.AuditRetentionPeriodDefaultInHoursForUI;
            ErrorRetention           = SettingConstants.ErrorRetentionPeriodDefaultInDaysForUI;
            Description              = "A ServiceControl Instance";
            HostName                 = "localhost";
            AuditQueueName           = "audit";
            AuditForwardingQueueName = "audit.log";
            AuditForwarding          = AuditForwardingOptions.First(p => !p.Value); //Default to Off.
            ErrorQueueName           = "error";
            ErrorForwardingQueueName = "error.log";
            ErrorForwarding          = ErrorForwardingOptions.First(p => !p.Value); //Default to Off.
            UseSystemAccount         = true;
        }
예제 #17
0
        public static ActionResult ServiceControlUnattendedRemoval(Session session)
        {
            var logger = new MSILogger(session);
            var removeInstancesPropertyValue = session["REMOVEALLINSTANCESANDDATA"];

            if (string.IsNullOrWhiteSpace(removeInstancesPropertyValue))
            {
                return(ActionResult.NotExecuted);
            }

            switch (removeInstancesPropertyValue.ToUpper())
            {
            case "YES":
            case "TRUE":
                break;

            default:
                return(ActionResult.NotExecuted);
            }

            if (InstanceFinder.ServiceControlInstances().Count == 0)
            {
                return(ActionResult.Success);
            }

            var unattendedInstaller = new UnattendServiceControlInstaller(logger, session["APPDIR"]);

            foreach (var instance in InstanceFinder.ServiceControlInstances())
            {
                try
                {
                    unattendedInstaller.Delete(instance.Name, true, true);
                }
                catch (Exception ex)
                {
                    logger.Error($"Error thrown when removing instance {instance.Name} - {ex}");
                }
            }

            return(ActionResult.Success);
        }
예제 #18
0
        static void UpgradeInstances(Session session, ServiceControlZipInfo zipInfo, MSILogger logger, UnattendServiceControlInstaller unattendedInstaller)
        {
            var options = new ServiceControlUpgradeOptions();

            var upgradeInstancesPropertyValue = session["UPGRADEINSTANCES"];

            if (string.IsNullOrWhiteSpace(upgradeInstancesPropertyValue))
            {
                return;
            }

            upgradeInstancesPropertyValue = upgradeInstancesPropertyValue.Trim();

            var forwardErrorMessagesPropertyValue = session["FORWARDERRORMESSAGES"];

            try
            {
                options.OverrideEnableErrorForwarding = bool.Parse(forwardErrorMessagesPropertyValue);
            }
            catch
            {
                options.OverrideEnableErrorForwarding = null;
            }

            var auditRetentionPeriodPropertyValue = session["AUDITRETENTIONPERIOD"];

            try
            {
                options.AuditRetentionPeriod = TimeSpan.Parse(auditRetentionPeriodPropertyValue);
            }
            catch
            {
                options.AuditRetentionPeriod = null;
            }

            var errorRetentionPeriodPropertyValue = session["ERRORRETENTIONPERIOD"];

            try
            {
                options.ErrorRetentionPeriod = TimeSpan.Parse(errorRetentionPeriodPropertyValue);
            }
            catch
            {
                options.ErrorRetentionPeriod = null;
            }

            var confirmDatabaseHasBeenBackedUpValue = session["CONFIRMDATABASEHASBEENBACKEDUP"];

            try
            {
                options.ConfirmDatabaseHasBeenBackedUp = bool.Parse(confirmDatabaseHasBeenBackedUpValue);
            }
            catch
            {
                options.ConfirmDatabaseHasBeenBackedUp = false;
            }

            var allowLargeDatabaseUpgradeValue = session["ALLOWLARGEDATABASEUPGRADE"];

            try
            {
                options.AllowLargeDatabaseUpdate = bool.Parse(allowLargeDatabaseUpgradeValue);
            }
            catch
            {
                options.ConfirmDatabaseHasBeenBackedUp = false;
            }

            //determine what to upgrade
            var instancesToUpgrade = new List <ServiceControlInstance>();

            if (upgradeInstancesPropertyValue.Equals("*", StringComparison.OrdinalIgnoreCase) || upgradeInstancesPropertyValue.Equals("ALL", StringComparison.OrdinalIgnoreCase))
            {
                instancesToUpgrade.AddRange(InstanceFinder.ServiceControlInstances());
            }
            else
            {
                var candidates = upgradeInstancesPropertyValue.Replace(" ", String.Empty).Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                instancesToUpgrade.AddRange(InstanceFinder.ServiceControlInstances().Where(instance => candidates.Contains(instance.Name, StringComparer.OrdinalIgnoreCase)));
            }

            // do upgrades
            foreach (var instance in instancesToUpgrade)
            {
                if (zipInfo.Version > instance.Version)
                {
                    var upgradeInfo = UpgradeControl.GetUpgradeInfoForTargetVersion(zipInfo.Version, instance.Version);

                    options.UpgradeInfo = upgradeInfo;

                    if (!instance.AppConfig.AppSettingExists(SettingsList.ForwardErrorMessages.Name) & !options.OverrideEnableErrorForwarding.Value)
                    {
                        logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. FORWARDERRORMESSAGES MSI parameter was required because appsettings needed a value for '{SettingsList.ForwardErrorMessages.Name}'");
                        continue;
                    }

                    if (!options.AuditRetentionPeriod.HasValue)
                    {
                        if (!instance.AppConfig.AppSettingExists(SettingsList.AuditRetentionPeriod.Name))
                        {
                            //Try migration first
                            if (instance.AppConfig.AppSettingExists(SettingsList.HoursToKeepMessagesBeforeExpiring.Name))
                            {
                                var i = instance.AppConfig.Read(SettingsList.HoursToKeepMessagesBeforeExpiring.Name, -1);
                                if (i > 0)
                                {
                                    options.AuditRetentionPeriod = TimeSpan.FromHours(i);
                                }
                            }
                            else
                            {
                                logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. AUDITRETENTIONPERIOD MSI parameter was required because appsettings needed a value for '{SettingsList.AuditRetentionPeriod.Name}'");
                                continue;
                            }
                        }
                    }

                    if (!instance.AppConfig.AppSettingExists(SettingsList.ErrorRetentionPeriod.Name) & !options.ErrorRetentionPeriod.HasValue)
                    {
                        logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. ERRORRETENTIONPERIOD MSI parameter was required because appsettings needed a value for '{SettingsList.ErrorRetentionPeriod.Name}'");
                        continue;
                    }

                    if (upgradeInfo.DataBaseUpdate) //Database is being updated -> recommend DB backup
                    {
                        if (!options.ConfirmDatabaseHasBeenBackedUp)
                        {
                            logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. This upgrade requires a database update and the database should be backed up prior to updating. CONFIRMDATABASEHASBEENBACKEDUP MSI parameter was required to allow the database upgrade.'");
                            continue;
                        }

                        var dbSize = instance.GetDatabaseSizeInGb();
                        if (dbSize >= 100) // 100GB
                        {
                            logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. Upgrade requires a database update and the database being upgraded is {dbSize:N0} GB. " +
                                        "Migrating this much data could take a long time and ServiceControl will be stopped for that entire duration. It is recommended that you consider one of the other upgrade approaches instead. " +
                                        "ALLOWLARGEDATABASEUPGRADE MSI parameter can be used to allow an unattended database upgrade.'");
                            continue;
                        }
                    }

                    if (!unattendedInstaller.Upgrade(instance, options))
                    {
                        logger.Warn($"Failed to upgrade {instance.Name} to {zipInfo.Version}");
                    }
                }
            }
        }
예제 #19
0
 protected override void ProcessRecord()
 {
     WriteObject(InstanceFinder.ServiceControlInstances().Select(PsServiceControl.FromInstance), true);
 }
예제 #20
0
        static void UpgradeInstances(Session session, ServiceControlZipInfo zipInfo, MSILogger logger, UnattendServiceControlInstaller unattendedInstaller)
        {
            var options = new ServiceControlUpgradeOptions();

            var upgradeInstancesPropertyValue = session["UPGRADEINSTANCES"];

            if (string.IsNullOrWhiteSpace(upgradeInstancesPropertyValue))
            {
                return;
            }
            upgradeInstancesPropertyValue = upgradeInstancesPropertyValue.Trim();

            var forwardErrorMessagesPropertyValue = session["FORWARDERRORMESSAGES"];

            try
            {
                options.OverrideEnableErrorForwarding = bool.Parse(forwardErrorMessagesPropertyValue);
            }
            catch
            {
                options.OverrideEnableErrorForwarding = null;
            }

            var auditRetentionPeriodPropertyValue = session["AUDITRETENTIONPERIOD"];

            try
            {
                options.AuditRetentionPeriod = TimeSpan.Parse(auditRetentionPeriodPropertyValue);
            }
            catch
            {
                options.AuditRetentionPeriod = null;
            }

            var errorRetentionPeriodPropertyValue = session["ERRORRETENTIONPERIOD"];

            try
            {
                options.ErrorRetentionPeriod = TimeSpan.Parse(errorRetentionPeriodPropertyValue);
            }
            catch
            {
                options.ErrorRetentionPeriod = null;
            }

            //determine what to upgrade
            var instancesToUpgrade = new List <ServiceControlInstance>();

            if (upgradeInstancesPropertyValue.Equals("*", StringComparison.OrdinalIgnoreCase) || upgradeInstancesPropertyValue.Equals("ALL", StringComparison.OrdinalIgnoreCase))
            {
                instancesToUpgrade.AddRange(InstanceFinder.ServiceControlInstances());
            }
            else
            {
                var candidates = upgradeInstancesPropertyValue.Replace(" ", String.Empty).Split(",".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
                instancesToUpgrade.AddRange(InstanceFinder.ServiceControlInstances().Where(instance => candidates.Contains(instance.Name, StringComparer.OrdinalIgnoreCase)));
            }

            // do upgrades
            foreach (var instance in instancesToUpgrade)
            {
                if (zipInfo.Version > instance.Version)
                {
                    if (!instance.AppConfig.AppSettingExists(SettingsList.ForwardErrorMessages.Name) & !options.OverrideEnableErrorForwarding.Value)
                    {
                        logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. FORWARDERRORMESSAGES MSI parameter was required because appsettings needed a value for '{SettingsList.ForwardErrorMessages.Name}'");
                        continue;
                    }

                    if (!options.AuditRetentionPeriod.HasValue)
                    {
                        if (!instance.AppConfig.AppSettingExists(SettingsList.AuditRetentionPeriod.Name))
                        {
                            //Try migration first
                            if (instance.AppConfig.AppSettingExists(SettingsList.HoursToKeepMessagesBeforeExpiring.Name))
                            {
                                var i = instance.AppConfig.Read(SettingsList.HoursToKeepMessagesBeforeExpiring.Name, -1);
                                if (i > 0)
                                {
                                    options.AuditRetentionPeriod = TimeSpan.FromHours(i);
                                }
                            }
                            else
                            {
                                logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. AUDITRETENTIONPERIOD MSI parameter was required because appsettings needed a value for '{SettingsList.AuditRetentionPeriod.Name}'");
                                continue;
                            }
                        }
                    }

                    if (!instance.AppConfig.AppSettingExists(SettingsList.ErrorRetentionPeriod.Name) & !options.ErrorRetentionPeriod.HasValue)
                    {
                        logger.Warn($"Unattend upgrade {instance.Name} to {zipInfo.Version} not attempted. ERRORRETENTIONPERIOD MSI parameter was required because appsettings needed a value for '{SettingsList.ErrorRetentionPeriod.Name}'");
                        continue;
                    }

                    if (!unattendedInstaller.Upgrade(instance, options))
                    {
                        logger.Warn($"Failed to upgrade {instance.Name} to {zipInfo.Version}");
                    }
                }
            }
        }