View Javadoc
1   /**
2    * This Source Code Form is subject to the terms of the Mozilla Public
3    * License, v. 2.0. If a copy of the MPL was not distributed with this
4    * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5    *
6    * If it is not possible or desirable to put the notice in a particular
7    * file, then You may include the notice in a location (such as a LICENSE
8    * file in a relevant directory) where a recipient would be likely to look
9    * for such a notice.
10  
11   * 
12   */
13   
14  /*  ---------------------------------------------------------------------------
15   *  U.S. Government, Department of the Army
16   *  Army Materiel Command
17   *  Research Development Engineering Command
18   *  Communications Electronics Research Development and Engineering Center
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   * NonTransactionalSLAProcessor - handles most non transactional SLA
48   * rules for web services, processes, operating systems, status What
49   * is a Non Transactional SLA? Something that occurs over a range of time or
50   * grouping of records
51   *
52   * @author AO
53   */
54  public class NonTransactionalSLAProcessor {
55  
56      public NonTransactionalSLAProcessor()//Hashtable policyCache, ConcurrentLinkedQueue<AddDataRequestMsg> outboundQueue)
57      {
58      }
59      // in ms
60      //   private long timeRange;
61      // private Hashtable policyCache;
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       * processes time range based SLAs for all service policy types
75       *
76       * @param ispooled
77       */
78      public void run(boolean ispooled) {
79          log.log(Level.INFO, "Loading service policies...");
80          List<ServicePolicy> servicePolicyQueue = Load(ispooled);
81  
82          //     UpdateStatus();
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                 //identify if any non transaction rules are present, if so collect results and add them to a HashMap
120 //                flag = ProcessNonTransactionalRules(pol.url, faultMsg, pol.slas.getValue().getSLA().get(i).getRule(), lastprocessedat);
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             // comm.setString(1, ;
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             //      comm.setString(1,);
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 }