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.sla.rules;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.IOException;
24  import java.io.InputStream;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.concurrent.atomic.AtomicReference;
28  import java.util.logging.Level;
29  import javax.xml.parsers.DocumentBuilderFactory;
30  import javax.xml.xpath.XPath;
31  import javax.xml.xpath.XPathConstants;
32  import javax.xml.xpath.XPathFactory;
33  import org.miloss.fgsms.common.Constants;
34  import org.miloss.fgsms.common.Logger;
35  ;
36  import org.miloss.fgsms.common.Utility;
37  import org.miloss.fgsms.plugins.sla.AlertType;
38  import org.miloss.fgsms.plugins.sla.SLARuleInterface;
39  import org.miloss.fgsms.services.interfaces.common.MachinePerformanceData;
40  import org.miloss.fgsms.services.interfaces.common.NameValuePair;
41  import org.miloss.fgsms.services.interfaces.common.PolicyType;
42  import org.miloss.fgsms.services.interfaces.common.ProcessPerformanceData;
43  import org.miloss.fgsms.services.interfaces.datacollector.AddDataRequestMsg;
44  import org.miloss.fgsms.services.interfaces.datacollector.BrokerData;
45  import org.miloss.fgsms.services.interfaces.policyconfiguration.ServicePolicy;
46  import org.miloss.fgsms.services.interfaces.policyconfiguration.TransactionalWebServicePolicy;
47  import org.miloss.fgsms.services.interfaces.status.SetStatusRequestMsg;
48  import org.w3c.dom.Document;
49  
50  /**
51   *
52   * @author AO
53   */
54  
55  
56  public class XPathExpression implements SLARuleInterface {
57  
58      @Override
59      public boolean CheckTransactionalRule(SetStatusRequestMsg req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
60          return false;
61      }
62  
63      @Override
64      public boolean CheckTransactionalRule(ProcessPerformanceData req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
65          return false;
66      }
67  
68      @Override
69      public boolean CheckTransactionalRule(MachinePerformanceData req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
70          return false;
71      }
72      static final Logger log = Logger.getLogger("fgsms.SLAProcessor");
73  
74      @Override
75      public boolean CheckTransactionalRule(AddDataRequestMsg req, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
76          if (nullableFaultMsg == null) {
77              nullableFaultMsg = new AtomicReference<String>();
78          }
79          NameValuePair mc = Utility.getNameValuePairByName(params, "MessageChoice");
80          String item = mc.getValue();
81          if (mc.isEncrypted()) {
82              item = Utility.DE(mc.getValue());
83          }
84          NameValuePair xpath = Utility.getNameValuePairByName(params, "XPath");
85          String xpathi = xpath.getValue();
86          if (xpath.isEncrypted()) {
87              xpathi = Utility.DE(xpath.getValue());
88          }
89          InputStream is = null;
90          try {
91  
92              if (item.equalsIgnoreCase("request")) {
93                  is = new ByteArrayInputStream(req.getXmlRequest().getBytes(Constants.CHARSET));
94              } else {
95                  is = new ByteArrayInputStream(req.getXmlResponse().getBytes(Constants.CHARSET));
96              }
97              Document xmlDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(is);
98              is.close();
99              XPath xp = XPathFactory.newInstance().newXPath();
100             javax.xml.xpath.XPathExpression xpc = xp.compile(xpathi);
101             Boolean result = (Boolean) xpc.evaluate(xmlDocument, XPathConstants.BOOLEAN);
102             if (result) {
103                 nullableFaultMsg.set("Xpath expression " + xpathi + " result in TRUE. " + nullableFaultMsg.get());
104                 return true;
105             }
106         } catch (Exception ex) {
107             log.error("SLA Processing failed for " + req.getURI(), ex);
108         } finally {
109             if (is!=null)
110             try {
111                 is.close();
112             } catch (IOException ex) {
113 
114             }
115         }
116         return false;
117     }
118 
119     @Override
120     public boolean CheckTransactionalRule(String url, List<BrokerData> data, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg) {
121         return false;
122     }
123 
124     @Override
125     public boolean CheckNonTransactionalRule(ServicePolicy pol, List<NameValuePair> params, AtomicReference<String> nullableFaultMsg, boolean pooled) {
126         return false;
127     }
128 
129     @Override
130     public String GetDisplayName() {
131         return "Evaluate XPath expression";
132     }
133 
134     @Override
135     public String GetHtmlFormattedHelp() {
136         return "This rule triggers when the specified XPath expression evaluates to true when processed against a request or response message. "
137                 + "This rule always processes on the fgsms Server, requires the request and/or response to be recorded"
138                 + " and applies only to transactional service policies. <br><br>"
139                 + "Required parameters:"
140                 + "<ul>"
141                 + "<li>MessageChoice - must be either Request or Response</li>"
142                 + "<li>XPath - an XPath expression that evaluates to true or false</li>"
143                 //   + "<li>XMLNamespacePrefixies - this must be in the format prefix||Namespace||prefix||Namespace....</li>"
144                 + "</ul>";
145     }
146 
147     @Override
148     public List<NameValuePair> GetRequiredParameters() {
149         ArrayList<NameValuePair> arrayList = new ArrayList<NameValuePair>();
150         arrayList.add(Utility.newNameValuePair("MessageChoice", null, false, false));
151         arrayList.add(Utility.newNameValuePair("XPath", null, false, false));
152         //arrayList.add(Utility.newNameValuePair("IsCertificate", null, false, false));
153         //  arrayList.add(Utility.newNameValuePair("XMLNamespacePrefixies", null, false, false));
154 
155         return arrayList;
156     }
157 
158     @Override
159     public List<NameValuePair> GetOptionalParameters() {
160         return new ArrayList<NameValuePair>();
161     }
162 
163     @Override
164     public AlertType GetType() {
165         return AlertType.Performance;
166     }
167 
168     @Override
169     public boolean ValidateConfiguration(List<NameValuePair> params, AtomicReference<String> outError, ServicePolicy policy) {
170 
171         if (outError == null) {
172             outError = new AtomicReference<String>();
173         }
174         if (params == null || params.isEmpty()) {
175             outError.set("The parameter 'MessageChoice' and 'XPath' are required. " + outError.get());
176         }
177         if (!(policy instanceof TransactionalWebServicePolicy)) {
178             outError.set("This rule only applies to Transactional Service Policies. " + outError.get());
179         }
180         boolean foundLogger = false;
181         boolean foundLogge2r = false;
182         for (int i = 0; i < params.size(); i++) {
183             if (params.get(i).getName().equals("MessageChoice")) {
184                 foundLogger = true;
185                 if (Utility.stringIsNullOrEmpty(params.get(i).getValue())) {
186                     outError.set("A value must be specified for the parameter 'MessageChoice'. " + outError.get());
187                 }
188             }
189             if (params.get(i).getName().equals("XPath")) {
190                 foundLogge2r = true;
191                 if (Utility.stringIsNullOrEmpty(params.get(i).getValue())) {
192                     outError.set("A value must be specified for the parameter 'XPath'. " + outError.get());
193                 }
194             }
195         }
196         if (!foundLogger) {
197             outError.set("The parameter 'MessageChoice' is required. " + outError.get());
198         }
199         if (!foundLogge2r) {
200             outError.set("The parameter 'XPath' is required. " + outError.get());
201         }
202         if (Utility.stringIsNullOrEmpty(outError.get())) {
203             return true;
204         } else {
205             return false;
206         }
207     }
208 
209     @Override
210     public String GetHtmlFormattedDisplay(List<NameValuePair> params) {
211         NameValuePair mc = Utility.getNameValuePairByName(params, "MessageChoice");
212         String item = UNDEFINED_VALUE;
213         if (mc != null) {
214             item = mc.getValue();
215             if (mc.isEncrypted() || mc.isEncryptOnSave()) {
216                 item = ENCRYPTED_MASK;
217             }
218         }
219         String xpathi = UNDEFINED_VALUE;
220 
221         NameValuePair xpath = Utility.getNameValuePairByName(params, "XPath");
222         if (xpath != null) {
223             xpathi = xpath.getValue();
224             if (xpath.isEncrypted() || mc.isEncryptOnSave()) {
225                 xpathi = ENCRYPTED_MASK;
226             }
227         }
228         return GetDisplayName() + " " + Utility.encodeHTML(xpathi) + " on " + Utility.encodeHTML(item);
229     }
230 
231     @Override
232     public List<PolicyType> GetAppliesTo() {
233         List<PolicyType> ret = new ArrayList<PolicyType>();
234         ret.add(PolicyType.TRANSACTIONAL);
235         return ret;
236     }
237 }