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  package org.miloss.fgsms.sla.rules;
22  
23  import java.io.ByteArrayInputStream;
24  import java.sql.Connection;
25  import java.sql.PreparedStatement;
26  import java.sql.ResultSet;
27  import java.util.ArrayList;
28  import java.util.GregorianCalendar;
29  import java.util.List;
30  import java.util.concurrent.atomic.AtomicReference;
31  import javax.xml.bind.JAXBContext;
32  import javax.xml.bind.JAXBElement;
33  import javax.xml.bind.Unmarshaller;
34  import javax.xml.datatype.DatatypeFactory;
35  import javax.xml.stream.XMLInputFactory;
36  import javax.xml.stream.XMLStreamReader;
37  import org.apache.log4j.Level;
38  import org.miloss.fgsms.common.Logger;;
39  import org.miloss.fgsms.common.Utility;
40  import org.miloss.fgsms.plugins.sla.AlertType;
41  import org.miloss.fgsms.plugins.sla.SLARuleInterface;
42  import org.miloss.fgsms.services.interfaces.common.MachinePerformanceData;
43  import org.miloss.fgsms.services.interfaces.common.NameValuePair;
44  import org.miloss.fgsms.services.interfaces.common.PolicyType;
45  import org.miloss.fgsms.services.interfaces.common.ProcessPerformanceData;
46  import org.miloss.fgsms.services.interfaces.datacollector.AddDataRequestMsg;
47  import org.miloss.fgsms.services.interfaces.datacollector.BrokerData;
48  import org.miloss.fgsms.services.interfaces.policyconfiguration.GetProcessesListByMachineResponseMsg;
49  import org.miloss.fgsms.services.interfaces.policyconfiguration.MachinePolicy;
50  import org.miloss.fgsms.services.interfaces.policyconfiguration.ServicePolicy;
51  import org.miloss.fgsms.services.interfaces.policyconfiguration.SetProcessListByMachineRequestMsg;
52  import org.miloss.fgsms.services.interfaces.status.SetStatusRequestMsg;
53  
54  /**
55   *
56   * @author AO
57   */
58  public class LowDiskSpace implements SLARuleInterface {
59  
60      private static Logger log = Logger.getLogger("fgsms.SLAProcessor");
61  
62      @Override
63      public boolean CheckTransactionalRule(SetStatusRequestMsg req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
64          return false;
65      }
66  
67      @Override
68      public boolean CheckTransactionalRule(ProcessPerformanceData req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
69          return false;
70      }
71  
72      @Override
73      public boolean CheckTransactionalRule(MachinePerformanceData req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
74          if (nullableFaultMsg == null) {
75              nullableFaultMsg = new AtomicReference<String>();
76          }
77          NameValuePair partition = Utility.getNameValuePairByName(params, "partition");
78          NameValuePair value = Utility.getNameValuePairByName(params, "value");
79          long val = 0;
80          String part = partition.getValue();
81          if (partition.isEncrypted()) {
82              part = Utility.DE(partition.getValue());
83          }
84          if (value.isEncrypted()) {
85              val = Long.parseLong(Utility.DE(value.getValue()));
86          } else {
87              val = Long.parseLong((value.getValue()));
88          }
89  
90          for (int i = 0; i < req.getDriveInformation().size(); i++) {
91              if (req.getDriveInformation().get(i).getPartition().equalsIgnoreCase(part)) {
92                  if (req.getDriveInformation().get(i).getFreespace() < val) {
93                      nullableFaultMsg.set("The partion's freespace, " + req.getDriveInformation().get(i).getFreespace() + " is less than the threshold of " + val + ". " + nullableFaultMsg.get());
94                  }
95                  return true;
96              }
97          }
98  
99          return false;
100     }
101 
102     @Override
103     public boolean CheckTransactionalRule(AddDataRequestMsg req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
104         return false;
105     }
106 
107     @Override
108     public boolean CheckTransactionalRule(String url, List<BrokerData> data, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
109         return false;
110     }
111 
112     @Override
113     public boolean CheckNonTransactionalRule(ServicePolicy pol, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg, boolean pooled) {
114         return false;
115     }
116 
117     @Override
118     public String GetDisplayName() {
119         return "Low disk space on a partition or drive";
120     }
121 
122     @Override
123     public String GetHtmlFormattedHelp() {
124         return "This rule will trigger when a partition's free disk space becomes less than the threshold 'value'. <br><br>"
125                 + "Required parameters:"
126                 + "<ul>"
127                 + "<li>partition - the name of the partition. It must exist and must be monitored</li>"
128                 + "<li>value - the size in megabytes</li>"
129                 + "</ul>";
130     }
131 
132     @Override
133     public List<NameValuePair> GetRequiredParameters() {
134         ArrayList<NameValuePair> arrayList = new ArrayList<NameValuePair>();
135         arrayList.add(Utility.newNameValuePair("partition", null, false, false));
136         arrayList.add(Utility.newNameValuePair("value", null, false, false));
137         return arrayList;
138     }
139 
140     @Override
141     public List<NameValuePair> GetOptionalParameters() {
142         return new ArrayList<NameValuePair>();
143     }
144 
145     @Override
146     public boolean ValidateConfiguration(List<NameValuePair> params, AtomicReference<String> outError, ServicePolicy policy) {
147 
148         if (outError == null) {
149             outError = new AtomicReference<String>();
150         }
151 
152         if (!(policy instanceof MachinePolicy)) {
153             outError.set("This rule only applies to Machine Policies. " + outError.get());
154             return false;
155         }
156 
157         boolean partitionfound = false;
158         boolean valuefound = false;
159         //fetch partition from params
160         long value = -1;
161         String partition = null;
162         for (int i = 0; i < params.size(); i++) {
163 
164             if (params.get(i).getName().equals("partition")) {
165                 partitionfound = true;
166                 if (Utility.stringIsNullOrEmpty(params.get(i).getValue())) {
167                     outError.set("A value must be specified for the parameter 'partition'. " + outError.get());
168                 }
169                 if (params.get(i).isEncrypted()) {
170                     partition = Utility.DE(params.get(i).getValue());
171                 } else {
172                     partition = (params.get(i).getValue());
173                 }
174             }
175             if (params.get(i).getName().equals("value")) {
176                 valuefound = true;
177                 if (Utility.stringIsNullOrEmpty(params.get(i).getValue())) {
178                     outError.set("A value must be specified for the parameter 'value'. " + outError.get());
179                 }
180                 try {
181                     value = Long.parseLong(params.get(i).getValue());
182                     if (value < 0) {
183                         outError.set("The parameter 'value' must be greater than or equal to zero. " + outError.get());
184                     }
185                 } catch (Exception ex) {
186                     outError.set("Bad value for parameter 'value'. It must be an integer or long. Message:" + ex.getMessage() + ". " + outError.get());
187                 }
188             }
189         }
190 
191         if (!partitionfound) {
192             outError.set("The parameter 'partition' is required. " + outError.get());
193         }
194         if (!valuefound) {
195             outError.set("The parameter 'value' is required. " + outError.get());
196         }
197 
198         MachinePolicy pol = (MachinePolicy) policy;
199         //confirm that the low disk space parition exists on the machine and is being monitored.
200 
201         if (partitionfound) {
202             boolean driveismonitored = false;
203             GetProcessesListByMachineResponseMsg data = GetMachineInfo(policy.getMachineName(), policy.getDomainName());
204             if (!ConfirmDriveExists(data, partition)) {
205                 outError.set("The partition " + partition + " must exist on the machine being monitored. " + outError.get());
206             }
207             for (int k = 0; k < pol.getRecordDiskSpace().size(); k++) {
208                 if (pol.getRecordDiskSpace().get(k).equalsIgnoreCase(partition)) {
209                     driveismonitored = true;
210                 }
211             }
212             if (!driveismonitored) {
213                 outError.set("The partition " + partition + " s not currently being monitored, please add it to the list of monitored partitions then you can add this SLA Rule. " + outError.get());
214             }
215         }
216         if (Utility.stringIsNullOrEmpty(outError.get())) {
217             return true;
218         } else {
219             return false;
220         }
221 
222     }
223 
224     /**
225      *
226      * @param data
227      * @param partition
228      * @return true if valid
229      */
230     private boolean ConfirmDriveExists(GetProcessesListByMachineResponseMsg data, String partition) {
231         if (data == null) {
232             return false;
233         }
234         if (data.getMachineInformation() == null) {
235             return false;
236         }
237         if (data.getMachineInformation().getDriveInformation() == null) {
238             return false;
239         }
240         for (int i = 0; i < data.getMachineInformation().getDriveInformation().size(); i++) {
241             if (data.getMachineInformation().getDriveInformation().get(i).getPartition().equalsIgnoreCase(partition)) {
242                 return true;
243             }
244         }
245         return false;
246     }
247 
248     private GetProcessesListByMachineResponseMsg GetMachineInfo(String hostname, String domain) {
249         try {
250 
251             GetProcessesListByMachineResponseMsg response = new GetProcessesListByMachineResponseMsg();
252 
253             PreparedStatement comm = null;
254             Connection con = Utility.getConfigurationDBConnection();
255             
256             JAXBContext jc = Utility.getSerializationContext();
257             comm = con.prepareStatement(""
258                     + "select * from machineinfo where hostname=? and domaincol=?;");
259             comm.setString(1, hostname);
260             comm.setString(2, domain);
261             ResultSet rs = comm.executeQuery();
262             if (rs.next()) {
263                 GregorianCalendar gcal = new GregorianCalendar();
264                 gcal.setTimeInMillis(rs.getLong("lastchanged"));
265                 response.setLastupdateat((gcal));
266                 Unmarshaller u = jc.createUnmarshaller();
267                 byte[] s = rs.getBytes("xmlcol");
268 
269                 ByteArrayInputStream bss = new ByteArrayInputStream(s);
270                 //1 = reader
271                 //2 = writer
272                 //                XMLStreamReaderImpl r = new XMLStreamReaderImpl(bss, new PropertyManager(1));
273                 XMLInputFactory xf = XMLInputFactory.newInstance();
274                 XMLStreamReader r = xf.createXMLStreamReader(bss);
275 
276                 JAXBElement<SetProcessListByMachineRequestMsg> foo = (JAXBElement<SetProcessListByMachineRequestMsg>) u.unmarshal(r, SetProcessListByMachineRequestMsg.class);
277                 if (foo == null || foo.getValue() == null) {
278                     log.log(Level.WARN, "xml is unexpectedly null or empty");
279                 } else {
280                     response.setMachineInformation(foo.getValue().getMachineInformation());
281                     response.getProcessName().addAll(foo.getValue().getServices());
282                 }
283             }
284 
285 
286             rs.close();
287             comm.close();
288             con.close();
289             return response;
290         } catch (Exception ex) {
291             log.log(Level.ERROR, "error caught loading machine information", ex);
292             return null;
293         }
294     }
295     
296        @Override
297     public AlertType GetType() {
298        return AlertType.Performance;
299     }
300        
301        @Override
302     public String GetHtmlFormattedDisplay(List<NameValuePair> params) {
303        NameValuePair mc = Utility.getNameValuePairByName(params, "value");
304         String item = UNDEFINED_VALUE;
305         if (mc != null) {
306             item = mc.getValue();
307             if (mc.isEncrypted() || mc.isEncryptOnSave()) {
308                 item = ENCRYPTED_MASK;
309             }
310         }
311         
312         NameValuePair mc2 = Utility.getNameValuePairByName(params, "partition");
313         String item2 = UNDEFINED_VALUE;
314         if (mc2 != null) {
315             item2 = mc2.getValue();
316             if (mc2.isEncrypted() || mc2.isEncryptOnSave()) {
317                 item2 = ENCRYPTED_MASK;
318             }
319         }
320         return Utility.encodeHTML(GetDisplayName() + " " + item2 + " " + item+"MB");
321     }
322        
323          @Override
324     public List<PolicyType> GetAppliesTo() {
325          List<PolicyType> x = new ArrayList<PolicyType>();
326          x.add(PolicyType.MACHINE);
327       
328          
329          return x;
330     }
331 }