You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ode.apache.org by mi...@apache.org on 2008/07/18 20:05:21 UTC
svn commit: r677984 - in /ode/trunk/axis2/src:
main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java
test/java/org/apache/ode/axis2/httpbinding/HttpMethodConverterTest.java
Author: midon
Date: Fri Jul 18 11:05:20 2008
New Revision: 677984
URL: http://svn.apache.org/viewvc?rev=677984&view=rev
Log:
move stuff around to make code more readable
Modified:
ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java
ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpMethodConverterTest.java
Modified: ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java?rev=677984&r1=677983&r2=677984&view=diff
==============================================================================
--- ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java (original)
+++ ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpExternalService.java Fri Jul 18 11:05:20 2008
@@ -19,13 +19,11 @@
package org.apache.ode.axis2.httpbinding;
-import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.params.HttpParams;
-import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ode.axis2.ExternalService;
@@ -40,20 +38,15 @@
import org.apache.ode.il.epr.EndpointFactory;
import org.apache.ode.il.epr.WSAEndpoint;
import org.apache.ode.utils.DOMUtils;
-import org.apache.ode.utils.Namespaces;
import org.apache.ode.utils.wsdl.Messages;
import org.apache.ode.utils.wsdl.WsdlUtils;
import org.w3c.dom.Element;
import javax.wsdl.Binding;
-import javax.wsdl.BindingOperation;
import javax.wsdl.Definition;
-import javax.wsdl.Fault;
import javax.wsdl.Operation;
-import javax.wsdl.Part;
import javax.wsdl.Port;
import javax.wsdl.Service;
-import javax.wsdl.extensions.mime.MIMEContent;
import javax.xml.namespace.QName;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -73,7 +66,6 @@
protected BpelServer server;
protected ProcessConf pconf;
- private String targetNamespace;
protected QName serviceName;
protected String portName;
@@ -83,14 +75,14 @@
protected Binding portBinding;
public HttpExternalService(ProcessConf pconf, QName serviceName, String portName, BpelServer server) {
- if(log.isDebugEnabled()) log.debug("new HTTP External service, service name=["+serviceName+"]; port name=["+portName+"]");
+ if (log.isDebugEnabled())
+ log.debug("new HTTP External service, service name=[" + serviceName + "]; port name=[" + portName + "]");
this.portName = portName;
this.serviceName = serviceName;
this.server = server;
this.pconf = pconf;
Definition definition = pconf.getDefinitionForService(serviceName);
- targetNamespace = definition.getTargetNamespace();
Service serviceDef = definition.getService(serviceName);
if (serviceDef == null)
throw new IllegalArgumentException(msgs.msgServiceDefinitionNotFound(serviceName));
@@ -114,7 +106,7 @@
throw new IllegalArgumentException(msgs.msgPortDefinitionNotFound(serviceName, portName));
endpointReference = EndpointFactory.convertToWSA(ODEService.createServiceRef(eprElmt));
- httpMethodConverter = new HttpMethodConverter(portBinding);
+ httpMethodConverter = new HttpMethodConverter(definition, serviceName, portName);
connections = new MultiThreadedHttpConnectionManager();
}
@@ -169,15 +161,15 @@
}
} catch (UnsupportedEncodingException e) {
String errmsg = "The returned HTTP encoding isn't supported " + odeMex;
- log.error("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] "+errmsg, e);
+ log.error("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] " + errmsg, e);
odeMex.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR, errmsg, null);
} catch (URIException e) {
String errmsg = "Invalid URI " + odeMex;
- log.error("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] "+errmsg, e);
+ log.error("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] " + errmsg, e);
odeMex.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR, errmsg, null);
} catch (Exception e) {
String errmsg = "Unknown HTTP call error for ODE mex " + odeMex;
- log.error("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] "+errmsg, e);
+ log.error("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] " + errmsg, e);
odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, null);
}
@@ -199,7 +191,7 @@
try {
// simply execute the http method
HttpClient client = new HttpClient(connections);
- if (log.isDebugEnabled()){
+ if (log.isDebugEnabled()) {
log.debug("Executing http request : " + method.getName() + " " + method.getURI());
log.debug(HttpHelper.requestToString(method));
}
@@ -218,10 +210,10 @@
// Something happened, recording the failure
try {
String errmsg = "Unable to execute HTTP request : " + e.getMessage();
- log.error("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] "+errmsg, e);
+ log.error("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] " + errmsg, e);
odeMex.replyWithFailure(MessageExchange.FailureType.COMMUNICATION_ERROR, errmsg, null);
} catch (Exception e1) {
- String errmsg = "[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Error executing reply transaction; reply will be lost.";
+ String errmsg = "[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Error executing reply transaction; reply will be lost.";
log.error(errmsg, e);
}
} finally {
@@ -241,7 +233,7 @@
log.debug("OneWay HTTP Request, Status-Line: " + method.getStatusLine() + " for " + method.getURI());
}
} catch (URIException e) {
- String errmsg = "[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Exception occured while processing the HTTP response of a one-way request: " + e.getMessage();
+ String errmsg = "[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Exception occured while processing the HTTP response of a one-way request: " + e.getMessage();
log.error(errmsg, e);
}
}
@@ -267,13 +259,11 @@
unmanagedStatus();
}
} catch (Exception e) {
- String errmsg = "Exception occured while processing the HTTP response of a two-way request: " + e.getMessage();
- log.error("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] "+errmsg, e);
- odeMex.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR, errmsg, null);
+ replyWithFailure("Exception occured while processing the HTTP response of a two-way request. mexId= " + odeMex.getMessageExchangeId(), e);
}
}
- private void unmanagedStatus() throws IOException {
+ private void unmanagedStatus() throws Exception {
replyWithFailure("Unmanaged Status Code! Status-Line: " + method.getStatusLine() + " for " + method.getURI());
}
@@ -282,183 +272,43 @@
*
* @throws IOException
*/
- private void _5xx_serverError() throws IOException {
+ private void _5xx_serverError() throws Exception {
String errmsg;
if (log.isWarnEnabled()) {
- errmsg = "[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Status-Line: " + method.getStatusLine() + " for " + method.getURI();
+ errmsg = "[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Status-Line: " + method.getStatusLine() + " for " + method.getURI();
log.warn(errmsg);
}
+ Object[] fault = httpMethodConverter.parseFault(odeMex, method);
+ Message response = (Message) fault[1];
+ QName faultName = (QName) fault[0];
- Operation opDef = odeMex.getOperation();
- BindingOperation opBinding = portBinding.getBindingOperation(opDef.getName(), opDef.getInput().getName(), opDef.getOutput().getName());
-
- final String body;
- try {
- body = method.getResponseBodyAsString();
- } catch (IOException e) {
- errmsg = "[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Unable to get the request body : " + e.getMessage();
- log.error(errmsg, e);
- odeMex.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR, errmsg, HttpHelper.prepareDetailsElement(method));
- return;
- }
- Header h = method.getResponseHeader("Content-Type");
- String receivedType = h != null ? h.getValue() : null;
-
- if (opDef.getFaults().isEmpty()) {
- replyWithFailure("Operation [" + opDef.getName() + "] has no fault. This 500 error will be considered as a failure.");
- } else if (opBinding.getBindingFaults().isEmpty()) {
- replyWithFailure("No fault binding. This 500 error will be considered as a failure.");
- } else if (StringUtils.isEmpty(body)) {
- replyWithFailure("No body in the response. This 500 error will be considered as a failure.");
- } else if (receivedType != null && !HttpHelper.isXml(receivedType)) {
- replyWithFailure("Response Content-Type [" + receivedType + "] does not describe XML entities. Faults must be XML. This 500 error will be considered as a failure.");
- } else {
-
- if (receivedType == null) {
- if (log.isWarnEnabled())
- log.warn("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Received Response with a body but no 'Content-Type' header! Will try to parse nevertheless.");
- }
-
- // try to parse body
- final Element bodyElement;
- try {
- bodyElement = DOMUtils.stringToDOM(body);
- } catch (Exception e) {
- replyWithFailure("Unable to parse the response body as xml. This 500 error will be considered as a failure.");
- return;
- }
-
- // Guess which fault it is
- QName bodyName = new QName(bodyElement.getNamespaceURI(), bodyElement.getNodeName());
- Fault faultDef = WsdlUtils.inferFault(opDef, bodyName);
-
- if (faultDef == null) {
- replyWithFailure("Unknown Fault Type [" + bodyName + "] This 500 error will be considered as a failure.");
- } else if (!WsdlUtils.isOdeFault(opBinding.getBindingFault(faultDef.getName()))) {
- // is this fault bound with ODE extension?
- replyWithFailure("Fault [" + bodyName + "] is not bound with " + new QName(Namespaces.ODE_HTTP_EXTENSION_NS, "fault") + ". This 500 error will be considered as a failure.");
- } else {
- // a fault has only one part
- Part partDef = (Part) faultDef.getMessage().getParts().values().iterator().next();
-
- QName faultName = new QName(targetNamespace, faultDef.getName());
- QName faultType = faultDef.getMessage().getQName();
-
- // create the ODE Message now that we know the fault
- Message response = odeMex.createMessage(faultType);
+ // finally send the fault. We did it!
+ if (log.isWarnEnabled())
+ log.warn("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] Fault response: faultName=" + faultName + " faultType=" + response.getType() + "\n" + DOMUtils.domToString(response.getMessage()));
- // build the element to be sent back
- Element partElement = httpMethodConverter.createPartElement(partDef, bodyElement);
- response.setPart(partDef.getName(), partElement);
-
- // extract and set headers
- httpMethodConverter.extractHttpResponseHeaders(response, method, faultDef.getMessage(), opBinding.getBindingOutput());
-
- // finally send the fault. We did it!
- if (log.isWarnEnabled())
- log.warn("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Fault response: faultName=" + faultName + " faultType=" + faultType + "\n" + DOMUtils.domToString(response.getMessage()));
- odeMex.replyWithFault(faultName, response);
- }
-
- }
+ odeMex.replyWithFault(faultName, response);
}
- private void _4xx_badRequest() throws IOException {
+ private void _4xx_badRequest() throws Exception {
replyWithFailure("HTTP Status-Line: " + method.getStatusLine() + " for " + method.getURI());
}
- private void _3xx_redirection() throws IOException {
+ private void _3xx_redirection() throws Exception {
// redirections should be handled transparently by http-client
replyWithFailure("Redirections disabled! HTTP Status-Line: " + method.getStatusLine() + " for " + method.getURI());
}
- private void _2xx_success() throws IOException {
+ private void _2xx_success() throws Exception {
if (log.isDebugEnabled())
- log.debug("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] HTTP Status-Line: " + method.getStatusLine() + " for " + method.getURI());
+ log.debug("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] HTTP Status-Line: " + method.getStatusLine() + " for " + method.getURI());
if (log.isDebugEnabled()) log.debug("Received response for MEX " + odeMex);
Operation opDef = odeMex.getOperation();
- BindingOperation opBinding = portBinding.getBindingOperation(opDef.getName(), opDef.getInput().getName(), opDef.getOutput().getName());
- javax.wsdl.Message outputMessage = odeMex.getOperation().getOutput().getMessage();
-
// this is the message to populate and send to ODE
- Message odeResponse = odeMex.createMessage(outputMessage.getQName());
-
- /* process headers */
- httpMethodConverter.extractHttpResponseHeaders(odeResponse, method, outputMessage, opBinding.getBindingOutput());
-
- /* process the body if any */
-
- // assumption is made that a response may have at most one body. HttpBindingValidator checks this.
- MIMEContent outputContent = WsdlUtils.getMimeContent(opBinding.getBindingOutput().getExtensibilityElements());
- int statusCode = method.getStatusCode();
-
- boolean xmlExpected = outputContent != null && HttpHelper.isXml(outputContent.getType());
- // '202/Accepted' and '204/No Content' status codes explicitly state that there is no body, so we should not fail even if a part is bound to the body response
- boolean isBodyExpected = outputContent != null;
- boolean isBodyMandatory = isBodyExpected && statusCode!=204 && statusCode!=202;
-
-
- final String body;
- try {
- body = method.getResponseBodyAsString();
- } catch (IOException e) {
- String errmsg = "[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Unable to get the request body : " + e.getMessage();
- log.error(errmsg, e);
- odeMex.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR, errmsg, HttpHelper.prepareDetailsElement(method));
- return;
- }
+ QName outputMsgName = odeMex.getOperation().getOutput().getMessage().getQName();
+ Message odeResponse = odeMex.createMessage(outputMsgName);
- final boolean emptyBody = StringUtils.isEmpty(body);
- if (emptyBody) {
- if (isBodyMandatory) {
- replyWithFailure("Response body is mandatory but missing! Msg Id=" + odeMex.getMessageExchangeId());
- return;
- }
- } else {
- if (isBodyExpected) {
- Part partDef = outputMessage.getPart(outputContent.getPart());
- Element partElement;
-
- if (xmlExpected) {
-
- Header h = method.getResponseHeader("Content-Type");
- String receivedType = h != null ? h.getValue() : null;
- boolean contentTypeSet = receivedType != null;
- boolean xmlReceived = contentTypeSet && HttpHelper.isXml(receivedType);
-
- // a few checks
- if (!contentTypeSet) {
- if (log.isDebugEnabled())
- log.debug("Received Response with a body but no 'Content-Type' header!");
- } else if (!xmlReceived) {
- if (log.isDebugEnabled())
- log.debug("Xml type was expected but non-xml type received! Expected Content-Type=" + outputContent.getType() + " Received Content-Type=" + receivedType);
- }
-
- // parse the body and create the message part
- try {
- Element bodyElement = DOMUtils.stringToDOM(body);
- partElement = httpMethodConverter.createPartElement(partDef, bodyElement);
- } catch (Exception e) {
- String errmsg = "[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] Unable to parse the response body: " + e.getMessage();
- log.error(errmsg, e);
- odeMex.replyWithFailure(MessageExchange.FailureType.FORMAT_ERROR, errmsg, HttpHelper.prepareDetailsElement(method));
- return;
- }
- } else {
- // if not xml, process it as text
- partElement = httpMethodConverter.createPartElement(partDef, body);
- }
-
- // set the part
- odeResponse.setPart(partDef.getName(), partElement);
-
- } else {
- // the body was not expected but we don't know how to deal with it
- if (log.isDebugEnabled()) log.debug("Body received but not mapped to any part! Body=\n" + body);
- }
- }
+ httpMethodConverter.parseHttpResponse(odeResponse, method, opDef);
// finally send the message
try {
@@ -466,12 +316,16 @@
log.info("Response: " + (odeResponse.getMessage() != null ? DOMUtils.domToString(odeResponse.getMessage()) : "empty"));
odeMex.reply(odeResponse);
} catch (Exception ex) {
- replyWithFailure("Unable to process response: " + ex.getMessage());
- }
+ replyWithFailure("Unable to process response: " + ex.getMessage(), ex);
+ }
}
void replyWithFailure(String errmsg) {
- log.error("[Service: "+serviceName+", Port: "+portName+", Operation: "+odeMex.getOperationName()+"] "+errmsg);
+ replyWithFailure(errmsg, null);
+ }
+
+ void replyWithFailure(String errmsg, Throwable t) {
+ log.error("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + odeMex.getOperationName() + "] " + errmsg, t);
odeMex.replyWithFailure(MessageExchange.FailureType.OTHER, errmsg, HttpHelper.prepareDetailsElement(method));
}
}
Modified: ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java?rev=677984&r1=677983&r2=677984&view=diff
==============================================================================
--- ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java (original)
+++ ode/trunk/axis2/src/main/java/org/apache/ode/axis2/httpbinding/HttpMethodConverter.java Fri Jul 18 11:05:20 2008
@@ -19,8 +19,8 @@
package org.apache.ode.axis2.httpbinding;
-import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.Header;
+import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.methods.DeleteMethod;
import org.apache.commons.httpclient.methods.EntityEnclosingMethod;
import org.apache.commons.httpclient.methods.GetMethod;
@@ -29,51 +29,61 @@
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.params.HttpParams;
+import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.apache.commons.lang.StringUtils;
import org.apache.ode.axis2.Properties;
import org.apache.ode.axis2.util.URLEncodedTransformer;
import org.apache.ode.axis2.util.UrlReplacementTransformer;
import org.apache.ode.bpel.iapi.PartnerRoleMessageExchange;
+import org.apache.ode.il.epr.MutableEndpoint;
import org.apache.ode.utils.DOMUtils;
import org.apache.ode.utils.Namespaces;
import org.apache.ode.utils.wsdl.Messages;
import org.apache.ode.utils.wsdl.WsdlUtils;
-import org.apache.ode.il.epr.MutableEndpoint;
-import org.w3c.dom.Element;
import org.w3c.dom.Document;
+import org.w3c.dom.Element;
import org.w3c.dom.Node;
+import org.xml.sax.SAXException;
import javax.wsdl.Binding;
import javax.wsdl.BindingInput;
import javax.wsdl.BindingOperation;
+import javax.wsdl.BindingOutput;
import javax.wsdl.Message;
import javax.wsdl.Operation;
import javax.wsdl.Part;
-import javax.wsdl.BindingOutput;
+import javax.wsdl.Definition;
+import javax.wsdl.Fault;
+import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.wsdl.extensions.http.HTTPOperation;
import javax.wsdl.extensions.mime.MIMEContent;
-import javax.wsdl.extensions.UnknownExtensibilityElement;
import javax.xml.namespace.QName;
+import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
-import java.util.Collection;
public class HttpMethodConverter {
- private static final String CONTENT_TYPE_TEXT_XML = "text/xml";
private static final Log log = LogFactory.getLog(HttpMethodConverter.class);
protected static final Messages msgs = Messages.getMessages(Messages.class);
+ protected Definition definition;
protected Binding binding;
+ protected QName serviceName;
+ protected String portName;
- public HttpMethodConverter(Binding binding) {
- this.binding = binding;
+ public HttpMethodConverter(Definition definition, QName serviceName, String portName) {
+ this.definition = definition;
+ this.binding = definition.getService(serviceName).getPort(portName).getBinding();
+ this.serviceName = serviceName;
+ this.portName = portName;
}
+
public HttpMethod createHttpRequest(PartnerRoleMessageExchange odeMex, HttpParams params) throws UnsupportedEncodingException {
Operation operation = odeMex.getOperation();
BindingOperation bindingOperation = binding.getBindingOperation(operation.getName(), operation.getInput().getName(), operation.getOutput().getName());
@@ -369,11 +379,13 @@
*
* @param odeMessage
* @param method
- * @param messageDef
- * @param bindingOutput
+ * @param operationDef
*/
- public void extractHttpResponseHeaders(org.apache.ode.bpel.iapi.Message odeMessage, HttpMethod method, Message messageDef, BindingOutput bindingOutput) {
- Collection<UnknownExtensibilityElement> headerBindings = WsdlUtils.getHttpHeaders(bindingOutput.getExtensibilityElements());
+ public void extractHttpResponseHeaders(org.apache.ode.bpel.iapi.Message odeMessage, HttpMethod method, Operation operationDef) {
+ Message messageDef = operationDef.getOutput().getMessage();
+
+ BindingOutput outputBinding = binding.getBindingOperation(operationDef.getName(), operationDef.getInput().getName(), operationDef.getOutput().getName()).getBindingOutput();
+ Collection<UnknownExtensibilityElement> headerBindings = WsdlUtils.getHttpHeaders(outputBinding.getExtensibilityElements());
// iterate through the list of header bindings
// and set the message parts accordingly
@@ -410,6 +422,136 @@
odeMessage.setHeaderPart("Status-Line", HttpHelper.statusLineToElement(method.getStatusLine()));
}
+ public void parseHttpResponse(org.apache.ode.bpel.iapi.Message odeResponse, HttpMethod method, Operation opDef) throws Exception {
+ BindingOperation opBinding = binding.getBindingOperation(opDef.getName(), opDef.getInput().getName(), opDef.getOutput().getName());
+ /* process headers */
+ extractHttpResponseHeaders(odeResponse, method, opDef);
+
+ /* process the body if any */
+
+ // assumption is made that a response may have at most one body. HttpBindingValidator checks this.
+ MIMEContent outputContent = WsdlUtils.getMimeContent(opBinding.getBindingOutput().getExtensibilityElements());
+ int statusCode = method.getStatusCode();
+
+ boolean xmlExpected = outputContent != null && HttpHelper.isXml(outputContent.getType());
+ // '202/Accepted' and '204/No Content' status codes explicitly state that there is no body, so we should not fail even if a part is bound to the body response
+ boolean isBodyExpected = outputContent != null;
+ boolean isBodyMandatory = isBodyExpected && statusCode != 204 && statusCode != 202;
+ final String body;
+ try {
+ body = method.getResponseBodyAsString();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to get the request body : " + e.getMessage());
+ }
+
+ final boolean emptyBody = StringUtils.isEmpty(body);
+ if (emptyBody) {
+ if (isBodyMandatory) {
+ throw new RuntimeException("Response body is mandatory but missing!");
+ }
+ } else {
+ if (isBodyExpected) {
+ Part partDef = opDef.getOutput().getMessage().getPart(outputContent.getPart());
+ Element partElement;
+
+ if (xmlExpected) {
+
+ Header h = method.getResponseHeader("Content-Type");
+ String receivedType = h != null ? h.getValue() : null;
+ boolean contentTypeSet = receivedType != null;
+ boolean xmlReceived = contentTypeSet && HttpHelper.isXml(receivedType);
+
+ // a few checks
+ if (!contentTypeSet) {
+ if (log.isDebugEnabled())
+ log.debug("Received Response with a body but no 'Content-Type' header!");
+ } else if (!xmlReceived) {
+ if (log.isDebugEnabled())
+ log.debug("Xml type was expected but non-xml type received! Expected Content-Type=" + outputContent.getType() + " Received Content-Type=" + receivedType);
+ }
+
+ // parse the body and create the message part
+ Element bodyElement = DOMUtils.stringToDOM(body);
+ partElement = createPartElement(partDef, bodyElement);
+ } else {
+ // if not xml, process it as text
+ partElement = createPartElement(partDef, body);
+ }
+
+ // set the part
+ odeResponse.setPart(partDef.getName(), partElement);
+
+ } else {
+ // the body was not expected but we don't know how to deal with it
+ if (log.isDebugEnabled()) log.debug("Body received but not mapped to any part! Body=\n" + body);
+ }
+ }
+ }
+
+ public Object[] parseFault(PartnerRoleMessageExchange odeMex, HttpMethod method) {
+ Operation opDef = odeMex.getOperation();
+ BindingOperation opBinding = binding.getBindingOperation(opDef.getName(), opDef.getInput().getName(), opDef.getOutput().getName());
+
+ final String body;
+ try {
+ body = method.getResponseBodyAsString();
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to get the request body : " + e.getMessage(), e);
+ }
+ Header h = method.getResponseHeader("Content-Type");
+ String receivedType = h != null ? h.getValue() : null;
+ if (opDef.getFaults().isEmpty()) {
+ throw new RuntimeException("Operation [" + opDef.getName() + "] has no fault. This " + method.getStatusCode() + " error will be considered as a failure.");
+ } else if (opBinding.getBindingFaults().isEmpty()) {
+ throw new RuntimeException("No fault binding. This " + method.getStatusCode() + " error will be considered as a failure.");
+ } else if (StringUtils.isEmpty(body)) {
+ throw new RuntimeException("No body in the response. This " + method.getStatusCode() + " error will be considered as a failure.");
+ } else if (receivedType != null && !HttpHelper.isXml(receivedType)) {
+ throw new RuntimeException("Response Content-Type [" + receivedType + "] does not describe XML entities. Faults must be XML. This " + method.getStatusCode() + " error will be considered as a failure.");
+ } else {
+
+ if (receivedType == null) {
+ if (log.isWarnEnabled())
+ log.warn("[Service: " + serviceName + ", Port: " + portName + ", Operation: " + opDef.getName() + "] Received Response with a body but no 'Content-Type' header! Will try to parse nevertheless.");
+ }
+
+ // try to parse body
+ final Element bodyElement;
+ try {
+ bodyElement = DOMUtils.stringToDOM(body);
+ } catch (Exception e) {
+ throw new RuntimeException("Unable to parse the response body as xml. This " + method.getStatusCode() + " error will be considered as a failure.", e);
+ }
+
+ // Guess which fault it is
+ QName bodyName = new QName(bodyElement.getNamespaceURI(), bodyElement.getNodeName());
+ Fault faultDef = WsdlUtils.inferFault(opDef, bodyName);
+
+ if (faultDef == null) {
+ throw new RuntimeException("Unknown Fault Type [" + bodyName + "] This " + method.getStatusCode() + " error will be considered as a failure.");
+ } else if (!WsdlUtils.isOdeFault(opBinding.getBindingFault(faultDef.getName()))) {
+ // is this fault bound with ODE extension?
+ throw new RuntimeException("Fault [" + bodyName + "] is not bound with " + new QName(Namespaces.ODE_HTTP_EXTENSION_NS, "fault") + ". This " + method.getStatusCode() + " error will be considered as a failure.");
+ } else {
+ // a fault has only one part
+ Part partDef = (Part) faultDef.getMessage().getParts().values().iterator().next();
+
+ QName faultName = new QName(definition.getTargetNamespace(), faultDef.getName());
+ QName faultType = faultDef.getMessage().getQName();
+
+ // create the ODE Message now that we know the fault
+ org.apache.ode.bpel.iapi.Message response = odeMex.createMessage(faultType);
+
+ // build the element to be sent back
+ Element partElement = createPartElement(partDef, bodyElement);
+ response.setPart(partDef.getName(), partElement);
+
+ // extract and set headers
+ extractHttpResponseHeaders(response, method, opDef);
+ return new Object[]{faultName, response};
+ }
+ }
+ }
}
Modified: ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpMethodConverterTest.java
URL: http://svn.apache.org/viewvc/ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpMethodConverterTest.java?rev=677984&r1=677983&r2=677984&view=diff
==============================================================================
--- ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpMethodConverterTest.java (original)
+++ ode/trunk/axis2/src/test/java/org/apache/ode/axis2/httpbinding/HttpMethodConverterTest.java Fri Jul 18 11:05:20 2008
@@ -72,12 +72,12 @@
Service deliciousService = definition.getService(new QName("http://ode/bpel/unit-test.wsdl", "DeliciousService"));
deliciousPort = deliciousService.getPort("TagHttpPort");
deliciousBinding = deliciousPort.getBinding();
- deliciousBuilder = new HttpMethodConverter(deliciousBinding);
+ deliciousBuilder = new HttpMethodConverter(definition, deliciousService.getQName(), deliciousPort.getName());
Service dummyService = definition.getService(new QName("http://ode/bpel/unit-test.wsdl", "DummyService"));
dummyPort = dummyService.getPort("DummyServiceHttpport");
dummyBinding = dummyPort.getBinding();
- dummyBuilder = new HttpMethodConverter(dummyBinding);
+ dummyBuilder = new HttpMethodConverter(definition, dummyService.getQName(), dummyPort.getName());
}