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.agentcore;
22  
23  import java.io.InputStream;
24  import java.net.HttpURLConnection;
25  import java.net.URL;
26  import java.util.HashMap;
27  import java.util.Iterator;
28  import java.util.List;
29  import java.util.Map;
30  import javax.wsdl.*;
31  import javax.wsdl.xml.WSDLReader;
32  import javax.xml.parsers.DocumentBuilderFactory;
33  import javax.xml.ws.handler.soap.SOAPMessageContext;
34  import org.miloss.fgsms.common.Utility;
35  import org.apache.log4j.Level;
36  import org.miloss.fgsms.common.Logger;;
37  import org.w3c.dom.Document;
38  
39  /**
40   * Experimental, determines if a URI/SOAP Action is an
41   *
42   * @OneWAY transaction by pulling the wsdl and parsing
43   * @author AO
44   * @since 6.2
45   */
46  public class OneWayJudge {
47  
48      final static Logger log = Logger.getLogger(org.miloss.fgsms.common.Constants.LoggerName);
49      final static Map<String, Boolean> cache = new HashMap<String, Boolean>();
50  
51      /**
52       * attempts to determine if the SOAP service is a one way transaction by parsing the wsdl
53       * @param requestURL
54       * @param messageContext
55       * @param action
56       * @return 
57       */
58      public static boolean determineOneWay(String requestURL, SOAPMessageContext messageContext, String action) {
59          String actionLastPart = ToShortActionString(action);
60          if (cache.containsKey(requestURL + "|" + actionLastPart)) {
61              log.log(Level.DEBUG, "determined @OneWAY from cache");
62              return cache.get(requestURL + "|" + actionLastPart);
63          }
64  
65          //TODO handle ssl, ssl with auth? 
66  
67          log.log(Level.INFO, "Operation mappings not available for " + requestURL + " " + action + " attempting to load the wsdl and cache");
68          try {
69              HttpURLConnection conn = (HttpURLConnection) new URL(requestURL + "?wsdl").openConnection();
70              conn.setRequestMethod("GET");
71  
72              InputStream inputStream = conn.getInputStream();
73              conn.connect();
74  
75              WSDLReader newWSDLReader = javax.wsdl.factory.WSDLFactory.newInstance().newWSDLReader();
76              DocumentBuilderFactory f = DocumentBuilderFactory.newInstance();
77              f.setNamespaceAware(true);
78              Document doc = f.newDocumentBuilder().parse(inputStream);
79              conn.disconnect();
80              Definition readWSDL = newWSDLReader.readWSDL(null, doc);
81  
82              Map allPortTypes = readWSDL.getAllPortTypes();
83              Iterator ports = allPortTypes.keySet().iterator();
84              while (ports.hasNext()) //for each port
85              {
86                  Object t = ports.next();
87                  PortType portType = (PortType) allPortTypes.get(t);
88                  List operations = portType.getOperations();
89                  for (int i = 0; i < operations.size(); i++) {
90                      Operation operation = (Operation) operations.get(i);
91                      cache.put(requestURL + "|" + operation.getName(), operation.getOutput() == null || operation.getStyle().equals(OperationType.ONE_WAY));
92                  }
93              }
94  
95              if (cache.containsKey(requestURL + "|" + actionLastPart)) {
96                  return cache.get(requestURL + "|" + actionLastPart);
97              }
98              log.log(Level.WARN, "the action " + action + " couldn't be found in the wsdl. I'm guessing that its NOT a one way transaction.");
99              cache.put(requestURL + "|" + actionLastPart, false);
100         } catch (Exception ex) {
101             log.log(Level.WARN, "OneWAY  detected failed " + ex.getMessage());
102             cache.put(requestURL + "|" + actionLastPart, false);
103 
104             return false;
105         }
106         return false;
107     }
108 
109     private static String ToShortActionString(String action) {
110         if (Utility.stringIsNullOrEmpty(action)) {
111             return "";
112         }
113         String ret = action;
114         int clip = 0;
115         if (ret.lastIndexOf("/") > clip) {
116             clip = ret.lastIndexOf("/");
117         }
118         if (ret.lastIndexOf("}") > clip) {
119             clip = ret.lastIndexOf("}");
120         }
121         if (ret.lastIndexOf(":") > clip) {
122             clip = ret.lastIndexOf(":");
123         }
124         if (ret.lastIndexOf("#") > clip) {
125             clip = ret.lastIndexOf("#");
126         }
127 
128         if (clip > 0) {
129             ret = (ret.substring(clip + 1));
130         }
131         return ret;
132 
133     }
134 }