diff ServerMonitor/Objects/Check.cs @ 0:3e1a2131f897

Initial commit. Ping check, scheduling, UI working. SSH check mostly working.
author Brad Greco <brad@bgreco.net>
date Mon, 31 Dec 2018 18:32:14 -0500
parents
children 9e92780ebc0f
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ServerMonitor/Objects/Check.cs	Mon Dec 31 18:32:14 2018 -0500
@@ -0,0 +1,210 @@
+using System;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Xml.Serialization;
+
+namespace ServerMonitorApp
+{
+    /*public enum CheckType
+    {
+        Command
+    }*/
+
+    public enum CheckStatus
+    {
+        Success,
+        Information,
+        Warning,
+        Error,
+        Running,
+        Disabled,
+    }
+
+    public abstract class Check
+    {
+        private static Type[] _checkTypes;
+
+        public static Type[] CheckTypes
+        {
+            get
+            {
+                return _checkTypes ?? (_checkTypes = typeof(Check).Assembly.GetTypes()
+                    .Where(t => t.IsSubclassOf(typeof(Check)))
+                    .OrderBy(t => t.GetAttribute<DisplayWeightAttribute>()?.DisplayWeight).ToArray());
+            }
+        }
+
+        public int Id { get; set; }
+
+        public string Name { get; set; }
+
+        /*public CheckType Type { get; set; }*/
+
+        public int Timeout { get; set; }
+
+        public bool Enabled { get; set; }
+
+        public Schedule Schedule { get; set; }
+
+        public DateTime LastRunTime { get; set; }
+
+        public DateTime LastScheduledRunTime { get; set; }
+
+        public DateTime NextRunTime { get; set; }
+
+        public string LastMessage { get; set; }
+
+        public CheckStatus Status { get; set; }
+
+        public CheckStatus FailStatus { get; set; }
+
+        [XmlIgnore]
+        public Server Server { get; set; }
+
+        public Check()
+        {
+            FailStatus = CheckStatus.Error;
+        }
+
+        public override string ToString()
+        {
+            return Name;
+        }
+
+        public virtual string Validate(bool saving = true)
+        {
+            string message = string.Empty;
+            if (Name.IsNullOrEmpty() && saving)
+                message += "Name cannot be blank." + Environment.NewLine;
+            return message;
+        }
+
+        //public virtual CheckStatus Execute()
+        //{
+        //    //TODO
+        //    throw new NotImplementedException();
+        //}
+
+        public async Task<CheckResult> ExecuteAsync(CancellationToken token = default(CancellationToken), bool update = true)
+        {
+            //TODO check cancellation token before proceeding
+            CheckResult result;
+            DateTime startTime = DateTime.Now;
+            try
+            {
+                Task<CheckResult> checkTask = ExecuteCheckAsync(token);
+                try
+                {
+                    if (await Task.WhenAny(checkTask, Task.Delay(Timeout, token)) == checkTask)
+                    {
+                        result = await checkTask;
+                    }
+                    else
+                    {
+                        result = Fail("Timed out.");
+                    }
+                }
+                catch (TaskCanceledException)
+                {
+                    return null;
+                }
+            }
+            catch (Exception e)
+            {
+                result = Fail(e.GetBaseException().Message);
+            }
+            result.StartTime = startTime;
+            result.EndTime = DateTime.Now;
+            // If a check is executed from the CheckForm, we don't want to update the status or log the event.
+            if (update)
+            {
+                Status = result.CheckStatus;
+                LastMessage = result.Message;
+                LastRunTime = result.EndTime;
+            }
+            return result;
+        }
+
+        protected CheckResult Pass(string message)
+        {
+            return new CheckResult(this, CheckStatus.Success, message);
+        }
+
+        protected CheckResult Fail(string message)
+        {
+            return new CheckResult(this, FailStatus, message);
+        }
+
+        protected CheckResult Fail(Exception e)
+        {
+            return new CheckResult(this, FailStatus, e.GetBaseException().Message);
+        }
+
+        protected virtual CheckResult GetIntResult(int expectedValue, int resultValue, string description)
+        {
+            if (expectedValue == resultValue)
+                return Pass(string.Format("{0}: {1}", description, resultValue));
+            else
+                return Fail(string.Format("{0}: {1} (expected: {2})", description, resultValue, expectedValue));
+        }
+
+        protected virtual CheckResult GetStringResult(MatchType matchType, string expectedPattern, bool useRegex, string resultValue, string description)
+        {
+            bool match;
+            if (useRegex)
+            {
+                if (matchType.In(MatchType.Equals, MatchType.NotEquals))
+                {
+                    if (!expectedPattern.StartsWith("^"))
+                        expectedPattern = "^" + expectedPattern;
+                    if (!expectedPattern.EndsWith("$"))
+                        expectedPattern += "$";
+                }
+                Regex re = new Regex(expectedPattern, RegexOptions.Singleline);
+                match = re.IsMatch(resultValue);
+            }
+            else
+            {
+                if (matchType.In(MatchType.Equals, MatchType.NotEquals))
+                    match = expectedPattern == resultValue;
+                else
+                    match = resultValue.Contains(expectedPattern);
+            }
+
+            if (matchType.In(MatchType.Equals, MatchType.Contains))
+            {
+                if (match)
+                    return Pass(string.Format("{0} {1} the pattern: {2}", description, matchType.ToString().ToLower(), expectedPattern));
+                else
+                    return Fail(string.Format("{0} does not {1} the pattern: {2} ({0}: {3})", description, matchType.ToString().ToLower().TrimEnd('s'), expectedPattern, resultValue));
+            }
+            else
+            {
+                if (match)
+                    return Fail(string.Format("{0} {1} the pattern: {2} ({0}: {3})", description, matchType.ToString().ToLower().Replace("not", ""), expectedPattern, resultValue));
+                else
+                    return Pass(string.Format("{0} does not {1} the pattern: {2}", description, matchType.ToString().ToLower().TrimEnd('s').Replace("not", ""), expectedPattern));
+            }
+        }
+
+        protected CheckResult MergeResults(params CheckResult[] results)
+        {
+            StringBuilder message = new StringBuilder();
+            bool failed = false;
+            foreach (CheckResult result in results)
+            {
+                if (result == null)
+                    continue;
+                if (result.CheckStatus != CheckStatus.Success)
+                    failed = true;
+                message.AppendLine(result.Message);
+            }
+            return failed ? Fail(message.ToString().Trim()) : Pass(message.ToString().Trim());
+        }
+
+        protected abstract Task<CheckResult> ExecuteCheckAsync(CancellationToken token);
+    }
+}
\ No newline at end of file