Esempio n. 1
0
        public static ServiceStatus Deserialize(string file, ServiceConfig config)
        {
            Log.Trace("Trying to deserialize status XML file [{0}].", file);
            ServiceStatus status;

            var xs = new XmlSerializer(typeof(ServiceStatus));

            try {
                var reader = File.OpenText(file);
                status = (ServiceStatus)xs.Deserialize(reader);
                reader.Close();
                Log.Trace("Finished deserializing service status XML file.");
            }
            catch (Exception) {
                // if reading the status XML fails, we return an empty (new) one
                status = new ServiceStatus();
                Log.Warn("Deserializing [{0}] failed, creating new status using defaults.", file);
            }
            status._config = config;
            ValidateStatus(status);
            // now set the storage filename:
            status._storageFile = file;
            return(status);
        }
Esempio n. 2
0
        /// <summary>
        /// Validate the configuration, throwing exceptions on invalid parameters.
        /// </summary>
        private static void ValidateConfiguration(ServiceConfig c)
        {
            Log.Debug("Validating configuration...");
            var errmsg = "";

            string CheckEmpty(string value, string name)
            {
                // if the string is null terminate the validation immediately since this means the
                // file doesn't contain a required parameter at all:
                if (value == null)
                {
                    var msg = $"mandatory parameter missing: <{name}>";
                    Log.Error(msg);
                    throw new ConfigurationErrorsException(msg);
                }

                if (string.IsNullOrWhiteSpace(value))
                {
                    return($"mandatory parameter unset: <{name}>\n");
                }

                return(string.Empty);
            }

            string CheckMinValue(int value, string name, int min)
            {
                if (value == 0)
                {
                    return($"<{name}> is unset (or set to 0), minimal accepted value is {min}\n");
                }

                if (value < min)
                {
                    return($"<{name}> must not be smaller than {min}\n");
                }

                return(string.Empty);
            }

            string CheckLocalDrive(string value, string name)
            {
                var driveType = new DriveInfo(value).DriveType;

                if (driveType != DriveType.Fixed)
                {
                    return($"<{name}> ({value}) must be a local fixed drive, not '{driveType}'!\n");
                }
                return(string.Empty);
            }

            void WarnOnHighValue(int value, string name, int thresh)
            {
                if (value > thresh)
                {
                    SubOptimal(value.ToString(), name, "value is set very high, please check!");
                }
            }

            void SubOptimal(string value, string name, string message)
            {
                var msg = $">>> Sub-optimal setting detected: <{name}> [{value}] {message}";

                ValidatorWarnings += msg + "\n";
                Log.Warn(msg);
            }

            void LogAndThrow(string msg)
            {
                msg = $"Configuration issues detected:\n{msg}";
                Log.Error(msg);
                throw new ConfigurationErrorsException(msg);
            }

            // check if all required parameters are there and non-empty / non-zero:
            errmsg += CheckEmpty(c.HostAlias, nameof(c.HostAlias));
            errmsg += CheckEmpty(c.SourceDrive, nameof(c.SourceDrive));
            errmsg += CheckEmpty(c.IncomingDirectory, nameof(c.IncomingDirectory));
            errmsg += CheckEmpty(c.ManagedDirectory, nameof(c.ManagedDirectory));
            errmsg += CheckEmpty(c.DestinationAlias, nameof(c.DestinationAlias));
            errmsg += CheckEmpty(c.DestinationDirectory, nameof(c.DestinationDirectory));
            errmsg += CheckEmpty(c.TmpTransferDir, nameof(c.TmpTransferDir));

            errmsg += CheckMinValue(c.ServiceTimer, nameof(c.ServiceTimer), 1000);
            errmsg += CheckMinValue(c.MaxCpuUsage, nameof(c.MaxCpuUsage), 5);
            errmsg += CheckMinValue(c.MaxDiskQueue, nameof(c.MaxDiskQueue), 1);
            errmsg += CheckMinValue(c.MinAvailableMemory, nameof(c.MinAvailableMemory), 256);

            // if any of the required parameter checks failed we terminate now as many of the
            // string checks below would fail on empty strings:
            if (!string.IsNullOrWhiteSpace(errmsg))
            {
                LogAndThrow(errmsg);
            }


            ////////// REQUIRED PARAMETERS SETTINGS VALIDATION //////////

            // SourceDrive
            if (c.SourceDrive.Substring(1) != @":\")
            {
                errmsg += "<SourceDrive> must be of form [X:\\]\n!";
            }
            errmsg += CheckLocalDrive(c.SourceDrive, nameof(c.SourceDrive));

            // spooling directories: IncomingDirectory + ManagedDirectory
            if (c.IncomingDirectory.StartsWith(@"\"))
            {
                errmsg += "<IncomingDirectory> must not start with a backslash!\n";
            }
            if (c.ManagedDirectory.StartsWith(@"\"))
            {
                errmsg += "<ManagedDirectory> must not start with a backslash!\n";
            }

            // DestinationDirectory
            if (!Directory.Exists(c.DestinationDirectory))
            {
                errmsg += $"can't find (or reach) destination: {c.DestinationDirectory}\n";
            }

            // TmpTransferDir
            var tmpTransferPath = Path.Combine(c.DestinationDirectory, c.TmpTransferDir);

            if (!Directory.Exists(tmpTransferPath))
            {
                errmsg += $"can't find (or reach) temporary transfer dir: {tmpTransferPath}\n";
            }


            ////////// OPTIONAL PARAMETERS SETTINGS VALIDATION //////////

            // EmailFrom
            if (!string.IsNullOrWhiteSpace(c.SmtpHost) &&
                string.IsNullOrWhiteSpace(c.EmailFrom))
            {
                errmsg += "<EmailFrom> must not be empty if <SmtpHost> is configured!\n";
            }

            // DriveName
            foreach (var driveToCheck in c.SpaceMonitoring)
            {
                errmsg += CheckLocalDrive(driveToCheck.DriveName, nameof(driveToCheck.DriveName));
            }


            ////////// WEAK CHECKS ON PARAMETERS SETTINGS //////////
            // those checks are non-critical and are simply reported to the logs

            WarnOnHighValue(c.ServiceTimer, nameof(c.ServiceTimer), 10000);
            WarnOnHighValue(c.MaxCpuUsage, nameof(c.MaxCpuUsage), 75);
            WarnOnHighValue(c.MaxDiskQueue, nameof(c.MaxDiskQueue), 2000);
            WarnOnHighValue(c.MinAvailableMemory, nameof(c.MinAvailableMemory), 8192);
            WarnOnHighValue(c.AdminNotificationDelta, nameof(c.AdminNotificationDelta), 1440);
            WarnOnHighValue(c.GraceNotificationDelta, nameof(c.GraceNotificationDelta), 10080);
            WarnOnHighValue(c.StorageNotificationDelta, nameof(c.StorageNotificationDelta), 10080);
            WarnOnHighValue(c.GracePeriod, nameof(c.GracePeriod), 100);

            if (!c.DestinationDirectory.StartsWith(@"\\"))
            {
                SubOptimal(c.DestinationDirectory, "DestinationDirectory", "is not a UNC path!");
            }

            // LogLevel
            var validLogLevels = new List <string> {
                "Warn", "Info", "Debug", "Trace"
            };

            if (!validLogLevels.Contains(c.LogLevel))
            {
                SubOptimal(c.LogLevel, "LogLevel", "is invalid, using 'Debug'. Valid options: " +
                           string.Join(", ", validLogLevels));
                c.LogLevel = "Debug";
            }


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

            LogAndThrow(errmsg);
        }
Esempio n. 3
0
 /// <summary>
 /// Dummy method raising an exception (this class must not be serialized).
 /// </summary>
 public static void Serialize(string file, ServiceConfig c)
 {
     // the config is never meant to be written by us, therefore:
     throw new SettingsPropertyIsReadOnlyException("The config file must not be written by the service!");
 }