// Copyright 2012 Georg-August-Universität Göttingen, Germany // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package de.ugoe.cs.autoquest.plugin.http.eventcore; import java.net.MalformedURLException; import java.net.URL; import java.util.Properties; import java.util.logging.Level; import javax.xml.soap.SOAPException; import javax.xml.soap.SOAPMessage; import org.w3c.dom.Element; import de.ugoe.cs.autoquest.plugin.http.HTTPUtils; import de.ugoe.cs.autoquest.plugin.http.logdata.Header; import de.ugoe.cs.autoquest.plugin.http.logdata.HttpExchange; import de.ugoe.cs.util.console.Console; /** *

* represents the specific HTTP event for a SOAP message exchange. It contains the SOAP request * and response envelopes and is more concrete when comparing object. E.g., it considers the * called SOAP operation on performing comparison. *

* * @author Patrick Harms */ public final class SOAPEventType extends HTTPEventType { /** */ private static final long serialVersionUID = 1L; /** *

* the SOAP request belonging to the event *

*/ transient private final SOAPMessage soapRequest; /** *

* the SOAP response belonging to the event *

*/ transient private final SOAPMessage soapResponse; /** *

* the SOAP method called in this request *

*/ private final String calledMethod; /** *

* the name of the client; this is either the host/ip and port of the sender or, if a path * map is available, a human readable name that may be based also on the receiver *

*/ private final String clientName; /** *

* the name of the service; this is either the path or, if a path map is available, a human * readable name that is mapped to the path *

*/ private final String serviceName; /** *

* the human readable name of this event type *

*/ private final String name; /** *

* initializes the event type with the represented HTTP exchange and the already extracted * SOAP request and response. *

* * @param exchange the represented HTTP exchange * @param soapRequest the already extracted SOAP request * @param soapResponse the already extracted SOAP response * @param urlNameMap used to map paths of servives to logical names */ public SOAPEventType(HttpExchange exchange, SOAPMessage soapRequest, SOAPMessage soapResponse, Properties urlNameMap) { super(exchange); this.soapRequest = soapRequest; this.soapResponse = soapResponse; this.calledMethod = normalizeCalledMethod(determineCalledMethod(exchange, soapRequest)); String path = null; if ((exchange.getRequest() != null) && (exchange.getRequest().getUrl() != null)) { try { path = new URL(exchange.getRequest().getUrl()).getPath(); } catch (MalformedURLException e) { // ignore and continue } } StringBuffer nameBuffer = new StringBuffer("SOAPEvent"); // determine the client name if (urlNameMap == null) { clientName = exchange.getSender().getHost() + ":" + exchange.getSender().getPort(); } else { // check for a mapping of the sender host String key = "clientName.sender." + exchange.getSender().getHost(); String value = urlNameMap.getProperty(key); if (value == null) { key += ":" + exchange.getSender().getPort(); value = urlNameMap.getProperty(key); } if (value == null) { key = "clientName.receiver.server." + exchange.getReceiver().getHost(); value = urlNameMap.getProperty(key); } if (value == null) { key += ":" + exchange.getReceiver().getPort(); value = urlNameMap.getProperty(key); } if (value == null) { key = "clientName.receiver.port." + exchange.getReceiver().getPort(); value = urlNameMap.getProperty(key); } if (value == null) { key = "clientName.default"; value = urlNameMap.getProperty(key); } if (value != null) { clientName = value; } else { clientName = exchange.getSender().getHost() + ":" + exchange.getSender().getPort(); } } nameBuffer.append("("); nameBuffer.append(clientName); // determine the service name if (path != null) { nameBuffer.append(", "); if (urlNameMap == null) { serviceName = path; } else { String value = urlNameMap.getProperty("serviceName.path." + path); if (value != null) { serviceName = value; } else { serviceName = path; } } nameBuffer.append(serviceName); } else { serviceName = "NA"; } if (calledMethod != null) { nameBuffer.append(", "); nameBuffer.append(calledMethod); } String senderStr = HTTPUtils.toString(exchange.getSender()); String receiverStr = HTTPUtils.toString(exchange.getReceiver()); if ((senderStr != null) && (receiverStr != null)) { nameBuffer.append(", "); nameBuffer.append(senderStr); nameBuffer.append(" --> "); nameBuffer.append(receiverStr); } else if (senderStr != null) { nameBuffer.append(", "); nameBuffer.append(senderStr); } else if (receiverStr != null) { nameBuffer.append(", "); nameBuffer.append(receiverStr); } nameBuffer.append(")"); this.name = nameBuffer.toString(); } /** *

* the SOAP method called in this request *

* * @return the SOAP method called in this request */ public String getCalledMethod() { return calledMethod; } /** *

* the name of the client calling in this request *

* * @return the name of the client calling in this request */ public String getClientName() { return clientName; } /** *

* the name of the service called in this request *

* * @return the name of the service called in this request */ public String getServiceName() { return serviceName; } /** * @return the soapRequest */ public SOAPMessage getSoapRequest() { return soapRequest; } /** * @return the soapResponse */ public SOAPMessage getSoapResponse() { return soapResponse; } /** * @return the body of the soapRequest */ public Element getSoapRequestBody() { try { return soapRequest.getSOAPBody(); } catch (SOAPException e) { return null; } } /** * @return the body of the soapResponse */ public Element getSoapResponseBody() { try { if( soapResponse!=null ) { return soapResponse.getSOAPBody(); } else { return null; } } catch (SOAPException e) { return null; } } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.eventcore.IEventType#getName() */ @Override public String getName() { return name; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#toString() */ @Override public String toString() { return name; } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (this == obj) { return true; } else if (obj instanceof SOAPEventType) { if (!obj.getClass().isAssignableFrom(this.getClass())) { return false; } return super.equals(obj) && HTTPUtils.equals(calledMethod, ((SOAPEventType) obj).calledMethod) && HTTPUtils.equals(serviceName, ((SOAPEventType) obj).serviceName) && HTTPUtils.equals(clientName, ((SOAPEventType) obj).clientName); } else { return false; } } /* (non-Javadoc) * @see de.ugoe.cs.autoquest.plugin.http.eventcore.HTTPEventType#hashCode() */ @Override public int hashCode() { int hashCode = super.hashCode(); if (calledMethod != null) { hashCode += calledMethod.hashCode(); } if( serviceName != null ) { hashCode += serviceName.hashCode(); } if( clientName != null ) { hashCode += clientName.hashCode(); } return hashCode; } /** *

* determines the name of the method called in a SOAP request either through the HTTP header * or through the SOAP body *

*/ private String determineCalledMethod(HttpExchange exchange, SOAPMessage soapRequest) { // first check for a header containing the SOAP action if ((exchange.getRequest() != null) && (exchange.getRequest().getHeaders() != null) && (exchange.getRequest().getHeaders().getHeader() != null)) { for (Header header : exchange.getRequest().getHeaders().getHeader()) { if ("SOAPAction".equalsIgnoreCase(header.getKey())) { return header.getValue(); } } } // if there is none, use the root element of the body try { if ((soapRequest.getSOAPBody() != null) && (soapRequest.getSOAPBody().getChildNodes() != null) && (soapRequest.getSOAPBody().getChildNodes().getLength() > 0)) { return soapRequest.getSOAPBody().getChildNodes().item(0).getNodeName(); } } catch (SOAPException e) { Console.traceln(Level.WARNING, "could not process SOAP message correctly: " + e); Console.logException(e); } return null; } /** * removes unnecessary characters from the method name */ private String normalizeCalledMethod(String calledMethod) { if (calledMethod != null) { if (calledMethod.startsWith("\"") && calledMethod.endsWith("\"")) { calledMethod = calledMethod.substring(1, calledMethod.length() - 1); } if (calledMethod.startsWith("urn:")) { calledMethod = calledMethod.substring(4); } if (calledMethod.startsWith("http://")) { calledMethod = calledMethod.split("/")[calledMethod.split("/").length-1]; } } return calledMethod; } }