Hi,
I had some issues with soap messages not being serialized properly,
header/body handling (binding) etc. I'm using the wsdl11-wrapping and
I don't know if it has something to do with this. Anyways, at least it
looks like the binding stuff is being discarded at
org.apache.servicemix.http.HttpEndpoint:228, but I don't know if the
part handling (soap binding) was occurring before that; although, the
end-results weren't suggesting so. (All parts were serialized to the
soap body, or something.) So I hacked up this little patch which does
the part handling. Diffs attached. Best effort -kind of stuff, works
for me. Just if anyone else is interested.. Though, I didn't quite get
what HttpEndpoint#overrideDefinition was trying to do so that hack may
be a little conflicting.. (see the httpendpoint-patch.)
I'd also like to know if this would somehow work without the patch as
patches are a bit annoying. :)
(There also appears to be some major stuff coming in the soap2-module,
but it seemed a little incomplete so I didn't take a closer look.)
Btw., I guess the soap-headers of the reply message are being
forwarded correctly?
-janne
Index:
servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java
===================================================================
---
servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java
(revision 523275)
+++
servicemix-soap/src/main/java/org/apache/servicemix/soap/marshalers/JBIMarshaler.java
(working copy)
@@ -17,6 +17,8 @@
package org.apache.servicemix.soap.marshalers;
import java.net.URI;
+import java.util.Collection;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
@@ -24,11 +26,26 @@
import javax.activation.DataHandler;
import javax.jbi.messaging.Fault;
import javax.jbi.messaging.NormalizedMessage;
+import javax.wsdl.Message;
+import javax.wsdl.Part;
+import javax.wsdl.WSDLElement;
+import javax.wsdl.extensions.soap.SOAPHeader;
import javax.xml.namespace.QName;
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMResult;
+import javax.xml.transform.dom.DOMSource;
import org.apache.servicemix.JbiConstants;
+import org.apache.servicemix.jbi.util.DOMUtil;
import org.apache.servicemix.soap.SoapFault;
+import org.w3c.dom.Document;
import org.w3c.dom.DocumentFragment;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
/**
*
@@ -73,7 +90,8 @@
}
}
- public void fromNMS(SoapMessage soapMessage, NormalizedMessage
normalizedMessage) {
+ public void fromNMS(SoapMessage soapMessage, NormalizedMessage
normalizedMessage,
+ Message msg, WSDLElement bindingElem) {
if (normalizedMessage.getProperty(JbiConstants.SOAP_HEADERS) !=
null) {
Map headers = (Map)
normalizedMessage.getProperty(JbiConstants.SOAP_HEADERS);
for (Iterator it = headers.entrySet().iterator();
it.hasNext();) {
@@ -95,6 +113,55 @@
URI role = (URI) normalizedMessage.getProperty(SOAP_FAULT_ROLE);
SoapFault fault = new SoapFault(code, subcode, reason, node, role,
normalizedMessage.getContent());
soapMessage.setFault(fault);
+ } else if (bindingElem != null) {
+ boolean success = false;
+ DocumentBuilder docBuilder = null;
+ try {
+ // QName#hashCode() is implemented suitably
+ Collection<QName> headerElems = new HashSet<QName>();
+ for (Object ext :
bindingElem.getExtensibilityElements()) {
+ if (ext instanceof SOAPHeader) {
+ Part p = msg.getPart(((SOAPHeader)
ext).getPart());
+ if (p != null && p.getElementName() !=
null)
+
headerElems.add(p.getElementName());
+ }
+ }
+ docBuilder = DOMUtil.getBuilder();
+ Transformer tr =
TransformerFactory.newInstance().newTransformer();
+ Document jbiContent = docBuilder.newDocument();
+ Document soapBody = docBuilder.newDocument();
+ tr.transform(normalizedMessage.getContent(), new
DOMResult(jbiContent));
+ NodeList wrapperMsg = jbiContent.getElementsByTagNameNS(
+
"http://java.sun.com/xml/ns/jbi/wsdl-11-wrapper", "message");
+ if (wrapperMsg.getLength() == 1) {
+ Node part = wrapperMsg.item(0).getFirstChild();
+ while (part != null &&
"part".equals(part.getLocalName())
+ &&
part.getChildNodes().getLength() == 1) {
+ Node partContent = part.getFirstChild();
+ QName elemName = new
QName(partContent.getNamespaceURI(),
+
partContent.getLocalName());
+ if (headerElems.contains(elemName)) {
+ DocumentFragment headerFrag =
+
docBuilder.newDocument().createDocumentFragment();
+ tr.transform(new
DOMSource(partContent),
+ new
DOMResult(headerFrag));
+ soapMessage.addHeader(elemName,
headerFrag);
+ } else { // assume it's a valid part
for body
+
soapBody.appendChild(soapBody.adoptNode(partContent));
+ }
+ part = part.getNextSibling();
+ }
+ }
+ soapMessage.setSource(new DOMSource(soapBody));
+ success = true;
+ } catch (ParserConfigurationException e) {
+ } catch (TransformerException e) {
+ } finally {
+ if (!success)
+
soapMessage.setSource(normalizedMessage.getContent());
+ if (docBuilder != null)
+ DOMUtil.releaseBuilder(docBuilder);
+ }
} else {
soapMessage.setSource(normalizedMessage.getContent());
}
Index:
servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java
===================================================================
---
servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java
(revision 523281)
+++
servicemix-http/src/main/java/org/apache/servicemix/http/processors/ProviderProcessor.java
(working copy)
@@ -33,6 +33,11 @@
import javax.jbi.messaging.MessageExchange;
import javax.jbi.messaging.NormalizedMessage;
import javax.servlet.http.HttpServletRequest;
+import javax.wsdl.BindingOperation;
+import javax.wsdl.Message;
+import javax.wsdl.Port;
+import javax.wsdl.Service;
+import javax.wsdl.WSDLElement;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.Header;
@@ -126,7 +131,20 @@
PostMethod method = new PostMethod(getRelUri(locationURI));
SoapMessage soapMessage = new SoapMessage();
- soapHelper.getJBIMarshaler().fromNMS(soapMessage, nm);
+ Service svcDesc =
endpoint.getDefinition().getService(exchange.getService());
+ Message inputMsg = null;
+ WSDLElement inputBinding = null;
+ if (svcDesc != null) {
+ Port port =
svcDesc.getPort(exchange.getEndpoint().getEndpointName());
+ if (port != null) {
+ BindingOperation op =
port.getBinding().getBindingOperation(
+ exchange.getOperation().getLocalPart(),
null, null);
+ if (op != null)
+ inputMsg =
op.getOperation().getInput().getMessage();
+ inputBinding = op.getBindingInput();
+ }
+ }
+ soapHelper.getJBIMarshaler().fromNMS(soapMessage, nm, inputMsg,
inputBinding);
Context context = soapHelper.createContext(soapMessage);
soapHelper.onSend(context);
SoapWriter writer =
soapHelper.getSoapMarshaler().createWriter(soapMessage);
Index:
servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java
===================================================================
--- servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java
(revision 523281)
+++ servicemix-http/src/main/java/org/apache/servicemix/http/HttpEndpoint.java
(working copy)
@@ -209,6 +209,8 @@
}
protected void overrideDefinition(Definition def) throws Exception {
+ this.definition = def;
+ if (true) return;
PortType portType = getTargetPortType(def);
if (portType != null) {
QName[] names = (QName[]) def.getPortTypes().keySet().toArray(new
QName[0]);