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   *  U.S. Government, Department of the Army
15   *  Army Materiel Command
16   *  Research Development Engineering Command
17   *  Communications Electronics Research Development and Engineering Center
18   *  ---------------------------------------------------------------------------
19   */
20  package org.miloss.fgsms.osagent;
21  
22  import org.miloss.fgsms.osagent.sensor.ISensorProvider;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStream;
27  import java.io.RandomAccessFile;
28  import java.nio.channels.FileChannel;
29  import java.nio.channels.FileLock;
30  import java.text.NumberFormat;
31  import java.util.ArrayList;
32  import java.util.GregorianCalendar;
33  import java.util.HashSet;
34  import java.util.List;
35  import java.util.Properties;
36  import java.util.Set;
37  import javax.xml.bind.JAXBContext;
38  import javax.xml.bind.Marshaller;
39  import javax.xml.datatype.DatatypeConfigurationException;
40  import javax.xml.datatype.DatatypeFactory;
41  import javax.xml.datatype.Duration;
42  import java.util.Calendar;
43  import java.util.Iterator;
44  import java.util.UUID;
45  import org.miloss.fgsms.agentcore.ConfigurationException;
46  import org.miloss.fgsms.agentcore.OSAgentHelper;
47  import org.miloss.fgsms.agentcore.PersistentStorage;
48  import org.miloss.fgsms.common.Utility;
49  import org.miloss.fgsms.services.interfaces.common.*;
50  import org.miloss.fgsms.services.interfaces.datacollector.AddMachineAndProcessDataRequestMsg;
51  import org.miloss.fgsms.services.interfaces.datacollector.AddMachineAndProcessDataResponseMsg;
52  import org.miloss.fgsms.services.interfaces.policyconfiguration.*;
53  import org.miloss.fgsms.osagent.Ifconfig.NetworkRate;
54  import org.miloss.fgsms.osagent.Iostat.DiskRates;
55  import org.miloss.fgsms.osagent.sensor.SensorProviderFactory;
56  import org.apache.log4j.Level;
57  import org.miloss.fgsms.common.Logger;;
58  import org.hyperic.sigar.Mem;
59  import org.hyperic.sigar.OperatingSystem;
60  import org.hyperic.sigar.Sigar;
61  import org.hyperic.sigar.SigarException;
62  import org.hyperic.sigar.SigarLoader;
63  import org.hyperic.sigar.win32.Service;
64  import org.miloss.fgsms.common.Constants;
65  import us.gov.ic.ism.v2.ClassificationType;
66  
67  /**
68   * fgsms's Operating System agent Provides monitoring and some SLA processing
69   * for the machine as a whole or processes running on a machine. Uses the SIGARS
70   * API provided by VMWare
71   *
72   * <br><br><br> FAQ: How to change the reporting rate of os (machine and process
73   * monitor) agents?<Br>
74   *
75   * OS Agents use two different timers. <ol><li> 1) update the running process
76   * list, hardware and network information. This is referred to as the refresh
77   * rate.</li><li> 2) update the current status and performnace data. This is
78   * referred to as the Reporting Frequency.</il></ol>
79   *
80   * The RF is changed via the global configuration setting, Agents.Process,
81   * ReportingFrequency.<Br><br>
82   *
83   * However, changes with this value are by default updated <ul><li>when the
84   * agent starts</li> <li>once an hour</li> </ul>
85   *
86   * Since 6.2.1. To increase the rate, a command line option can be added to the
87   * os agent's startup script with overrides the default refresh rate to whatever
88   * you want, measured in ms. This will generate slightly more load on the
89   * machine hosting the agent, and will add additional bandwidth consumption if
90   * it is turned down from the defaults. Use the following option
91   * -DrefreshRateOverride=(some duration in milliseconds)
92   *
93   * Since 6.3, OS Agents can now report sensor data back to fgsms. To configure a
94   * sensor data feed, a properties file must be provided. Either place
95   * sensor.properties in the current working directory or use
96   * -DsensorProviders=path to provide the configuration. <br><br> The properties
97   * file needs only a single setting, sensorProviders with a value equal to a
98   * comma delimited list of classes that implement the ISensorProvider interface.
99   *
100  * @since RC6
101  * @see ISensorProvider
102  * @see SensorProviderFactory
103  * @author AO
104  */
105 public class OSAgent {
106 
107     private static final String WINDOWS_KEY = "WindowsService:";
108     public final static Logger log = Logger.getLogger("fgsms.fgsmsOSAgent");
109     private static boolean isWindows = false;
110 
111     private DatatypeFactory df = null;
112     protected boolean running = false;
113     private boolean done = false;
114     private File file;
115     private FileChannel channel;
116     private List<ISensorProvider> sensors = new ArrayList<ISensorProvider>();
117     private FileLock lock;
118     private SecurityWrapper classlevel = new SecurityWrapper(ClassificationType.U, "");
119     private Duration frequency = null;
120     private MachinePolicy machine = null;
121     private List<ProcessPolicy> processes = null;
122     /*
123      * Debug adds additional logging
124      */
125     private boolean DEBUG = false;
126     /**
127      * NO_SEND prevents the agent from sending any data. It will perform a test
128      * to detect memory leaks in hyperic's sigar api
129      */
130     private boolean NO_SEND = false;
131 
132     public long startedat = -1;
133     public long datasend_success = 0;
134     public long datasend_failures = 0;
135     //  protected Endpoint callback = null;
136     //  protected Endpoint callback_ipv6 = null;
137     //   protected boolean callback_running = false;
138     protected int callback_port = 4000;
139     protected int maxportattempts = 1000;
140     protected int currentportattempts = 0;
141     private Properties sensorconfig = null;
142 
143     private long iteration = 0;
144 
145     private static String filter(String description) {
146         return description.replaceAll("[^\\x00-\\x7F]", "").replaceAll("\\p{Cc}", "");
147     }
148 
149     public OSAgent() throws DatatypeConfigurationException {
150         df = DatatypeFactory.newInstance();
151         this.classlevel = new SecurityWrapper(ClassificationType.U, "");
152     }
153 
154     /**
155      * @param args the command line arguments
156      */
157     public static void main(String[] args) throws Exception {
158 
159         new OSAgent().startup(args);
160 
161     }
162 
163     /**
164      * Gathers the current machine information
165      *
166      * @return
167      * @throws SigarException
168      */
169     protected static MachineInformation gatherInformation() throws SigarException {
170         Sigar s = new Sigar();
171         MachineInformation m = new MachineInformation();
172 
173         m.setHostname(Utility.getHostName());
174         OperatingSystem sys = OperatingSystem.getInstance();
175 
176         PropertyPair pp = null;
177         pp = new PropertyPair();
178         pp.setPropertyname("OS Description");
179         pp.setPropertyvalue(filter(sys.getDescription()));
180         m.getPropertyPair().add(pp);
181 
182         pp = new PropertyPair();
183         pp.setPropertyname("OS Name");
184         pp.setPropertyvalue(filter(sys.getName()));
185         m.getPropertyPair().add(pp);
186 
187         pp = new PropertyPair();
188         pp.setPropertyname("OS Architecture");
189         pp.setPropertyvalue(filter(sys.getArch()));
190         m.getPropertyPair().add(pp);
191 
192         pp = new PropertyPair();
193         pp.setPropertyname("OS Machine");
194         pp.setPropertyvalue(filter(sys.getMachine()));
195         m.getPropertyPair().add(pp);
196 
197         pp = new PropertyPair();
198         pp.setPropertyname("OS Version");
199         pp.setPropertyvalue(filter(sys.getVersion()));
200         m.getPropertyPair().add(pp);
201 
202         pp = new PropertyPair();
203         pp.setPropertyname("OS Patch Level");
204         pp.setPropertyvalue(filter(sys.getPatchLevel()));
205         m.getPropertyPair().add(pp);
206 
207         pp = new PropertyPair();
208         pp.setPropertyname("OS Vendor Version");
209         pp.setPropertyvalue(filter(sys.getVendorVersion()));
210         m.getPropertyPair().add(pp);
211 
212         pp = new PropertyPair();
213         pp.setPropertyname("OS Vendor");
214         pp.setPropertyvalue(filter(sys.getVendor()));
215         m.getPropertyPair().add(pp);
216 
217         if (sys.getVendorCodeName() != null) {
218             pp = new PropertyPair();
219             pp.setPropertyname("OS Code Name");
220             pp.setPropertyvalue(filter(sys.getVendorCodeName()));
221             m.getPropertyPair().add(pp);
222 
223         }
224         pp = new PropertyPair();
225         pp.setPropertyname("OS Data Model");
226         pp.setPropertyvalue(filter(sys.getDataModel()));
227         m.getPropertyPair().add(pp);
228 
229         pp = new PropertyPair();
230         pp.setPropertyname("OS CPU Endian");
231         pp.setPropertyvalue(filter(sys.getCpuEndian()));
232         m.getPropertyPair().add(pp);
233 
234         pp = new PropertyPair();
235         pp.setPropertyname("JVM Version");
236         pp.setPropertyvalue(filter(System.getProperty("java.vm.version")));
237         m.getPropertyPair().add(pp);
238 
239         pp = new PropertyPair();
240         pp.setPropertyname("JVM Vendor");
241         pp.setPropertyvalue(filter(System.getProperty("java.vm.vendor")));
242         m.getPropertyPair().add(pp);
243 
244         pp = new PropertyPair();
245         pp.setPropertyname("JVM Home");
246         pp.setPropertyvalue(filter(System.getProperty("java.home")));
247         m.getPropertyPair().add(pp);
248 
249         Ps ps = new Ps();
250         try {
251 
252             m.setCpucorecount(ps.GetCPUCores());
253         } catch (Exception ex) {
254             log.log(Level.WARN, "unable to get cpu core count", ex);
255         } finally {
256             try {
257                 ps.close();
258             } catch (Exception ex) {
259             }
260         }
261 
262         Mem mem = s.getMem();
263 
264         m.setMemoryinstalled(mem.getRam() * 1024 * 1024);
265         m.setOperatingsystem(System.getProperty("os.name"));
266         if (m.getOperatingsystem().toLowerCase().contains("win")) {
267             isWindows = true;
268         }
269         m.getDriveInformation().addAll(getDriveInfo());
270         NetInfo ni = new NetInfo();
271         try {
272             m.getAddresses().addAll(ni.GetNetworkInfo());
273         } catch (Exception ex) {
274             log.log(Level.WARN, "unable to get network info", ex);
275         } finally {
276             try {
277                 ni.close();
278             } catch (Exception ex) {
279             }
280         }
281         m.getHostname();
282         m.setDomain(getDomainName());
283 
284         m.setUri("urn:" + Utility.getHostName() + ":system");
285         s.close();
286         return m;
287 
288     }
289 
290     /**
291      * Returns a list of running processes, if windows, the windows installed
292      * service list is also included
293      *
294      * @param isWindows
295      * @return
296      * @throws SigarException
297      */
298     protected static List<String> getServiceList(boolean isWindows) throws SigarException {
299         List<String> items = new ArrayList<String>();
300         if (isWindows) {
301             try {
302                 List services = Service.getServiceNames();
303                 for (int i = 0; i < services.size(); i++) {
304                     items.add(WINDOWS_KEY + (String) services.get(i));
305 
306                 }
307             } catch (Exception ex) {
308                 ex.printStackTrace();
309             }
310         }
311         //changed to prevent multiple instances of the same executable from being listed
312         Ps ps = new Ps();
313         try {
314             List<String> data = (ps.runningProcesses());
315             Set<String> set = new HashSet<String>(data);
316             Iterator<String> iterator = set.iterator();
317             while (iterator.hasNext()) {
318                 String i = iterator.next();
319                 i = Utility.encodeHTML(i);
320                 items.add(i);
321             }
322 
323         } catch (Exception ex) {
324             log.log(Level.WARN, "can't get the list of running processes");
325         } finally {
326             try {
327                 ps.close();
328             } catch (Exception e) {
329             }
330         }
331 
332         return items;
333     }
334 
335     /**
336      * Sends the most recent performance metrics to fgsms
337      *
338      * @return
339      * @throws SigarException
340      * @throws ConfigurationException
341      */
342     private boolean refreshInfo() throws SigarException, ConfigurationException {
343         MachineInformation m = gatherInformation();
344         SetProcessListByMachineRequestMsg req = new SetProcessListByMachineRequestMsg();
345         req.setAgentType(OSAgent.class.getCanonicalName());
346         req.setMachineInformation(m);
347 
348         if (req.getMachineInformation().getOperatingsystem().toLowerCase().contains("win")) {
349             req.getServices().addAll(getServiceList(true));
350         } else {
351             req.getServices().addAll(getServiceList(false));
352         }
353         /*    if (callback_running) {
354          PropertyPair callbackp = new PropertyPair();
355          callbackp.setPropertyname(org.miloss.fgsms.common.Constants.PROPERTYPAIR_OS_AGENT_CALLBACK_URL);
356          callbackp.setPropertyvalue("http://" + Utility.getHostName() + ":" + callback_port + "/os_agent");
357          req.getMachineInformation().getPropertyPair().add(callbackp);
358          }*/
359 
360         PropertyPair callbackp = new PropertyPair();
361         callbackp.setPropertyname(org.miloss.fgsms.common.Constants.PROPERTYPAIR_OS_AGENT_STARTED);
362         callbackp.setPropertyvalue(Long.toString(startedat));
363         req.getMachineInformation().getPropertyPair().add(callbackp);
364         SetProcessListByMachineResponseMsg SetMachineInfo = OSAgentHelper.SetMachineInfo(req);
365         if (SetMachineInfo == null) {
366             datasend_failures++;
367             log.log(Level.WARN, "unable to reach the fgsms PCS service. This could either be a connectivity issue or a problem at the service.");
368             return false;
369         } else {
370             datasend_success++;
371             frequency = SetMachineInfo.getReportingFrequency();
372             classlevel = SetMachineInfo.getClassification();
373             machine = SetMachineInfo.getMachinePolicy();
374             processes = SetMachineInfo.getProcessPolicy();
375             return true;
376         }
377     }
378 
379     protected void startup(String[] args) throws Exception {
380         System.out.println("Use \"java -jar fgsms.OSBuellerNextGen.jar help\" for command line options");
381         boolean dump = false;
382         if (args != null && args.length >= 1 && args[0].equalsIgnoreCase("help")) {
383             printUsage();
384             return;
385         }
386         if (args != null && args.length >= 1 && args[0].equalsIgnoreCase("debug")) {
387             DEBUG = true;
388         }
389         if (args != null && args.length >= 1 && args[0].equalsIgnoreCase("nosend")) {
390             NO_SEND = true;
391             RUN_DEBUG_TEST();
392             return;
393         }
394         if (args != null && args.length >= 1 && args[0].equalsIgnoreCase("runleaktest")) {
395             try {
396                 RUN_LEAK_TEST();
397             } catch (Exception ex) {
398                 java.util.logging.Logger.getLogger(OSAgent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
399             }
400             return;
401         }
402         if (args != null && args.length >= 1 && args[0].equalsIgnoreCase("dump")) {
403             dump = true;
404         }
405         if (dump) {
406             dumpInfo();
407             return;
408         }
409         try {
410             file = new File("procmon.lck");
411             channel = new RandomAccessFile(file, "rw").getChannel();
412             lock = channel.tryLock();
413         } catch (Exception e) {
414             // already locked
415             closeLock();
416             System.out.println("Could not obtain the lock, this means that either this program is already running or something went wrong and the file procmon.lck needs to be deleted.");
417             return;
418         }
419         if (lock == null) {
420             closeLock();
421             System.out.println("Could not obtain the lock, this means that either this program is already running or something went wrong and the file procmon.lck needs to be deleted.");
422             return;
423         }
424         startedat = System.currentTimeMillis();
425         /*     RemoteAgentCallbackImpl callback_service = new RemoteAgentCallbackImpl(this);
426 
427          log.log(Level.INFO, "Attempting to start the callback endpoint");
428          //TODO reconfigure this to also support IPv6
429          while (!callback_running && currentportattempts < maxportattempts) {
430          currentportattempts++;
431          callback_port++;
432          try {
433          callback = Endpoint.publish("http://0.0.0.0:" + callback_port + "/os_agent", callback_service);
434          } catch (Exception ex) {
435          log.log(Level.WARN, "unable to set callback point on port " + callback_port, ex);
436          }
437          if (callback != null && callback.isPublished()) {
438          callback_running = true;
439          }
440          }
441          if (!callback_running) {
442          log.log(Level.WARN, "Unable to establish callback service. Remote administrative actions from fgsms will not be possible");
443          } else {
444          log.log(Level.INFO, "Remote callbacks setup at http://" + Utility.getHostName() + ":" + callback_port + "/os_agent  (all IPs are bound)");
445          }*/
446         Runtime.getRuntime().addShutdownHook(new RunWhenShuttingDown());
447 //        PropertyConfigurator.configure("log4j.properties");
448         done = true;
449         if (DEBUG) {
450             log.log(Level.INFO, "fgsms.OS Agent (Machine, Process Performance Monitor) startup.....");
451         }
452 
453         startSensorFeeds();
454 
455         try {
456             refreshInfo();
457         } catch (Exception ex) {
458             log.log(Level.FATAL, "something went really wrong, exiting", ex);
459             done = true;
460             running = false;
461             printSigarInfo();
462             return;
463         }
464         if (frequency == null) {
465             log.log(Level.WARN, "the current reporting frequency is unexpectedly null. defaulting to 30 seconds");
466             frequency = df.newDuration(30 * 1000);
467         }
468         if (machine == null) {
469             log.log(Level.WARN, "the machine policy is null, default to a basic policy");
470             machine = loadDefaultMachinePolicy();
471             //return;
472         }
473         done = false;
474         running = true;
475         long lastRanAt = 0;
476         long interval = Utility.durationToTimeInMS(frequency);
477         long refresh = 60 * 60 * 1000;
478 
479         String override = System.getProperty("refreshRateOverride");
480         if (override != null) {
481             try {
482                 refresh = Long.parseLong(override);
483             } catch (Exception ex) {
484                 System.err.println("I couldn't parse the value of refreshRateOverride, defaulting to 1 hr" + ex.getMessage());
485             }
486         }
487 
488         long lastRefresh = System.currentTimeMillis();
489         NumberFormat nf = NumberFormat.getNumberInstance();
490         log.log(Level.INFO, "Starting Persistent Storage Agent");
491         PersistentStorage.start(new String[]{"nostatus"});
492         while (running) {
493             if ((System.currentTimeMillis() - lastRefresh > refresh) || machine == null) {
494                 lastRefresh = System.currentTimeMillis();
495                 try {
496                     if (DEBUG) {
497                         log.log(Level.INFO, "Data Interval: " + interval + " Config Interval: " + refresh);
498                     }
499                     refreshInfo();
500                 } catch (Exception ex) {
501                     log.log(Level.FATAL, "something went really wrong, exiting", ex);
502                     done = true;
503                     running = false;
504                     return;
505                 }
506             }
507             if (System.currentTimeMillis() - lastRanAt > interval) {
508                 lastRanAt = System.currentTimeMillis();
509                 //run
510                 try {
511                     iteration++;
512                     long timer = System.currentTimeMillis();
513                     if (DEBUG) {
514                         log.log(Level.INFO, "Data Interval: " + interval + " Config Interval: " + refresh);
515                         log.log(Level.INFO, "iteration " + nf.format(iteration) + " of " + nf.format(Long.MAX_VALUE));
516                         log.log(Level.INFO, "Current VM Memory : total = " + nf.format(Runtime.getRuntime().totalMemory()) + " free = " + nf.format(Runtime.getRuntime().freeMemory())
517                                 + " used " + nf.format(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
518                     }
519                     fire();
520                     if (DEBUG) {
521                         log.log(Level.INFO, "Took " + nf.format((System.currentTimeMillis() - timer)) + " ms to run");
522                     }
523                 } catch (Exception ex) {
524                     log.log(Level.WARN, "error caught ", ex);
525                 }
526                 if (DEBUG) {
527                     log.log(Level.INFO, "Pausing until the next iteration in " + interval + "ms.....");
528                 }
529             }
530             if (running) {
531                 try {
532                     Thread.sleep(1000);
533                 } catch (InterruptedException ex) {
534                     java.util.logging.Logger.getLogger(OSAgent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
535                 }
536             }
537         }
538         running = false;
539         done = true;
540     }
541 
542     public SecurityWrapper getClasslevel() {
543         return classlevel;
544     }
545 
546     public SecurityWrapper getClassLevelAsCopy() {
547         if (classlevel == null) {
548             classlevel = new SecurityWrapper(ClassificationType.U, "");
549         }
550         SecurityWrapper x = new SecurityWrapper();
551         x.setCaveats(classlevel.getCaveats());
552         x.setClassification(classlevel.getClassification());
553         return x;
554     }
555 
556     private void closeLock() {
557         try {
558             lock.release();
559         } catch (Exception e) {
560         }
561         try {
562             channel.close();
563         } catch (Exception e) {
564         }
565     }
566 
567     private void deleteFile() {
568         try {
569             file.delete();
570         } catch (Exception e) {
571         }
572     }
573 
574     private static String getDomainName() {
575         String domain = System.getenv().get("USERDOMAIN");
576         if (domain != null && !domain.equalsIgnoreCase(Utility.getHostName())) {
577             return (domain.toLowerCase().trim());
578         } else {
579             return Constants.UNSPECIFIED;
580         }
581     }
582 
583     /**
584      * Fetches the most recent performance data, sends it to fgsms, then
585      * performs some basic
586      *
587      * @throws ConfigurationException
588      * @throws SigarException
589      * @throws DatatypeConfigurationException
590      */
591     protected void fire() throws ConfigurationException, SigarException, DatatypeConfigurationException {
592         AddMachineAndProcessDataRequestMsg req = new AddMachineAndProcessDataRequestMsg();
593         req.setAgentType(this.getClass().getCanonicalName());
594         req.setClassification(classlevel);
595 
596         //req.getDriveInformation().addAll(GetDriveInfo(this.machine.getRecordDiskSpace()));
597         log.log(Level.INFO, "refreshing local machine performance information");
598         req.setMachineData(getMachineInfo(this.machine));
599         if (req.getMachineData() == null) {
600             log.log(Level.WARN, "Machine info and/or the Machine Policy is unexpectly null. This can happen when all the fgsms servers are offline. I'll try again in a minute");
601             return;
602         }
603         req.setHostname(Utility.getHostName());
604         log.log(Level.INFO, "refreshing local process performance information");
605         req.getProcessData().addAll(getProcessData(this.processes));
606         req.setDomainname(getDomainName());
607         req.setSensorData(getSensorData());
608         if (!NO_SEND) {
609             log.log(Level.INFO, "sending data...");
610             //JAXB.marshal(req,System.out);
611             AddMachineAndProcessDataResponseMsg res = OSAgentHelper.AddMachineAndProcessDataRequestMsg(req);
612             if (res != null) {
613                 datasend_success++;
614                 log.log(Level.INFO, "sent successfully...");
615                 this.classlevel = res.getClassification();
616                 this.machine = res.getMachinePolicy();
617                 this.processes = res.getProcessPolicy();
618 
619                 log.log(Level.DEBUG, "processing SLA actions");
620             } else {
621                 datasend_failures++;
622                 log.log(Level.WARN, "trouble sending data...");
623             }
624 
625             doAgentSLAActions(req);
626         } else {
627             log.log(Level.INFO, "skipping sending iteration");
628         }
629     }
630 
631     protected static List<DriveInformation> getDriveInfo() throws SigarException {
632         Df sigar = new Df();
633         List<DriveInformation> ret = new ArrayList<DriveInformation>();
634         try {
635             ret = sigar.DriveInfo();
636         } catch (Exception ex) {
637             log.log(Level.WARN, "trouble getting drive info ", ex);
638         } finally {
639             try {
640                 sigar.close();
641             } catch (Exception ex) {
642             }
643         }
644         return ret;
645 
646     }
647 
648     /**
649      * Get machine information, such as current cpu, memory, disk, nic usage
650      *
651      * @param machine
652      * @return
653      * @throws DatatypeConfigurationException
654      * @throws SigarException
655      */
656     protected MachinePerformanceData getMachineInfo(MachinePolicy machine) throws DatatypeConfigurationException, SigarException, ConfigurationException {
657         if (machine == null) {
658             refreshInfo();
659         }
660         if (machine == null) {
661             return null;
662         }
663         MachinePerformanceData m = new MachinePerformanceData();
664         m.setUri(machine.getURL());
665         m.setId(UUID.randomUUID().toString());
666         m.setOperationalstatus(true);
667         m.setStatusmessage("Operational");
668         Ps ps = new Ps();
669         try {
670 
671             m.setNumberofActiveThreads(ps.CurrentThreadCount());
672             if (machine.isRecordCPUusage()) {
673                 m.setPercentusedCPU(ps.GetCurrentCPUUsage());
674                 m.setOperationalstatus(true);
675             }
676             GregorianCalendar gcal = new GregorianCalendar();
677             gcal.setTimeInMillis(ps.GetSystemBootTimeInMS());
678             m.setStartedAt((gcal));
679         } catch (Exception ex) {
680             m.setNumberofActiveThreads(-1L);
681         } finally {
682             try {
683                 ps.close();
684             } catch (Exception e) {
685             }
686         }
687         //  SysInfo si = new SysInfo();
688         MemWatch mw = new MemWatch();
689 
690         if (machine.isRecordMemoryUsage()) {
691             if (DEBUG) {
692                 log.log(Level.INFO, "getting machine memory usage");
693             }
694             Mem MemoryBytesUsed = mw.MemoryBytesUsed();
695             m.setBytesusedMemory(MemoryBytesUsed.getActualUsed());
696             if (DEBUG) {
697                 log.log(Level.INFO, "RAW values " + MemoryBytesUsed.getActualUsed());
698             }
699             //        new SysInfo().
700         }
701 
702         if (!machine.getRecordDiskUsagePartitionNames().isEmpty()) //if (machine.isRecordDiskUsage())
703         {
704             Iostat io = new Iostat();
705             Df sigar = new Df();
706             try {
707                 for (int i = 0; i < machine.getRecordDiskUsagePartitionNames().size(); i++) {
708                     DriveInformation di = new DriveInformation();
709                     di.setPartition(machine.getRecordDiskUsagePartitionNames().get(i));
710                     di.setSystemid(machine.getRecordDiskUsagePartitionNames().get(i));
711                     di.setTimestamp(new GregorianCalendar());
712                     DriveInformation driveInfo = sigar.GetDriveInfo(machine.getRecordDiskUsagePartitionNames().get(i));
713                     if (driveInfo != null) {
714                         di.setSystemid(driveInfo.getSystemid());
715                         di.setType(driveInfo.getType());
716                         di.setTotalspace(di.getTotalspace());
717                     } else {
718                         di.setSystemid("");
719                         di.setType("");
720                         di.setTotalspace(0L);
721                     }
722                     try {
723                         if (DEBUG) {
724                             log.log(Level.INFO, "getting disk io stats/usage for " + machine.getRecordDiskUsagePartitionNames().get(i));
725                         }
726 
727                         DiskRates rates = io.GetBytesPerSecond(machine.getRecordDiskUsagePartitionNames().get(i), isWindows);
728                         if (DEBUG) {
729                             log.log(Level.INFO, "RAW values " + rates.bytesreadpersecond + " " + rates.byteswritepersecond);
730                         }
731                         di.setKilobytespersecondDiskRead(rates.bytesreadpersecond / 1024);
732                         di.setKilobytespersecondDiskWrite(rates.byteswritepersecond / 1024);
733                         di.setOperational(true);
734                     } catch (Exception ex) {
735                         log.log(Level.WARN, "unable to get disk rates for " + machine.getRecordDiskUsagePartitionNames().get(i), ex);
736                         di.setOperational(false);
737                     }
738                     m.getDriveInformation().add(di);
739                 }
740             } catch (Exception ex) {
741                 log.log(Level.FATAL, "unexpected error", ex);
742             } finally {
743                 try {
744                     io.close();
745                 } catch (Exception ex) {
746                 }
747                 try {
748                     sigar.close();
749                 } catch (Exception ex) {
750                 }
751             }
752         }
753 
754         if (!machine.getRecordNetworkUsage().isEmpty()) {
755             Ifconfig ic = new Ifconfig();
756             try {
757                 for (int i = 0; i < machine.getRecordNetworkUsage().size(); i++) {
758                     try {
759                         if (DEBUG) {
760                             log.log(Level.INFO, "getting network io stats/usage for " + machine.getRecordNetworkUsage().get(i));
761                         }
762 
763                         NetworkRate rate = ic.NetworkSendRate(machine.getRecordNetworkUsage().get(i));
764                         NetworkAdapterPerformanceData nic = new NetworkAdapterPerformanceData();
765                         nic.setAdapterName(machine.getRecordNetworkUsage().get(i));
766                         if (DEBUG) {
767                             log.log(Level.INFO, "RAW values " + rate.rx + " " + rate.tx);
768                         }
769                         nic.setKilobytespersecondNetworkReceive(rate.rx / 1024);
770                         nic.setKilobytespersecondNetworkTransmit(rate.tx / 1024);
771                         m.getNetworkAdapterPerformanceData().add(nic);
772                     } catch (Exception ex) {
773                         log.log(Level.WARN, "unable to get NIC information ", ex);
774                     }
775                 }
776             } catch (Exception ex) {
777                 log.log(Level.FATAL, "unexpected error", ex);
778             } finally {
779                 try {
780                     ic.close();
781                 } catch (Exception ex) {
782                 }
783             }
784         }
785 
786         m.setTimestamp(getNow());
787         if (!machine.getRecordDiskSpace().isEmpty()) {
788             updateFreeSpaceRecords(m.getDriveInformation(), machine.getRecordDiskSpace());
789         }
790         //    m.getDriveInformation().addAll(GetDriveInfo(this.machine.getRecordDiskSpace()));
791         return m;
792     }
793 
794     private List<ProcessPerformanceData> getProcessData(List<ProcessPolicy> processes) {
795 
796         List<ProcessPerformanceData> data = new ArrayList<ProcessPerformanceData>();
797         if (processes == null || processes.isEmpty()) {
798             return data;
799         }
800         Ps ps = new Ps();
801         ProcInfo pi = new ProcInfo();
802         try {
803             for (int i = 0; i < processes.size(); i++) {
804                 try {
805                     if (DEBUG) {
806                         log.log(Level.INFO, "Getting process data for " + processes.get(i).getURL());
807                     }
808                     String name = getProcessName(processes.get(i).getURL());
809                     List<Long> pids = new ArrayList<Long>();
810                     if (name.startsWith(WINDOWS_KEY)) {
811                         name = name.replace(WINDOWS_KEY, "");
812                         pids.addAll(pi.getDataWindows(name, processes.get(i).getAlsoKnownAs(), true));
813                     } else if (name.startsWith("java:")) {
814                         //name = name.replace(WINDOWS_KEY, "");
815                         pids.addAll(pi.getDataJava(name, processes.get(i).getAlsoKnownAs()));
816                     } else {
817                         if (isWindows) {
818                             name = chopWindows(processes.get(i).getURL());
819                         } else {
820                             name = chopLinux(processes.get(i).getURL());
821                         }
822                         pids.addAll(pi.GetData(name, processes.get(i).getAlsoKnownAs()));
823                         //   pids.addAll(pi.GetData(name, processes.get(i).getAlsoKnownAs()));
824                     }
825                     if (DEBUG) {
826                         log.log(Level.INFO, "found " + pids.size() + " pids for the service" + processes.get(i).getURL() + " local name " + name);
827                     }
828                     ProcessPerformanceData ppd = ps.GetProcessData(pids);
829 
830                     ppd.setTimestamp(getNow());
831                     if (ppd.isOperationalstatus()) {
832                         if (DEBUG) {
833                             log.log(Level.INFO, "running");
834                         }
835                     } else {
836                         log.log(Level.WARN, processes.get(i).getURL() + " is NOT running " + ppd.getStatusmessage());
837                     }
838                     ppd.setUri(processes.get(i).getURL());
839                     data.add(ppd);
840 
841                 } catch (org.hyperic.sigar.win32.Win32Exception ex) {
842                     //usually access denied, monitoring a windows service and the agent is not running as a system service (user land)
843                     ProcessPerformanceData ppd = new ProcessPerformanceData();
844                     ppd.setStatusmessage(ex.getMessage());
845                     ppd.setOperationalstatus(false);
846                     ppd.setTimestamp(getNow());
847                     if (ppd.isOperationalstatus()) {
848                         if (DEBUG) {
849                             log.log(Level.INFO, "running");
850                         }
851                     } else {
852                         log.log(Level.WARN, processes.get(i).getURL() + " is NOT running " + ppd.getStatusmessage());
853                     }
854                     ppd.setUri(processes.get(i).getURL());
855                     data.add(ppd);
856                     log.log(Level.WARN, processes.get(i).getURL(), ex);
857                 } catch (Exception ex) {
858                     log.log(Level.WARN, processes.get(i).getURL(), ex);
859 
860                 }
861 
862             }
863         } catch (Exception ex) {
864             log.log(Level.FATAL, "unexpected error", ex);
865         } finally {
866             try {
867                 ps.close();
868             } catch (Exception ex) {
869                 log.log(Level.DEBUG, null, ex);
870             }
871             try {
872                 pi.close();
873             } catch (Exception ex) {
874                 log.log(Level.DEBUG, null, ex);
875             }
876         }
877         return data;
878     }
879 
880     private void updateFreeSpaceRecords(List<DriveInformation> driveInformation, List<String> partitions) {
881         Df driveinfo = new Df();
882         //List<DriveInformation> items = new ArrayList<DriveInformation>();
883         try {
884             for (int i = 0; i < partitions.size(); i++) {
885                 if (DEBUG) {
886                     log.log(Level.INFO, "getting free space for partition " + partitions.get(i));
887                 }
888                 try {
889                     DriveInformation di = driveinfo.GetDriveInfo(partitions.get(i));
890 
891                     DriveInformation record = findRecord(driveInformation, partitions.get(i));
892                     if (di == null) {
893                         record.setOperational(false);
894                     } else {
895                         record.setOperational(true);
896                         if (DEBUG) {
897                             log.log(Level.INFO, "RAW value " + di.getFreespace());
898                         }
899                         record.setFreespace(di.getFreespace() / 1024);
900                     }
901                 } catch (Exception ex) {
902                     log.log(Level.WARN, "error caught checking free space for " + partitions.get(i), ex);
903                 }
904             }
905         } catch (Exception ex) {
906             log.log(Level.FATAL, "unexpected error", ex);
907         } finally {
908             try {
909                 driveinfo.close();
910             } catch (Exception ex) {
911                 log.log(Level.DEBUG, null, ex);
912             }
913         }
914     }
915 
916     private DriveInformation findRecord(List<DriveInformation> driveInformation, String get) {
917         if (driveInformation == null) {
918             driveInformation = new ArrayList<DriveInformation>();
919         }
920         for (int i = 0; i < driveInformation.size(); i++) {
921             if (driveInformation.get(i).getPartition().equalsIgnoreCase(get)) {
922                 return driveInformation.get(i);
923             }
924         }
925         DriveInformation di = new DriveInformation();
926         di.setPartition(get);
927         driveInformation.add(di);
928         return di;
929     }
930 
931     private String getProcessName(String url) {
932 
933         String[] bits = url.split(":");
934         //urn
935         //hostname
936         //system
937         //optionally WindowsService or java
938         //process name
939         if (bits[bits.length - 2].equalsIgnoreCase(WINDOWS_KEY.replace(":", ""))
940                 || bits[bits.length - 2].equalsIgnoreCase("java")) {
941             return bits[bits.length - 2] + ":" + bits[bits.length - 1];
942         }
943         return bits[bits.length - 1];
944     }
945 
946     private Calendar getNow() {
947         GregorianCalendar gcal = new GregorianCalendar();
948         gcal.setTimeInMillis(System.currentTimeMillis());
949         return (gcal);
950     }
951 
952     private void doAgentSLAActions(AddMachineAndProcessDataRequestMsg req) {
953         if (this.machine != null) {
954             if (this.machine.getServiceLevelAggrements() != null
955                     && !this.machine.getServiceLevelAggrements().getSLA().isEmpty()) {
956                 doMachineSLAs(req, this.machine.getServiceLevelAggrements().getSLA());
957             }
958         }
959         if (this.processes != null) {
960             for (int i = 0; i < this.processes.size(); i++) {
961                 if (this.processes.get(i).getServiceLevelAggrements() != null && !this.processes.get(i).getServiceLevelAggrements().getSLA().isEmpty()) {
962 
963                     doProcessSLAs(getProcessRecord(this.processes.get(i).getURL(), req), this.machine.getServiceLevelAggrements().getSLA());
964                 }
965             }
966         }
967     }
968 
969     private ProcessPerformanceData getProcessRecord(String url, AddMachineAndProcessDataRequestMsg data) {
970         if (Utility.stringIsNullOrEmpty(url)) {
971             return null;
972         }
973         if (data == null || data.getProcessData().isEmpty()) {
974             return null;
975         }
976         for (int i = 0; i < data.getProcessData().size(); i++) {
977             if (data.getProcessData().get(i).getUri().equalsIgnoreCase(url)) {
978                 return data.getProcessData().get(i);
979             }
980         }
981         return null;
982     }
983 
984     private void doMachineSLAs(AddMachineAndProcessDataRequestMsg rec, List<SLA> sla) {
985         for (int i = 0; i < sla.size(); i++) {
986             if (containsSLAAgentActon(sla.get(i).getAction())) {
987                 if (checkRules(rec, sla.get(i).getRule())) {
988                     doActions(sla.get(i).getAction(), true, null);
989                 }
990             }
991         }
992     }
993 
994     private void doProcessSLAs(ProcessPerformanceData rec, List<SLA> sla) {
995         for (int i = 0; i < sla.size(); i++) {
996             if (containsSLAAgentActon(sla.get(i).getAction())) {
997                 if (checkRules(rec, sla.get(i).getRule())) {
998                     doActions(sla.get(i).getAction(), false, getPolicy(rec.getUri()));
999                 }
1000             }
1001         }
1002     }
1003 
1004     private boolean containsSLAAgentActon(ArrayOfSLAActionBaseType action) {
1005         if (action == null) {
1006             return false;
1007         }
1008         if (action.getSLAAction().isEmpty()) {
1009             return false;
1010         }
1011         for (int i = 0; i < action.getSLAAction().size(); i++) {
1012             if (action.getSLAAction().get(i).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRestart")) {
1013                 NameValuePair RUNAT = Utility.getNameValuePairByName(action.getSLAAction().get(i).getParameterNameValue(), "runAt");
1014                 if (RUNAT != null) {
1015                     RunAtLocation ral = null;
1016                     String t = null;
1017                     if (RUNAT.isEncrypted()) {
1018                         t = Utility.DE(RUNAT.getValue());
1019                     } else {
1020                         t = RUNAT.getValue();
1021                     }
1022                     ral = RunAtLocation.valueOf(t);
1023                     if (ral == RunAtLocation.FGSMS_AGENT) {
1024                         return true;
1025                     }
1026                 }
1027             }
1028             if (action.getSLAAction().get(i).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRunScript")) {
1029                 NameValuePair RUNAT = Utility.getNameValuePairByName(action.getSLAAction().get(i).getParameterNameValue(), "runAt");
1030                 if (RUNAT != null) {
1031                     RunAtLocation ral = null;
1032                     String t = null;
1033                     if (RUNAT.isEncrypted()) {
1034                         t = Utility.DE(RUNAT.getValue());
1035                     } else {
1036                         t = RUNAT.getValue();
1037                     }
1038                     ral = RunAtLocation.valueOf(t);
1039                     if (ral == RunAtLocation.FGSMS_AGENT) {
1040                         return true;
1041                     }
1042                 }
1043             }
1044         }
1045         return false;
1046     }
1047 
1048     /**
1049      * return true if a rule's conditions are met (SLA fault)
1050      *
1051      * @param rec
1052      * @param rule
1053      * @return
1054      */
1055     private boolean checkRules(ProcessPerformanceData rec, RuleBaseType rule) {
1056         if (rule instanceof AndOrNot) {
1057             AndOrNot r = (AndOrNot) rule;
1058             switch (r.getFlag()) {
1059                 case AND:
1060                     return checkRules(rec, r.getLHS()) && checkRules(rec, r.getRHS());
1061                 case OR:
1062                     return checkRules(rec, r.getLHS()) || checkRules(rec, r.getRHS());
1063                 case NOT:
1064                     return !checkRules(rec, r.getLHS());
1065             }
1066         }
1067         if (rule instanceof SLARuleGeneric) {
1068             SLARuleGeneric x = (SLARuleGeneric) rule;
1069             if (x.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighCPUUsage")) {
1070                 if (rec.getPercentusedCPU() == null) {
1071                     return false;
1072                 }
1073                 NameValuePair GetNameValuePairByName = Utility.getNameValuePairByName(x.getParameterNameValue(), "value");
1074                 long rate = -1;
1075                 if (GetNameValuePairByName.isEncrypted()) {
1076                     rate = Long.parseLong(Utility.DE(GetNameValuePairByName.getValue()));
1077                 } else {
1078                     rate = Long.parseLong(GetNameValuePairByName.getValue());
1079                 }
1080 
1081                 if (rec.getPercentusedCPU() > rate) {
1082                     return true;
1083                 }
1084             } else if (x.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighMemoryUsage")) {
1085                 if (rec.getBytesusedMemory() == null) {
1086                     return false;
1087                 }
1088                 NameValuePair GetNameValuePairByName = Utility.getNameValuePairByName(x.getParameterNameValue(), "value");
1089                 long rate = -1;
1090                 if (GetNameValuePairByName.isEncrypted()) {
1091                     rate = Long.parseLong(Utility.DE(GetNameValuePairByName.getValue()));
1092                 } else {
1093                     rate = Long.parseLong(GetNameValuePairByName.getValue());
1094                 }
1095 
1096                 if (rec.getBytesusedMemory() > rate) {
1097                     return true;
1098                 }
1099             } else if (x.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighOpenFileHandles")) {
1100                 NameValuePair GetNameValuePairByName = Utility.getNameValuePairByName(x.getParameterNameValue(), "value");
1101                 long rate = -1;
1102                 if (GetNameValuePairByName.isEncrypted()) {
1103                     rate = Long.parseLong(Utility.DE(GetNameValuePairByName.getValue()));
1104                 } else {
1105                     rate = Long.parseLong(GetNameValuePairByName.getValue());
1106                 }
1107 
1108                 if (rec.getOpenFileHandles() > rate) {
1109                     return true;
1110                 }
1111             } else if (x.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighThreadCount")) {
1112                 NameValuePair GetNameValuePairByName = Utility.getNameValuePairByName(x.getParameterNameValue(), "value");
1113                 long rate = -1;
1114                 if (GetNameValuePairByName.isEncrypted()) {
1115                     rate = Long.parseLong(Utility.DE(GetNameValuePairByName.getValue()));
1116                 } else {
1117                     rate = Long.parseLong(GetNameValuePairByName.getValue());
1118                 }
1119 
1120                 if (rec.getNumberofActiveThreads() != null && rec.getNumberofActiveThreads() > rate) {
1121                     return true;
1122                 }
1123             }
1124         }
1125         return false;
1126     }
1127 
1128     private void doActions(ArrayOfSLAActionBaseType action, boolean ismachine, ProcessPolicy p) {
1129         if (action == null) {
1130             return;
1131         }
1132         if (action.getSLAAction().isEmpty()) {
1133             return;
1134         }
1135         for (int i = 0; i < action.getSLAAction().size(); i++) {
1136             if (action.getSLAAction().get(i).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRestart")) {
1137                 if (ismachine) {
1138                     doRestartComputer();
1139                 } else {
1140                     DoRestartProcess(p);
1141                 }
1142             }
1143             if (action.getSLAAction().get(i).getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRunScript")) {
1144                 runScript(action.getSLAAction().get(i));
1145             }
1146         }
1147     }
1148 
1149     private boolean checkRules(AddMachineAndProcessDataRequestMsg rec, RuleBaseType rule) {
1150         if (rule instanceof AndOrNot) {
1151         } else if (rule instanceof SLARuleGeneric) {
1152             SLARuleGeneric r2 = (SLARuleGeneric) rule;
1153             NameValuePair val = Utility.getNameValuePairByName(r2.getParameterNameValue(), "value");
1154             long value = -1;
1155             if (val.isEncrypted()) {
1156                 value = Long.parseLong(Utility.DE(val.getValue()));
1157             } else {
1158                 value = Long.parseLong((val.getValue()));
1159             }
1160             if (r2.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighCPUUsage")) {
1161                 if (rec.getMachineData().getPercentusedCPU() == null) {
1162                     return false;
1163                 }
1164                 if (rec.getMachineData().getPercentusedCPU() > value) {
1165                     return true;
1166                 }
1167             }
1168             if (r2.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighMemoryUsage")) {
1169                 if (rec.getMachineData().getBytesusedMemory() == null) {
1170                     return false;
1171                 }
1172                 if (rec.getMachineData().getBytesusedMemory() > value) {
1173                     return true;
1174                 }
1175             }
1176             if (r2.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighNetworkUsage")) {
1177                 if (rec.getMachineData().getNetworkAdapterPerformanceData().isEmpty()) {
1178                     return false;
1179                 }
1180                 for (int i = 0; i < rec.getMachineData().getNetworkAdapterPerformanceData().size(); i++) {
1181                     if (rec.getMachineData().getNetworkAdapterPerformanceData().get(i).getKilobytespersecondNetworkReceive() != null) {
1182                         if (rec.getMachineData().getNetworkAdapterPerformanceData().get(i).getKilobytespersecondNetworkReceive() > value) {
1183                             return true;
1184                         }
1185                     }
1186                     if (rec.getMachineData().getNetworkAdapterPerformanceData().get(i).getKilobytespersecondNetworkTransmit() != null) {
1187                         if (rec.getMachineData().getNetworkAdapterPerformanceData().get(i).getKilobytespersecondNetworkTransmit() > value) {
1188                             return true;
1189                         }
1190                     }
1191                 }
1192 
1193             }
1194             if (r2.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.HighDiskUsage")) {
1195                 if (rec.getMachineData().getDriveInformation().isEmpty()) {
1196                     return false;
1197                 }
1198                 for (int i = 0; i < rec.getMachineData().getDriveInformation().size(); i++) {
1199                     if (rec.getMachineData().getDriveInformation().get(i).getKilobytespersecondDiskRead() != null) {
1200                         if (rec.getMachineData().getDriveInformation().get(i).getKilobytespersecondDiskRead() > value) {
1201                             return true;
1202                         }
1203                     }
1204                     if (rec.getMachineData().getDriveInformation().get(i).getKilobytespersecondDiskWrite() != null) {
1205                         if (rec.getMachineData().getDriveInformation().get(i).getKilobytespersecondDiskWrite() > value) {
1206                             return true;
1207                         }
1208                     }
1209                 }
1210             }
1211 
1212             if (r2.getClassName().equalsIgnoreCase("org.miloss.fgsms.sla.rules.LowDiskSpace")) {
1213                 if (rec.getMachineData().getDriveInformation().isEmpty()) {
1214                     return false;
1215                 }
1216                 NameValuePair p = Utility.getNameValuePairByName(r2.getParameterNameValue(), "partition");
1217                 String partition = null;
1218                 if (val.isEncrypted()) {
1219                     partition = (Utility.DE(val.getValue()));
1220                 } else {
1221                     partition = ((val.getValue()));
1222                 }
1223                 for (int i = 0; i < rec.getMachineData().getDriveInformation().size(); i++) {
1224                     if (rec.getMachineData().getDriveInformation().get(i).getPartition().equalsIgnoreCase(partition)) {
1225                         if (rec.getMachineData().getDriveInformation().get(i).getFreespace() < value) {
1226                             return true;
1227                         }
1228                     }
1229                 }
1230             }
1231 
1232         }
1233 
1234         return false;
1235     }
1236 
1237     private void doRestartComputer() {
1238         log.log(Level.ALL, "RESTART MACHINE TRIGGERED");
1239         Runtime run = Runtime.getRuntime();
1240 
1241         Process pr = null;
1242         try {
1243             if (isWindows) {
1244                 pr = run.exec("shutdown /r /c /f  /d u:00  \"fgsms Agent triggered shutdown\"");
1245             } else {
1246                 pr = run.exec("shutdown now -r");
1247             }
1248         } catch (IOException ex) {
1249             log.log(Level.WARN, "Could not process the SLA restart action", ex);
1250         }
1251 
1252     }
1253 
1254     private void DoRestartProcess(ProcessPolicy p) {
1255         log.log(Level.ALL, "RESTART PROCESS TRIGGERED");
1256         if (p.getURL().startsWith(WINDOWS_KEY)) {
1257             String s = p.getURL().replace(WINDOWS_KEY, null);
1258             ProcInfo pi = new ProcInfo();
1259             try {
1260                 pi.restartWindowsService(s);
1261             } catch (SigarException ex) {
1262                 log.log(Level.WARN, "unable to restart service " + s + " " + p.getURL(), ex);
1263             }
1264 
1265         }
1266         //TODO restart processes for other OS'es
1267 
1268     }
1269 
1270     private ProcessPolicy getPolicy(String uri) {
1271         if (this.processes == null) {
1272             return null;
1273         }
1274         for (int i = 0; i < processes.size(); i++) {
1275             if (processes.get(i).getURL().equalsIgnoreCase(uri)) {
1276                 return processes.get(i);
1277             }
1278         }
1279         return null;
1280     }
1281 
1282     private void runScript(SLAAction slaActionRunScript) {
1283         log.log(Level.ALL, "RUN SCRIPT TRIGGERED");
1284         Runtime run = Runtime.getRuntime();
1285 
1286         if (slaActionRunScript.getImplementingClassName().equalsIgnoreCase("org.miloss.fgsms.sla.actions.SLAActionRunScript")) {
1287             String path = null;
1288 
1289             NameValuePair runAt = Utility.getNameValuePairByName(slaActionRunScript.getParameterNameValue(), "runAt");
1290             NameValuePair runFromPath = Utility.getNameValuePairByName(slaActionRunScript.getParameterNameValue(), "runFromPath");
1291             NameValuePair command = Utility.getNameValuePairByName(slaActionRunScript.getParameterNameValue(), "command");
1292             if (runAt.isEncrypted()) {
1293                 if (!Utility.DE(runAt.getValue()).equalsIgnoreCase("fgsms_AGENT")) {
1294                     return;
1295                 }
1296             }
1297             String runfrom = runFromPath.getValue();
1298             if (runFromPath.isEncrypted()) {
1299                 runfrom = Utility.DE(runFromPath.getValue());
1300             }
1301             String cmd = command.getValue();
1302             if (command.isEncrypted()) {
1303                 cmd = Utility.DE(command.getValue());
1304             }
1305             Process pr = null;
1306             try {
1307                 if (!Utility.stringIsNullOrEmpty(runfrom)) {
1308                     File f = new File(runfrom);
1309                     if (f.exists()) {
1310                         pr = run.exec(cmd, null, f);
1311                     } else {
1312                         pr = run.exec(cmd);
1313                     }
1314                 } else {
1315                     pr = run.exec(cmd);
1316                 }
1317             } catch (IOException ex) {
1318                 log.log(Level.WARN, "Could not process the SLA Run Script action", ex);
1319             }
1320 
1321         }
1322     }
1323 
1324     private void dumpInfo() {
1325         try {
1326             MachineInformation m = gatherInformation();
1327             SetProcessListByMachineRequestMsg req = new SetProcessListByMachineRequestMsg();
1328             req.setAgentType(OSAgent.class.getCanonicalName());
1329             req.setMachineInformation(m);
1330 
1331             if (req.getMachineInformation().getOperatingsystem().toLowerCase().contains("win")) {
1332                 req.getServices().addAll(getServiceList(true));
1333             } else {
1334                 req.getServices().addAll(getServiceList(false));
1335             }
1336             JAXBContext ctx = JAXBContext.newInstance(MachineInformation.class, SetProcessListByMachineRequestMsg.class,
1337                     NetworkAdapterInfo.class, DriveInformation.class, PropertyPair.class, SecurityWrapper.class);
1338             Marshaller createMarshaller = ctx.createMarshaller();
1339             createMarshaller.marshal(req, System.out);
1340         } catch (Exception ex) {
1341             log.log(Level.WARN, null, ex);
1342         }
1343     }
1344 
1345     private String chopWindows(String urL) {
1346         // urn:hostname:path and stuff
1347         int x = urL.indexOf(":");
1348         x = urL.indexOf(":", x);
1349         return urL.substring(x);
1350         // return urL;
1351     }
1352 
1353     private String chopLinux(String urL) {
1354         // urn:hostname:path and stuff
1355         int x = urL.indexOf(":");
1356         x = urL.indexOf(":", x + 1);
1357         return urL.substring(x + 1);
1358         // return urL;
1359     }
1360 
1361     private MachinePolicy loadDefaultMachinePolicy() {
1362         classlevel = new SecurityWrapper();
1363         MachinePolicy mp = new MachinePolicy();
1364         mp.setURL("urn:" + Utility.getHostName() + ":system");
1365         mp.setRecordCPUusage(true);
1366         mp.setRecordMemoryUsage(true);
1367         mp.setMachineName(Utility.getHostName());
1368 
1369         return mp;
1370     }
1371 
1372     private void RUN_DEBUG_TEST() {
1373         System.out.println("Running debug rutine. This will attempt to cause memory leak issues with sigar, hopefully this will run forever without any issues.");
1374         try {
1375             NumberFormat nf = NumberFormat.getNumberInstance();
1376             long it = 0;
1377             refreshInfo();
1378             while (true) {
1379                 System.out.println("iteration " + nf.format(it) + " of " + nf.format(Long.MAX_VALUE));
1380                 log.log(Level.INFO, "Current VM Memory : total = " + nf.format(Runtime.getRuntime().totalMemory()) + " free = " + nf.format(Runtime.getRuntime().freeMemory())
1381                         + " used " + nf.format(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
1382                 it++;
1383                 fire();
1384 
1385             }
1386         } catch (ConfigurationException ex) {
1387             java.util.logging.Logger.getLogger(OSAgent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
1388         } catch (SigarException ex) {
1389             java.util.logging.Logger.getLogger(OSAgent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
1390         } catch (DatatypeConfigurationException ex) {
1391             java.util.logging.Logger.getLogger(OSAgent.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
1392         }
1393 
1394     }
1395 
1396     private void RUN_LEAK_TEST() throws Exception {
1397         NumberFormat nf = NumberFormat.getNumberInstance();
1398         long it = 0;
1399         while (true) {
1400             System.out.println("iteration " + nf.format(it) + " of " + nf.format(Long.MAX_VALUE));
1401             log.log(Level.INFO, "Current VM Memory : total = " + nf.format(Runtime.getRuntime().totalMemory()) + " free = " + nf.format(Runtime.getRuntime().freeMemory())
1402                     + " used " + nf.format(Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()));
1403             it++;
1404             Sigar s = new Sigar();
1405             s.close();
1406             Ps ps = new Ps();
1407             ps.close();
1408             Df df = new Df();
1409             df.close();
1410             ProcFileInfo pfi = new ProcFileInfo();
1411             pfi.close();;
1412             ProcInfo pi = new ProcInfo();
1413             pi.close();
1414             SysInfo si = new SysInfo();
1415             si.close();
1416             Ifconfig ic = new Ifconfig();
1417             ic.close();
1418         }
1419     }
1420 
1421     private void printUsage() {
1422         System.out.println("help - Shows this help message (duh)");
1423         System.out.println("dump - Dumps configuration information as identified by this agent to console in XML");
1424         System.out.println("debug - Logs additional debugging information");
1425         System.out.println("nosend - Performs all calculations, it just doesn't send the data back to fgsms. It does not delay between iterations");
1426         System.out.println("runleaktest - Performs a memory leak test for access sigars. If reliability problems occur, this may help identify the cause.");
1427 
1428         System.out.println("Use -Dsensorconfig=pathto/sensor.properties to use an alternative sensor configuration file");
1429     }
1430 
1431     protected void startSensorFeeds() {
1432         log.log(Level.INFO, "Starting sensor feeds");
1433         sensorconfig = loadSensorConfig();
1434         if (sensorconfig == null) {
1435             log.log(Level.INFO, "unable to load sensor.properties, sensor data will be unavailable");
1436             return;
1437         }
1438         String providers = sensorconfig.getProperty("sensorProviders");
1439         if (providers != null) {
1440             providers = providers.trim();
1441             String[] ps = providers.split(",");
1442             for (int i = 0; i < ps.length; i++) {
1443                 ISensorProvider instance = SensorProviderFactory.getInstance(ps[i].trim());
1444                 if (instance != null) {
1445                     sensors.add(instance);
1446                     instance.init(sensorconfig);
1447                 }
1448             }
1449         }
1450         log.log(Level.INFO, sensors.size() + " sensor providers loaded");
1451     }
1452 
1453     /**
1454      *
1455      * system properties for a value first check local file system check
1456      * classpath
1457      *
1458      * @return
1459      */
1460     private Properties loadSensorConfig() {
1461         File f = null;
1462         if (System.getProperty("sensorconfig") != null) {
1463             f = new File(System.getProperty("sensorconfig"));
1464         } else {
1465             f = new File("sensor.properties");
1466         }
1467 
1468         InputStream is = null;
1469         Properties p = new Properties();
1470         FileInputStream fis = null;
1471         if (f.exists()) {
1472             try {
1473 
1474                 fis = new FileInputStream(file);
1475                 is = fis;
1476                 log.log(Level.INFO, "Sensor Config loaded from file system " + f.getAbsolutePath() + " use -Dsensorconfig=PATH/FILE to override");
1477             } catch (Exception ex) {
1478                 log.log(Level.DEBUG, null, ex);
1479             }
1480         }
1481         if (is == null) {
1482             is = Thread.currentThread().getContextClassLoader().getResourceAsStream("sensor.properties");
1483             log.log(Level.INFO, "Sensor Config loaded from class path (probably within fgsms.OSBuellerNextGen.jar" + " use -Dsensorconfig=PATH/FILE to override");
1484         }
1485         if (is != null) {
1486             try {
1487                 p.load(is);
1488                 is.close();
1489             } catch (Exception ex) {
1490                 log.log(Level.WARN, null, ex);
1491                 p = null;
1492             } finally {
1493                 try {
1494                     is.close();
1495                     if (fis != null) {
1496                         fis.close();
1497                     }
1498                 } catch (Exception x) {
1499                     log.log(Level.DEBUG, null, x);
1500                 }
1501             }
1502         }
1503 
1504         return p;
1505     }
1506 
1507     private void stopAllSensors() {
1508         if (sensors == null) {
1509             return;
1510         }
1511         for (int i = 0; i < sensors.size(); i++) {
1512             sensors.get(i).stop();
1513             sensors = null;
1514         }
1515     }
1516 
1517     private NameValuePairSet getSensorData() {
1518         if (sensors == null || sensors.isEmpty()) {
1519             return null;
1520         }
1521         NameValuePairSet set = new NameValuePairSet();
1522 
1523         for (int i = 0; i < sensors.size(); i++) {
1524             try {
1525                 set.getItems().add(sensors.get(i).getSensorData());
1526             } catch (Exception ex) {
1527                 log.log(Level.WARN, "unexpected error fetching sensor data", ex);
1528             }
1529         }
1530         if (set.getItems().isEmpty()) {
1531             return null;
1532         }
1533         return set;
1534     }
1535 
1536     private void printSigarInfo() throws Exception {
1537         SigarLoader loader = new SigarLoader(Sigar.class);
1538         System.out.println(loader.getLibraryName());
1539         System.out.println(loader.getArchLibName());
1540         System.out.println(loader.getDefaultLibName());
1541         System.out.println(loader.getName());
1542         System.out.println(loader.getNativeLibrary());
1543         System.out.println(loader.getPackageName());
1544         
1545     }
1546 
1547     public class RunWhenShuttingDown extends Thread {
1548 
1549         public void run() {
1550             System.out.println("Control-C caught. Shutting down...");
1551             log.log(Level.INFO, "Stopping Persistent Storage Agent");
1552             PersistentStorage.stop(null);
1553             running = false;
1554             while (!done) {
1555                 try {
1556                     Thread.sleep(1000);
1557                 } catch (InterruptedException ex) {
1558                 }
1559             }
1560             stopAllSensors();
1561             closeLock();
1562             deleteFile();
1563             try {
1564                 org.miloss.fgsms.agentcore.StatusHelper.tryUpdateStatus(false, "urn:" + Utility.getHostName() + ":system", "Agent Stopped", false, PolicyType.MACHINE, Constants.UNSPECIFIED, Utility.getHostName());
1565             } catch (ConfigurationException ex) {
1566                 System.err.println("Unable to send status update. Configuration error.");
1567             }
1568         }
1569     }
1570 }