1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.miloss.fgsms.sla;
23
24 import java.net.URLEncoder;
25 import java.sql.Connection;
26 import java.sql.PreparedStatement;
27 import java.sql.ResultSet;
28 import java.util.List;
29 import java.util.Properties;
30 import java.util.UUID;
31 import java.util.concurrent.atomic.AtomicReference;
32 import javax.mail.Message;
33 import javax.mail.Session;
34 import javax.mail.Transport;
35 import javax.mail.internet.InternetAddress;
36 import javax.mail.internet.MimeMessage;
37 import javax.xml.datatype.Duration;
38 import org.apache.log4j.Level;
39 import org.miloss.fgsms.common.Logger;;
40 import org.miloss.fgsms.common.Utility;
41 import org.miloss.fgsms.plugins.sla.AlertType;
42 import org.miloss.fgsms.plugins.sla.SLARuleInterface;
43 import org.miloss.fgsms.services.interfaces.common.PolicyType;
44 import org.miloss.fgsms.services.interfaces.policyconfiguration.*;
45
46
47
48
49
50
51
52
53
54 public class NonTransactionalSLAProcessor {
55
56 public NonTransactionalSLAProcessor()
57 {
58 }
59
60
61
62 private static Logger log = Logger.getLogger("fgsms.SLAProcessor");
63
64 private List<ServicePolicy> Load(boolean pooled) {
65 List<ServicePolicy> list = null;
66
67 list = SLACommon.LoadServicePoliciesPooled();
68
69 return list;
70
71 }
72
73
74
75
76
77
78 public void run(boolean ispooled) {
79 log.log(Level.INFO, "Loading service policies...");
80 List<ServicePolicy> servicePolicyQueue = Load(ispooled);
81
82
83 log.log(Level.INFO, servicePolicyQueue.size() + " policies loaded...");
84
85 if (servicePolicyQueue.isEmpty()) {
86 log.log(Level.INFO, "fgsms SLA NT Processor nothing to process, exiting...");
87 return;
88 }
89 log.log(Level.INFO, "fgsms SLA Pusher entering loop " + servicePolicyQueue.size() + " policies to process. ");
90 for (int k = 0; k < servicePolicyQueue.size(); k++) {
91
92 if (servicePolicyQueue.get(k) == null) {
93 continue;
94 }
95 if (servicePolicyQueue.get(k).getServiceLevelAggrements() == null) {
96 continue;
97 }
98
99 if (servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().isEmpty()) {
100 continue;
101 }
102
103
104 for (int i = 0; i < servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().size(); i++) {
105 boolean flag = false;
106 StringBuffer faultMsg = new StringBuffer();
107
108
109 if (servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA() == null) {
110 continue;
111 }
112 if (servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().get(i) == null) {
113 continue;
114 }
115 if (servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().get(i).getRule() == null) {
116 continue;
117 }
118
119
120
121 flag = ProcessNonTransactionalRules(
122 faultMsg, servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().get(i).getRule(),
123 servicePolicyQueue.get(k).getPolicyType(), ispooled, servicePolicyQueue.get(k));
124
125 if (flag) {
126 String incident = UUID.randomUUID().toString();
127 log.log(Level.WARN, "SLA Fault tripped for " + servicePolicyQueue.get(k).getURL() + " message: " + faultMsg);
128
129
130 SLACommon.RecordSLAFault(new AtomicReference<String>(faultMsg.toString()), servicePolicyQueue.get(k).getURL(), null, System.currentTimeMillis(), incident, ispooled);
131 SLACommon.ProcessAlerts(faultMsg.toString(), "<h2>" + Utility.encodeHTML(faultMsg.toString()) + "</h2>", servicePolicyQueue.get(k).getURL(), null, System.currentTimeMillis(),
132 incident, ispooled, false, servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().get(i).getAction().getSLAAction(),
133 servicePolicyQueue.get(k).getServiceLevelAggrements().getSLA().get(i).getGuid(), servicePolicyQueue.get(k), AlertType.Performance);
134 }
135 }
136 }
137 }
138
139 public static String GenerateLink(String relativeUrl, ServicePolicy pol) {
140 if (pol.getPolicyType() == null || pol.getPolicyType() == PolicyType.TRANSACTIONAL) {
141 return "<a href=\"" + relativeUrl + "/TransactionLogViewer.jsp?url=" + URLEncoder.encode(pol.getURL()) + "\">View recent transactions</a><br>"
142 + "<a href=\"" + relativeUrl + "/availability.jsp?url=" + URLEncoder.encode(pol.getURL()) + "\">View availability data</a>";
143 }
144
145 if (pol.getPolicyType() == PolicyType.STATISTICAL) {
146 return "<a href=\"" + relativeUrl + "/messageBrokerDetail.jsp?url=" + URLEncoder.encode(pol.getURL()) + "\">View statistics</a><br>"
147 + "<a href=\"" + relativeUrl + "/availability.jsp?url=" + URLEncoder.encode(pol.getURL()) + "\">View availability data</a>";
148 }
149
150 if (pol.getPolicyType() == PolicyType.STATUS) {
151 return "<a href=\"" + relativeUrl + "/availability.jsp?url=" + URLEncoder.encode(pol.getURL()) + "\">View availability data</a>";
152 }
153 return "<a href=\"" + relativeUrl + "\">fgsms</a>";
154
155 }
156
157 public static String GenerateLink(String relativeUrl, String pol) {
158
159 return "<a href=\"" + relativeUrl + "/TransactionLogViewer.jsp?url=" + URLEncoder.encode(pol) + "\">View recent transactions</a><br>"
160 + "<a href=\"" + relativeUrl + "/availability.jsp?url=" + URLEncoder.encode(pol) + "\">View availability data</a>";
161 }
162
163 private boolean ProcessNonTransactionalRules(StringBuffer faultMsg, RuleBaseType rule, PolicyType pol, boolean pooled, ServicePolicy p) {
164
165 if (rule instanceof AndOrNot) {
166 AndOrNot aon = (AndOrNot) rule;
167 switch (aon.getFlag()) {
168 case AND:
169 return ProcessNonTransactionalRules(faultMsg, aon.getLHS(), pol, pooled, p) && ProcessNonTransactionalRules(faultMsg, aon.getRHS(), pol, pooled, p);
170 case OR:
171 return ProcessNonTransactionalRules(faultMsg, aon.getLHS(), pol, pooled, p) || ProcessNonTransactionalRules(faultMsg, aon.getRHS(), pol, pooled, p);
172 case NOT:
173 return !ProcessNonTransactionalRules(faultMsg, aon.getLHS(), pol, pooled, p);
174 }
175 } else if (rule instanceof SLARuleGeneric) {
176 SLARuleGeneric x = (SLARuleGeneric) rule;
177 if (x.getProcessAt() == RunAtLocation.FGSMS_SERVER) {
178 Class c = null;
179 try {
180 c = Thread.currentThread().getContextClassLoader().loadClass(x.getClassName());
181 } catch (ClassNotFoundException ex) {
182 log.log(Level.ERROR, SLACommon.getBundleString("ErrorSLAPluginRuleNCDF") + x.getClassName(), ex);
183 return false;
184 }
185 Object obj = null;
186 if (c != null) {
187 try {
188 obj = c.newInstance();
189 } catch (InstantiationException ex) {
190 log.log(Level.ERROR, SLACommon.getBundleString("ErrorSLAPluginRuleNCDF") + x.getClassName(), ex);
191 return false;
192 } catch (IllegalAccessException ex) {
193 log.log(Level.ERROR, SLACommon.getBundleString("ErrorSLAPluginRuleNCDF") + x.getClassName(), ex);
194 return false;
195 }
196 SLARuleInterface cast = null;
197 try {
198 cast = (SLARuleInterface) obj;
199 } catch (ClassCastException ex) {
200 log.log(Level.ERROR, String.format(SLACommon.getBundleString("ErrorSLAPluginRuleTypeCast"), x.getClassName(), SLARuleInterface.class.getCanonicalName()), ex);
201 return false;
202 }
203 try {
204 AtomicReference<String> msg = new AtomicReference<String>();
205 boolean CheckNonTransactionalRule = cast.CheckNonTransactionalRule(p, x.getParameterNameValue(), msg, pooled);
206 if (CheckNonTransactionalRule) {
207 faultMsg.append(msg.get());
208 return true;
209 }
210 } catch (Exception ex) {
211 log.log(Level.ERROR, String.format(SLACommon.getBundleString("ErrorSLAPluginRuleUnexpectedError"), x.getClassName()), ex);
212 }
213 }
214 }
215 }
216
217
218
219 return false;
220 }
221
222 boolean sendTest(String email) {
223
224 log.log(Level.INFO, "fgsms SLA Pusher test message");
225 try {
226 Properties props = SLACommon.LoadSLAPropertiesPooled();
227
228 Session mailSession = Session.getDefaultInstance(props);
229 Message simpleMessage = new MimeMessage(mailSession);
230 InternetAddress from;
231 if (Utility.stringIsNullOrEmpty(email)) {
232 from = new InternetAddress(props.getProperty("defaultReplyAddress"));
233 } else {
234 from = new InternetAddress(email);
235 }
236
237 InternetAddress to = new InternetAddress(email);
238 simpleMessage.setFrom(from);
239 simpleMessage.setRecipient(Message.RecipientType.TO, to);
240 simpleMessage.setSubject("fgsms SLA Processor Test Message");
241
242 simpleMessage.setContent("This is a test indicating that your fgsms SLA Processor is configured correctly." + "<br>"
243 + "<a href=\"" + props.getProperty("fgsms.GUI.URL") + "\">fgsms</a>", "text/html; charset=ISO-8859-1");
244 Transport.send(simpleMessage);
245 return true;
246 } catch (Exception ex) {
247 log.log(Level.ERROR, "Error sending SLA alert email! " + ex.getLocalizedMessage());
248 }
249 return false;
250
251
252 }
253 private static String allitems = "All-Methods";
254
255 public static long GrabMTBF(long x, String URL) {
256 Connection con = null;
257 try {
258 con = Utility.getPerformanceDB_NONPOOLED_Connection();
259 PreparedStatement comm = con.prepareStatement("select mtbf from agg2 where uri=? and soapaction=? and timerange=?");
260
261 comm.setString(1, URL);
262 comm.setString(2, allitems);
263 comm.setLong(3, x);
264 ResultSet rs = comm.executeQuery();
265 long ret = 0;
266 if (rs.next()) {
267 ret = rs.getLong(1);
268 }
269 rs.close();
270 comm.close();
271 con.close();
272 return ret;
273 } catch (Exception ex) {
274 log.log(Level.ERROR, null, ex);
275 }
276 try {
277 con.close();
278 } catch (Exception ex) {
279 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
280 }
281 return 0;
282 }
283
284 public static long GrabMTBF(Duration x, String URL) {
285 return GrabMTBF(RangeColumnName(x), URL);
286 }
287
288 public static long GrabFaultRate(long timeInMs, String URL) {
289 Connection con = null;
290 try {
291 con = Utility.getPerformanceDBConnection();
292 PreparedStatement comm = con.prepareStatement("select failure from agg2 where uri=? and soapaction=? and timerange=?");
293
294 comm.setString(1, URL);
295 comm.setString(2, allitems);
296 comm.setLong(3, timeInMs);
297 ResultSet rs = comm.executeQuery();
298 long ret = 0;
299 if (rs.next()) {
300 ret = rs.getLong(1);
301 }
302 rs.close();
303 comm.close();
304 con.close();
305 return ret;
306 } catch (Exception ex) {
307 log.log(Level.ERROR, null, ex);
308 }
309 try {
310 if (con != null && !con.isClosed()) {
311 con.close();
312 }
313 } catch (Exception ex) {
314 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
315 }
316
317 return 0;
318 }
319
320 public static long GrabFaultRate(Duration x, String URL) {
321 return GrabFaultRate(RangeColumnName(x), URL);
322 }
323
324 public static long GrabInvocationRate(long x, String URL) {
325 Connection con = null;
326 try {
327 con = Utility.getPerformanceDBConnection();
328 PreparedStatement comm = con.prepareStatement("select success from agg2 where URI=? and soapaction=? and timerange=?");
329
330 comm.setString(1, URL);
331 comm.setString(2, allitems);
332 comm.setLong(3, x);
333 ResultSet rs = comm.executeQuery();
334 long ret = 0;
335 if (rs.next()) {
336 ret = rs.getLong(1);
337 }
338 rs.close();
339 comm.close();
340 con.close();
341 return ret;
342 } catch (Exception ex) {
343 log.log(Level.ERROR, null, ex);
344 }
345 try {
346 if (con != null && !con.isClosed()) {
347 con.close();
348 }
349 } catch (Exception ex) {
350 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
351 }
352 return 0;
353 }
354
355 public static long GrabInvocationRate(Duration x, String URL) {
356 return GrabInvocationRate(RangeColumnName(x), URL);
357 }
358
359 public static long RangeColumnName(Duration time) {
360 return (Utility.durationToTimeInMS(time));
361 }
362
363 public static long GetDiskUsageOverTime(String pol, long timerange, boolean pooled) {
364 Connection con = null;
365 long ret = -1;
366 try {
367
368 con = Utility.getPerformanceDBConnection();
369
370 long limit = System.currentTimeMillis() - timerange;
371 PreparedStatement com = con.prepareStatement("select avg(diskKBs) from rawdatamachineprocess where uri=? and utcdatetime > ?; ");
372 com.setString(1, pol);
373 com.setLong(2, limit);
374 ResultSet rs = com.executeQuery();
375 if (rs.next()) {
376 ret = (long) rs.getDouble(1);
377 }
378 rs.close();
379 com.close();
380 } catch (Exception ex) {
381 log.log(Level.WARN, "trouble calculating avg disk used for " + pol, ex);
382 }
383 try {
384 if (con != null && !con.isClosed()) {
385 con.close();
386 }
387 } catch (Exception ex) {
388 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
389 }
390 return ret;
391 }
392
393 public static long GetDiskUsageOverTime(String pol, Duration timerange, boolean pooled) {
394 return GetDiskUsageOverTime(pol, Utility.durationToTimeInMS(timerange), pooled);
395 }
396
397 public static int GetCPUUsageOverTime(String pol, long timerange, boolean pooled) {
398 Connection con = null;
399 int ret = -1;
400 try {
401
402 con = Utility.getPerformanceDBConnection();
403
404 long limit = System.currentTimeMillis() - timerange;
405 PreparedStatement com = con.prepareStatement("select avg(percentcpu) from rawdatamachineprocess where uri=? and utcdatetime > ?; ");
406 com.setString(1, pol);
407 com.setLong(2, limit);
408 ResultSet rs = com.executeQuery();
409 if (rs.next()) {
410 ret = (int) rs.getDouble(1);
411 }
412 rs.close();
413 com.close();
414 } catch (Exception ex) {
415 log.log(Level.WARN, "trouble calculating avg cpu used for " + pol, ex);
416 }
417 try {
418 if (con != null && !con.isClosed()) {
419 con.close();
420 }
421 } catch (Exception ex) {
422 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
423 }
424 return ret;
425 }
426
427 public static int GetCPUUsageOverTime(String pol, Duration timerange, boolean pooled) {
428 return GetCPUUsageOverTime(pol, Utility.durationToTimeInMS(timerange), pooled);
429 }
430
431 public static long GetMemoryUsageOverTime(String pol, long timerange, boolean pooled) {
432 Connection con = null;
433 long ret = -1;
434 try {
435
436 con = Utility.getPerformanceDBConnection();
437
438 long limit = System.currentTimeMillis() - timerange;
439 PreparedStatement com = con.prepareStatement("select avg(memoryused) from rawdatamachineprocess where uri=? and utcdatetime > ?; ");
440 com.setString(1, pol);
441 com.setLong(2, limit);
442 ResultSet rs = com.executeQuery();
443 if (rs.next()) {
444 ret = (long) rs.getDouble(1);
445 }
446 rs.close();
447 com.close();
448 } catch (Exception ex) {
449 log.log(Level.WARN, "trouble calculating avg mmem used for " + pol, ex);
450 }
451 try {
452 if (con != null && !con.isClosed()) {
453 con.close();
454 }
455 } catch (Exception ex) {
456 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
457 }
458 return ret;
459 }
460
461 public static long GetMemoryUsageOverTime(String pol, Duration timerange, boolean pooled) {
462 return GetMemoryUsageOverTime(pol, Utility.durationToTimeInMS(timerange), pooled);
463 }
464
465 public static long GetNetworkUsageOverTime(String pol, Duration timerange, boolean pooled, String hostname, String domain) {
466 Connection con = null;
467 long ret = -1;
468 try {
469
470 con = Utility.getPerformanceDBConnection();
471
472 long limit = System.currentTimeMillis() - Utility.durationToTimeInMS(timerange);
473 PreparedStatement com = con.prepareStatement("select avg(sendkbs) from rawdatanic "
474 + "where hostname=? and domainname=? and utcdatetime > ?; ");
475
476
477 com.setString(1, hostname);
478 com.setString(2, domain);
479 com.setLong(3, limit);
480 ResultSet rs = com.executeQuery();
481 if (rs.next()) {
482 ret = (long) rs.getDouble(1);
483 }
484 rs.close();
485 com.close();
486 } catch (Exception ex) {
487 log.log(Level.WARN, "trouble calculating avg network used for " + pol, ex);
488 }
489 try {
490 if (con != null && !con.isClosed()) {
491 con.close();
492 }
493 } catch (Exception ex) {
494 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), ex);
495 }
496 return ret;
497 }
498
499 public static long GetLastKnownStatus(String URL, boolean pooled, AtomicReference<Boolean> success) {
500 Connection con = null;
501
502 con = Utility.getConfigurationDBConnection();
503
504 try {
505 PreparedStatement cmd = con.prepareStatement("select utcdatetime from status where uri=?");
506 cmd.setString(1, URL);
507 long ts = -1;
508 ResultSet rs = cmd.executeQuery();
509 if (rs.next()) {
510 ts = rs.getLong(1);
511 }
512 con.close();
513 if (ts > -1) {
514 success.set(true);
515 }
516 rs.close();
517 cmd.close();
518 con.close();
519 return ts;
520 } catch (Exception ex) {
521 try {
522 if (con != null && !con.isClosed()) {
523 con.close();
524 }
525 } catch (Exception x) {
526 log.log(Level.WARN, SLACommon.getBundleString("ErrorClosingDB"), x);
527 }
528 success.set(false);
529 return -1;
530 }
531 }
532 }