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.agents.qpidpy;
23  
24  import java.io.BufferedReader;
25  import java.io.File;
26  import java.io.IOException;
27  import java.io.InputStreamReader;
28  import java.util.ArrayList;
29  import java.util.List;
30  import org.miloss.fgsms.agentcore.ConfigurationException;
31  import org.miloss.fgsms.agentcore.PolicyFetch;
32  import org.miloss.fgsms.agentcore.StatisticalHelper;
33  import org.miloss.fgsms.common.Utility;
34  import org.miloss.fgsms.services.interfaces.common.PolicyType;
35  import org.miloss.fgsms.services.interfaces.datacollector.AddStatisticalDataRequestMsg;
36  import org.miloss.fgsms.services.interfaces.datacollector.BrokerData;
37  import org.miloss.fgsms.services.interfaces.policyconfiguration.*;
38  import org.apache.log4j.Level;
39  import org.miloss.fgsms.common.Logger;;
40  import org.miloss.fgsms.services.interfaces.common.NameValuePair;
41  
42  /**
43   * Redhat MRG/Apache Qpid C++ Broker agent Calls the
44   * quid-stat2 python command (including with fgsms) to parse the output and
45   * statististics from a C++ Qpid broker Then sends the data back via web service
46   * call
47   *
48   * @author AO
49   */
50  public class qpidcmdws {
51  
52      public qpidcmdws() {
53      }
54      private static final Logger log = Logger.getLogger("fgsms.QpidPython");
55  
56      private List<BrokerData> LoadExchangeData(String url) {
57          //Logger log = Logger.getAnonymousLogger();
58          String cmd = "./qpid-stat2 -e";
59          Runtime run = Runtime.getRuntime();
60          List<BrokerData> list = new ArrayList<BrokerData>();
61          Process pr = null;
62          try {
63              pr = run.exec(cmd);
64          } catch (IOException ex) {
65              log.log(Level.WARN, null, ex);
66              return null;
67          }
68          try {
69              pr.waitFor();
70          } catch (InterruptedException ex) {
71              log.log(Level.WARN, null, ex);
72              return null;
73          }
74  
75  
76          BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
77          String line = "";
78  
79          int count = 0;
80          try {
81              while ((line = buf.readLine()) != null) {
82                  if (count == 0) {
83                      if (line.contains("Failed")) {
84  
85                          //AuxHelper.TryUpdateStatus(false, url, line, false, AuxHelper.UNSPECIFIED, SLACommon.getHostName());
86                          log.log(Level.WARN, "broker at " + url + " is not available");
87                          return null;
88                      }
89                  }
90                  if (count > 2) {
91                      //first item of exchanges
92                      //name(may be null) type durable(bool may be null) bind msgIn msgOut dropped, bytein byteout bytedrop
93                      line = line.trim();
94                      //qpid.management topic
95                      String[] data = line.split(",");
96                      String name = "";
97                      String type = "";
98                      long msgdrop = 0, msgin = 0, msgout = 0, bytesdrop = 0, bytesin = 0, bytesout = 0, bind = 0;
99                      if (data.length == 9) {
100                         name = data[0].trim();
101                         type = data[1].trim();
102                         bind = parseText(data[2].trim());
103                         msgin = parseText(data[3].trim());
104                         msgout = parseText(data[4].trim());
105                         msgdrop = parseText(data[5].trim());
106                         bytesin = parseText(data[6].trim());
107                         bytesout = parseText(data[7].trim());
108                         bytesdrop = parseText(data[8].trim());
109                         BrokerData d = new BrokerData();
110                         d.setQueueOrTopicName(name);
111                         d.setQueueOrTopicCanonicalName(url + name);
112                         d.setActiveConsumers(bind);
113                         d.setItemType(type);
114                         d.setBytesDropped(bytesdrop);
115                         d.setBytesIn(bytesin);
116                         d.setBytesOut(bytesout);
117                         d.setMessagesDropped(msgdrop);
118                         d.setMessagesIn(msgin);
119                         d.setMessagesOut(msgout);
120                         d.setDepth(0);
121                         list.add(d);
122                     }
123 
124                 }
125                 count++;
126             }
127         } catch (IOException ex) {
128             log.log(Level.WARN, null, ex);
129         }
130         return list;
131     }
132 
133     private Long parseText(String s) {
134         Long l;
135         Double d;
136         String working = s.trim();
137         if (s.contains("k") || s.contains("K")) {
138             working = working.replace("k", "");
139             working = working.replace("K", "");
140             d = Double.parseDouble(working) * 1000;
141             return d.longValue();
142         } else if (s.contains("m") || s.contains("M")) {
143             working = working.replace("m", "");
144             working = working.replace("M", "");
145             d = Double.parseDouble(working) * 1000000;
146             return d.longValue();
147         } else if (s.contains("g") || s.contains("G")) {
148             working = working.replace("g", "");
149             working = working.replace("G", "");
150             d = Double.parseDouble(working) * 1000000000;
151             return d.longValue();
152         }
153 
154         return Long.parseLong(working);
155     }
156 
157     private List<BrokerData> LoadQueueData(String url) {
158         //Logger log = Logger.getAnonymousLogger();
159         String cmd = "./qpid-stat2 -q";
160         Runtime run = Runtime.getRuntime();
161         Process pr = null;
162         List<BrokerData> list = new ArrayList<BrokerData>();
163         boolean ok = false;
164 
165         try {
166             pr = run.exec(cmd);
167             ok = true;
168         } catch (IOException ex) {
169             log.log(Level.WARN, null, ex);
170             return null;
171         }
172         try {
173             pr.waitFor();
174             ok = true;
175         } catch (InterruptedException ex) {
176             log.log(Level.WARN, null, ex);
177             return null;
178         }
179 
180         BufferedReader buf = new BufferedReader(new InputStreamReader(pr.getInputStream()));
181         String line = "";
182         int count = 0;
183         try {
184             while ((line = buf.readLine()) != null) {
185                 if (count == 0) {
186                     if (line.contains("Failed")) {
187 
188                         //SetStatus(url, false, line,  perf,  con);
189                         log.log(Level.WARN, "broker at " + url + " is not available");
190                         pr.destroy();
191                         pr = null;
192                         return null;
193                     }
194                 }
195                 if (count > 2) {
196                     String[] data = line.split(",");
197                     String name = "";
198                     long msg = 0, msgin = 0, msgout = 0, bytes = 0, bytesin = 0, bytesout = 0, cons = 0, bind = 0;
199                     if (data.length == 9) {
200                         name = data[0].trim();
201                         msg = parseText(data[1]);//message/queue depth
202                         msgin = parseText(data[2]);//total enqueues
203                         msgout = parseText(data[3]);//total dequeues
204                         bytes = parseText(data[4]);//bytes depth
205                         bytesin = parseText(data[5]);//bytes enqueue
206                         bytesout = parseText(data[6]);//bytes dequeue
207                         cons = parseText(data[7]);//consumer
208                         bind = parseText(data[8]);//bindings
209                         BrokerData d = new BrokerData();
210                         d.setActiveConsumers(bind);
211                         d.setTotalConsumers(cons);
212                         d.setBytesIn(bytesin);
213                         d.setBytesOut(bytesout);
214                         d.setItemType("queue");
215                         d.setMessagesIn(msgin);
216                         d.setMessagesOut(msgout);
217                         d.setQueueOrTopicName(name);
218                         d.setQueueOrTopicCanonicalName(url + name);
219                         d.setDepth(msg);
220                         list.add(d);
221                     }
222                 }
223                 count++;
224             }
225 
226         } catch (IOException ex) {
227             log.log(Level.WARN, null, ex);
228         }
229         try {
230             pr.destroy();
231 
232             pr = null;
233         } catch (Exception ex) {
234         }
235         return list;
236     }
237 
238     void Fire(String url) throws ConfigurationException {
239         AddStatisticalDataRequestMsg req = new AddStatisticalDataRequestMsg();
240         req.setBrokerURI(url);
241         req.setBrokerHostname(Utility.getHostName());
242         req.setAgentType(this.getClass().getCanonicalName());
243         //req.setClassification(cfg.getClasslevel());
244         req.setDomain("unspecified");
245 
246         req.setOperationalStatus(true);
247         req.setOperationalStatusMessage("OK");
248         List<BrokerData> d = this.LoadExchangeData(url);
249         List<BrokerData> d1 = (this.LoadQueueData(url));
250         if (d == null && d1 == null) {
251             req.setOperationalStatus(false);
252             req.setOperationalStatusMessage("Broker is offline");
253         }
254         if (d != null) {
255             req.getData().addAll(d);
256         }
257 
258 
259         StatisticalHelper.send(req);
260         StatisticalServicePolicy pol = (StatisticalServicePolicy) PolicyFetch.TryFetchPolicy(url, PolicyType.STATISTICAL, "unspecified", Utility.getHostName());
261         if (pol != null) {
262             ProcessStatisticalAgentActions(pol, req);
263 
264         }
265 
266 
267     }
268 
269     private List<SLA> GetAgentActions(ArrayOfSLA serviceLevelAggrements) {
270         if (serviceLevelAggrements == null) {
271             return null;
272         }
273         
274         if (serviceLevelAggrements.getSLA().isEmpty()) {
275             return null;
276         }
277         List<SLA> ret = new ArrayList<SLA>();
278         for (int i = 0; i < serviceLevelAggrements.getSLA().size(); i++) {
279             if (serviceLevelAggrements.getSLA().get(i).getAction() != null) {
280                 if (serviceLevelAggrements.getSLA().get(i).getAction().getSLAAction() != null) {
281                     for (int k = 0; k < serviceLevelAggrements.getSLA().get(i).getAction().getSLAAction().size(); k++) {
282                         if (serviceLevelAggrements.getSLA().get(i).getAction().getSLAAction().get(k).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRestart")) {
283                             ret.add(serviceLevelAggrements.getSLA().get(i));
284                         }
285                         if (serviceLevelAggrements.getSLA().get(i).getAction().getSLAAction().get(k).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRunScript")) {
286                             // SLAActionRunScript action = (SLAActionRunScript) serviceLevelAggrements.getSLA().get(i).getAction().getSLAAction().get(k);
287                             NameValuePair runat = Utility.getNameValuePairByName(serviceLevelAggrements.getSLA().get(i).getAction().getSLAAction().get(k).getParameterNameValue(), "runAt");
288                             String location = null;
289                             if (runat != null) {
290 
291                                 if (runat.isEncrypted()) {
292                                     location = Utility.DE(runat.getValue());
293                                 } else {
294                                     location = runat.getValue();
295                                 }
296                             }
297                             if (location != null && location.equalsIgnoreCase(RunAtLocation.FGSMS_AGENT.value())) {
298                                 ret.add(serviceLevelAggrements.getSLA().get(i));
299                             }
300                         }
301                     }
302                 }
303             }
304         }
305         return ret;
306     }
307 
308     private void ProcessStatisticalAgentActions(StatisticalServicePolicy pol, AddStatisticalDataRequestMsg req) {
309         if (pol == null) {
310             return;
311         }
312         if (req == null) {
313             return;
314         }
315 
316         List<SLA> slas = GetAgentActions(pol.getServiceLevelAggrements());
317         if (slas == null) {
318             return;
319         }
320         if (slas.isEmpty()) {
321             return;
322         }
323         ProcessSLAs(slas, req);
324 
325     }
326 
327     private void ProcessSLAs(List<SLA> slas, AddStatisticalDataRequestMsg req) {
328         if (slas == null) {
329             return;
330         }
331         for (int i = 0; i < slas.size(); i++) {
332             boolean flag = ProcessSLA(slas.get(i), req);
333             if (flag) {
334                 DoActions(slas.get(i));
335             }
336         }
337 
338     }
339 
340     private boolean ProcessSLARule(RuleBaseType rule1, AddStatisticalDataRequestMsg req) {
341         if (rule1 == null) {
342             return false;
343         }
344         if (rule1 instanceof AndOrNot) {
345             AndOrNot aon = (AndOrNot) rule1;
346             switch (aon.getFlag()) {
347                 case AND:
348                     return ProcessSLARule(aon.getLHS(), req) && ProcessSLARule(aon.getRHS(), req);
349                 case NOT:
350                     return ProcessSLARule(aon.getLHS(), req) || ProcessSLARule(aon.getRHS(), req);
351                 case OR:
352                     return ProcessSLARule(aon.getLHS(), req);
353             }
354 
355         }
356         if (rule1 instanceof SLARuleGeneric) {
357             SLARuleGeneric r = (SLARuleGeneric) rule1;
358             if (r.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.QueueOrTopicDoesNotExist")) {
359                 String param = null;
360                 NameValuePair value = Utility.getNameValuePairByName(r.getParameterNameValue(), "value");
361                 if (value != null) {
362                     if (value.isEncrypted()) {
363                         param = Utility.DE(value.getValue());
364                     } else {
365                         param = value.getValue();
366                     }
367 
368                     boolean found = false;
369                     for (int i = 0; i < req.getData().size(); i++) {
370                         if (req.getData().get(i).getQueueOrTopicName().toLowerCase().contains(param)) {
371                             found = true;
372                         }
373                     }
374                     if (!found) {
375                         return true;
376                     }
377                 }
378 
379             }
380             if (r.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.BrokerQueueSizeGreaterThan")) {
381 
382                 NameValuePair value = Utility.getNameValuePairByName(r.getParameterNameValue(), "value");
383                 long val = -1;
384                 String topic = null;
385                 NameValuePair optionalName = Utility.getNameValuePairByName(r.getParameterNameValue(), "name");
386                 if (value != null) {
387                     if (value.isEncrypted()) {
388                         val = Long.parseLong(Utility.DE(value.getValue()));
389                     } else {
390                         val = Long.parseLong((value.getValue()));
391                     }
392                 }
393                 if (value != null) {
394                     if (value.isEncrypted()) {
395                         topic = (Utility.DE(optionalName.getValue()));
396                     } else {
397                         topic = ((optionalName.getValue()));
398                     }
399                 }
400                 long maxdepth = 0;
401                 for (int i = 0; i < req.getData().size(); i++) {
402                     if (topic == null) {
403                         if (req.getData().get(i).getDepth() > maxdepth) {
404                             maxdepth = req.getData().get(i).getDepth();
405                         }
406                         if (val > maxdepth) {
407                             return true;
408                         }
409                     } else {
410                         if (req.getData().get(i).getQueueOrTopicName().equalsIgnoreCase(topic) && req.getData().get(i).getDepth() > maxdepth) {
411                             maxdepth = req.getData().get(i).getDepth();
412                         }
413                         if (val > maxdepth) {
414                             return true;
415                         }
416                     }
417                 }
418             }
419 
420         }
421         return false;
422     }
423 //
424 
425     private boolean ProcessSLA(SLA sla, AddStatisticalDataRequestMsg req) {
426         if (sla == null) {
427             return false;
428         }
429 
430         return ProcessSLARule(sla.getRule(), req);
431     }
432 
433     private void DoActions(SLA sla) {
434         if (sla == null) {
435             return;
436         }
437         if (sla.getAction() == null) {
438             return;
439         }
440         if (sla.getAction().getSLAAction().isEmpty()) {
441             return;
442         }
443 
444         for (int i = 0; i < sla.getAction().getSLAAction().size(); i++) {
445             if (sla.getAction().getSLAAction().get(i).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRunScript")) {
446                 NameValuePair runat = Utility.getNameValuePairByName(sla.getAction().getSLAAction().get(i).getParameterNameValue(), "runAt");
447                 NameValuePair runFromPath = Utility.getNameValuePairByName(sla.getAction().getSLAAction().get(i).getParameterNameValue(), "runFromPath");
448                 NameValuePair command = Utility.getNameValuePairByName(sla.getAction().getSLAAction().get(i).getParameterNameValue(), "command");
449                 String location = null;
450                 String cmd = null;
451                 String path = null;
452                 if (runat != null) {
453 
454                     if (runat.isEncrypted()) {
455                         location = Utility.DE(runat.getValue());
456                     } else {
457                         location = runat.getValue();
458                     }
459                 }
460                 if (command != null) {
461 
462                     if (command.isEncrypted()) {
463                         cmd = Utility.DE(command.getValue());
464                     } else {
465                         cmd = command.getValue();
466                     }
467                 }
468                 if (runFromPath != null) {
469 
470                     if (runFromPath.isEncrypted()) {
471                         path = Utility.DE(runFromPath.getValue());
472                     } else {
473                         path = runFromPath.getValue();
474                     }
475                 }
476 
477                 if (location != null && location.equalsIgnoreCase(RunAtLocation.FGSMS_AGENT.value())) {
478                     Runtime run = Runtime.getRuntime();
479                     Process pr = null;
480                     try {
481                         if (Utility.stringIsNullOrEmpty(path)) {
482                             pr = run.exec(cmd);
483                         } else {
484                             pr = run.exec(cmd, null, new File(path));
485                         }
486                     } catch (IOException ex) {
487                         log.log(Level.WARN, null, ex);
488                     }
489 
490                 }
491             }
492         }
493     }
494 }