comparison 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
comparison
equal deleted inserted replaced
-1:000000000000 0:3e1a2131f897
1 using System;
2 using System.Linq;
3 using System.Text;
4 using System.Text.RegularExpressions;
5 using System.Threading;
6 using System.Threading.Tasks;
7 using System.Xml.Serialization;
8
9 namespace ServerMonitorApp
10 {
11 /*public enum CheckType
12 {
13 Command
14 }*/
15
16 public enum CheckStatus
17 {
18 Success,
19 Information,
20 Warning,
21 Error,
22 Running,
23 Disabled,
24 }
25
26 public abstract class Check
27 {
28 private static Type[] _checkTypes;
29
30 public static Type[] CheckTypes
31 {
32 get
33 {
34 return _checkTypes ?? (_checkTypes = typeof(Check).Assembly.GetTypes()
35 .Where(t => t.IsSubclassOf(typeof(Check)))
36 .OrderBy(t => t.GetAttribute<DisplayWeightAttribute>()?.DisplayWeight).ToArray());
37 }
38 }
39
40 public int Id { get; set; }
41
42 public string Name { get; set; }
43
44 /*public CheckType Type { get; set; }*/
45
46 public int Timeout { get; set; }
47
48 public bool Enabled { get; set; }
49
50 public Schedule Schedule { get; set; }
51
52 public DateTime LastRunTime { get; set; }
53
54 public DateTime LastScheduledRunTime { get; set; }
55
56 public DateTime NextRunTime { get; set; }
57
58 public string LastMessage { get; set; }
59
60 public CheckStatus Status { get; set; }
61
62 public CheckStatus FailStatus { get; set; }
63
64 [XmlIgnore]
65 public Server Server { get; set; }
66
67 public Check()
68 {
69 FailStatus = CheckStatus.Error;
70 }
71
72 public override string ToString()
73 {
74 return Name;
75 }
76
77 public virtual string Validate(bool saving = true)
78 {
79 string message = string.Empty;
80 if (Name.IsNullOrEmpty() && saving)
81 message += "Name cannot be blank." + Environment.NewLine;
82 return message;
83 }
84
85 //public virtual CheckStatus Execute()
86 //{
87 // //TODO
88 // throw new NotImplementedException();
89 //}
90
91 public async Task<CheckResult> ExecuteAsync(CancellationToken token = default(CancellationToken), bool update = true)
92 {
93 //TODO check cancellation token before proceeding
94 CheckResult result;
95 DateTime startTime = DateTime.Now;
96 try
97 {
98 Task<CheckResult> checkTask = ExecuteCheckAsync(token);
99 try
100 {
101 if (await Task.WhenAny(checkTask, Task.Delay(Timeout, token)) == checkTask)
102 {
103 result = await checkTask;
104 }
105 else
106 {
107 result = Fail("Timed out.");
108 }
109 }
110 catch (TaskCanceledException)
111 {
112 return null;
113 }
114 }
115 catch (Exception e)
116 {
117 result = Fail(e.GetBaseException().Message);
118 }
119 result.StartTime = startTime;
120 result.EndTime = DateTime.Now;
121 // If a check is executed from the CheckForm, we don't want to update the status or log the event.
122 if (update)
123 {
124 Status = result.CheckStatus;
125 LastMessage = result.Message;
126 LastRunTime = result.EndTime;
127 }
128 return result;
129 }
130
131 protected CheckResult Pass(string message)
132 {
133 return new CheckResult(this, CheckStatus.Success, message);
134 }
135
136 protected CheckResult Fail(string message)
137 {
138 return new CheckResult(this, FailStatus, message);
139 }
140
141 protected CheckResult Fail(Exception e)
142 {
143 return new CheckResult(this, FailStatus, e.GetBaseException().Message);
144 }
145
146 protected virtual CheckResult GetIntResult(int expectedValue, int resultValue, string description)
147 {
148 if (expectedValue == resultValue)
149 return Pass(string.Format("{0}: {1}", description, resultValue));
150 else
151 return Fail(string.Format("{0}: {1} (expected: {2})", description, resultValue, expectedValue));
152 }
153
154 protected virtual CheckResult GetStringResult(MatchType matchType, string expectedPattern, bool useRegex, string resultValue, string description)
155 {
156 bool match;
157 if (useRegex)
158 {
159 if (matchType.In(MatchType.Equals, MatchType.NotEquals))
160 {
161 if (!expectedPattern.StartsWith("^"))
162 expectedPattern = "^" + expectedPattern;
163 if (!expectedPattern.EndsWith("$"))
164 expectedPattern += "$";
165 }
166 Regex re = new Regex(expectedPattern, RegexOptions.Singleline);
167 match = re.IsMatch(resultValue);
168 }
169 else
170 {
171 if (matchType.In(MatchType.Equals, MatchType.NotEquals))
172 match = expectedPattern == resultValue;
173 else
174 match = resultValue.Contains(expectedPattern);
175 }
176
177 if (matchType.In(MatchType.Equals, MatchType.Contains))
178 {
179 if (match)
180 return Pass(string.Format("{0} {1} the pattern: {2}", description, matchType.ToString().ToLower(), expectedPattern));
181 else
182 return Fail(string.Format("{0} does not {1} the pattern: {2} ({0}: {3})", description, matchType.ToString().ToLower().TrimEnd('s'), expectedPattern, resultValue));
183 }
184 else
185 {
186 if (match)
187 return Fail(string.Format("{0} {1} the pattern: {2} ({0}: {3})", description, matchType.ToString().ToLower().Replace("not", ""), expectedPattern, resultValue));
188 else
189 return Pass(string.Format("{0} does not {1} the pattern: {2}", description, matchType.ToString().ToLower().TrimEnd('s').Replace("not", ""), expectedPattern));
190 }
191 }
192
193 protected CheckResult MergeResults(params CheckResult[] results)
194 {
195 StringBuilder message = new StringBuilder();
196 bool failed = false;
197 foreach (CheckResult result in results)
198 {
199 if (result == null)
200 continue;
201 if (result.CheckStatus != CheckStatus.Success)
202 failed = true;
203 message.AppendLine(result.Message);
204 }
205 return failed ? Fail(message.ToString().Trim()) : Pass(message.ToString().Trim());
206 }
207
208 protected abstract Task<CheckResult> ExecuteCheckAsync(CancellationToken token);
209 }
210 }