You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2012/03/02 21:53:54 UTC

svn commit: r1296454 - in /cxf/trunk: rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/ systests/jaxws/ systests/jaxws/src/test/java/org/apache/cxf/systest/provider/ systests/jaxws/src/test/resources/wsdl_systest_jaxws/

Author: dkulp
Date: Fri Mar  2 20:53:53 2012
New Revision: 1296454

URL: http://svn.apache.org/viewvc?rev=1296454&view=rev
Log:
[CXF-4130] Fix problems with Providers writing bodies into headers
Patch from Seumas Soltysik applied

Added:
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java   (with props)
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java   (with props)
    cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt   (with props)
    cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl   (with props)
Modified:
    cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/MessageModeOutInterceptor.java
    cxf/trunk/systests/jaxws/pom.xml

Modified: cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/MessageModeOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/MessageModeOutInterceptor.java?rev=1296454&r1=1296453&r2=1296454&view=diff
==============================================================================
--- cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/MessageModeOutInterceptor.java (original)
+++ cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/MessageModeOutInterceptor.java Fri Mar  2 20:53:53 2012
@@ -54,6 +54,7 @@ import org.apache.cxf.message.MessageImp
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
+import org.apache.cxf.service.model.BindingMessageInfo;
 import org.apache.cxf.service.model.BindingOperationInfo;
 import org.apache.cxf.staxutils.OverlayW3CDOMStreamWriter;
 import org.apache.cxf.staxutils.StaxUtils;
@@ -187,7 +188,7 @@ public class MessageModeOutInterceptor e
         
         public void handleMessage(SoapMessage message) throws Fault {
             MessageContentsList list = (MessageContentsList)message.getContent(List.class);
-            Object o = list.get(0);
+            Object o = list.remove(0);
             SOAPMessage soapMessage = null;
             
             if (o instanceof SOAPMessage) {
@@ -221,7 +222,9 @@ public class MessageModeOutInterceptor e
             // Replace stax writer with DomStreamWriter
             message.setContent(XMLStreamWriter.class, writer);
             message.setContent(SOAPMessage.class, soapMessage);
-            
+
+            BindingOperationInfo bop = message.getExchange().get(BindingOperationInfo.class);
+
             DocumentFragment frag = soapMessage.getSOAPPart().createDocumentFragment();
             try {
                 Node body = soapMessage.getSOAPBody();
@@ -231,7 +234,25 @@ public class MessageModeOutInterceptor e
                     frag.appendChild(nd);
                     nd = soapMessage.getSOAPBody().getFirstChild();
                 }
-                list.set(0, frag);
+                
+                int index = 0;
+
+                boolean client = isRequestor(message);
+                BindingMessageInfo bmsg = null; 
+
+                if (client) {
+                    bmsg = bop.getInput();
+                } else if (bop.getOutput() != null) {
+                    bmsg = bop.getOutput();  
+                }
+                if (bmsg != null && bmsg.getMessageParts() != null 
+                    && bmsg.getMessageParts().size() > 0) {
+                    index = bmsg.getMessageParts().get(0).getIndex(); 
+                }
+
+                list.set(index, frag);
+                
+                
                 //No need to buffer this as we're already a DOM, 
                 //but only do so if someone hasn't actually configured this
                 Object buffer = message
@@ -242,7 +263,6 @@ public class MessageModeOutInterceptor e
             } catch (Exception ex) {
                 throw new Fault(ex);
             }
-            BindingOperationInfo bop = message.getExchange().get(BindingOperationInfo.class);
             if (bop != null && bop.isUnwrapped()) {
                 bop = bop.getWrappedOperation();
                 message.getExchange().put(BindingOperationInfo.class, bop);

Modified: cxf/trunk/systests/jaxws/pom.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/pom.xml?rev=1296454&r1=1296453&r2=1296454&view=diff
==============================================================================
--- cxf/trunk/systests/jaxws/pom.xml (original)
+++ cxf/trunk/systests/jaxws/pom.xml Fri Mar  2 20:53:53 2012
@@ -192,6 +192,11 @@
             <scope>test</scope>
         </dependency>
         <dependency>
+          <groupId>commons-httpclient</groupId>
+          <artifactId>commons-httpclient</artifactId>
+          <scope>test</scope>
+        </dependency>
+        <dependency>
             <groupId>org.apache.geronimo.specs</groupId>
             <artifactId>geronimo-j2ee-connector_1.5_spec</artifactId>
         </dependency>

Added: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java?rev=1296454&view=auto
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java (added)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java Fri Mar  2 20:53:53 2012
@@ -0,0 +1,89 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.systest.provider;
+
+import java.io.StringReader;
+
+import javax.annotation.Resource;
+import javax.xml.soap.MessageFactory;
+import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.ws.Provider;
+import javax.xml.ws.ServiceMode;
+import javax.xml.ws.WebServiceContext;
+import javax.xml.ws.WebServiceException;
+import javax.xml.ws.WebServiceProvider;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+@WebServiceProvider(serviceName = "InBandSoapHeaderService",
+    targetNamespace = "http://cxf.apache.org/soapheader/inband", 
+    portName = "InBandSoapHeaderSoapHttpPort", 
+    wsdlLocation = "/wsdl_systest_jaxws/cxf4130.wsdl")
+@ServiceMode(value = javax.xml.ws.Service.Mode.MESSAGE)
+public class CXF4130Provider implements Provider<SOAPMessage> {
+
+    @Resource
+    protected WebServiceContext context;
+
+    public SOAPMessage invoke(SOAPMessage request) {
+        try {
+            Document soapBodyDomDocument = request.getSOAPBody().extractContentAsDocument();
+            Node node = soapBodyDomDocument.getDocumentElement();
+            String requestMsgName = node.getLocalName();
+            String responseText = null;
+
+            if ("FooRequest".equals(requestMsgName)) {
+                responseText = "<SOAP-ENV:Envelope "
+                               + "xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\">"
+                               + "<SOAP-ENV:Header>"
+                               + "<FooResponseHeader xmlns:ns2=\"http://cxf.apache.org/soapheader/inband\">"
+                               + "FooResponseHeader</FooResponseHeader>"
+                               + "</SOAP-ENV:Header>"
+                               + "<SOAP-ENV:Body>"
+                               + "<ns2:FooResponse xmlns:ns2=\"http://cxf.apache.org/soapheader/inband\">"
+                               + "<ns2:Return>Foo Response Body</ns2:Return>"
+                               + "</ns2:FooResponse>"
+                               + "</SOAP-ENV:Body>" 
+                               + "</SOAP-ENV:Envelope>\n";
+
+            } else {
+                throw new WebServiceException("Error in InBand Provider JAX-WS service -- Unknown Request: "
+                                              + requestMsgName);
+            }
+
+            // Create a SOAP request message
+            MessageFactory soapmsgfactory = MessageFactory.newInstance();
+            SOAPMessage responseMessage = soapmsgfactory.createMessage();
+            StreamSource responseMessageSrc = null;
+
+            responseMessageSrc = new StreamSource(new StringReader(responseText));
+            responseMessage.getSOAPPart().setContent(responseMessageSrc);
+            responseMessage.saveChanges();
+
+            return responseMessage;
+
+        } catch (Exception e) {
+            throw new WebServiceException(e);
+        }
+
+    }
+
+}

Propchange: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Provider.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java?rev=1296454&view=auto
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java (added)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java Fri Mar  2 20:53:53 2012
@@ -0,0 +1,96 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.cxf.systest.provider;
+
+
+import java.io.InputStream;
+
+import javax.xml.ws.Endpoint;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.commons.httpclient.HttpClient;
+import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
+import org.apache.commons.httpclient.methods.PostMethod;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.cxf.testutil.common.TestUtil;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class CXF4130Test extends AbstractBusClientServerTestBase {
+
+    public static final String ADDRESS 
+        = "http://localhost:" + TestUtil.getPortNumber(Server.class)
+            + "/InBand33MessageServiceProvider/InBandSoapHeaderSoapHttpPort";
+    
+    public static class Server extends AbstractBusTestServerBase {
+
+        protected void run() {
+            Object implementor = new CXF4130Provider();
+            Endpoint.publish(ADDRESS, implementor);                                 
+        }
+
+        public static void main(String[] args) {
+            try {
+                Server s = new Server();
+                s.start();
+            } catch (Exception ex) {
+                ex.printStackTrace();
+                System.exit(-1);
+            } finally {
+                System.out.println("done!");
+            }
+        }
+    }
+
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue("server did not launch correctly", launchServer(Server.class, true));
+    }
+    
+    @Test
+    public void testCxf4130() throws Exception {
+        InputStream body = getClass().getResourceAsStream("cxf4130data.txt");
+        HttpClient client = new HttpClient();
+        PostMethod post = new PostMethod(ADDRESS);
+        post.setRequestEntity(new InputStreamRequestEntity(body, "text/xml"));
+        client.executeMethod(post); 
+
+        Document doc = StaxUtils.read(post.getResponseBodyAsStream());
+        Element root = doc.getDocumentElement();
+        Node child = root.getFirstChild();
+        
+        boolean foundBody = false;
+        while (child != null) {
+            if ("Body".equals(child.getLocalName())) {
+                foundBody = true;
+                assertEquals(1, child.getChildNodes().getLength());
+                assertEquals("FooResponse", child.getFirstChild().getLocalName());
+            }
+            child = child.getNextSibling();
+        }
+        assertTrue("Did not find the soap:Body element", foundBody);
+    }
+
+}

Propchange: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/CXF4130Test.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt?rev=1296454&view=auto
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt (added)
+++ cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt Fri Mar  2 20:53:53 2012
@@ -0,0 +1,8 @@
+<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:inb="http://cxf.apache.org/soapheader/inband">
+   <soapenv:Header>
+      <inb:FooRequestHeader>?</inb:FooRequestHeader>
+   </soapenv:Header>
+   <soapenv:Body>
+      <inb:FooRequest/>
+   </soapenv:Body>
+</soapenv:Envelope>
\ No newline at end of file

Propchange: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/jaxws/src/test/java/org/apache/cxf/systest/provider/cxf4130data.txt
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl?rev=1296454&view=auto
==============================================================================
--- cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl (added)
+++ cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl Fri Mar  2 20:53:53 2012
@@ -0,0 +1,62 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://cxf.apache.org/soapheader/inband" targetNamespace="http://cxf.apache.org/soapheader/inband">
+	<types>
+		<schema elementFormDefault="qualified" targetNamespace="http://cxf.apache.org/soapheader/inband" xmlns="http://www.w3.org/2001/XMLSchema">
+>
+			<element name="FooRequest">
+				<complexType>
+					<sequence/>
+				</complexType>
+			</element>
+
+			<element name="FooResponse">
+				<complexType>
+					<sequence>
+						<element name="Return" type="string"/>
+					</sequence>
+				</complexType>
+			</element>
+
+			<element name="FooRequestHeader" type="string"/>
+			<element name="FooResponseHeader" type="string"/>
+		</schema>
+	</types>
+
+	<message name="FooRequest">
+		<part name="FooRequestHeader" element="tns:FooRequestHeader"/>
+		<part name="FooRequest" element="tns:FooRequest"/>
+	</message>
+	<message name="FooResponse">
+		<part name="FooResponseHeader" element="tns:FooResponseHeader"/>
+		<part name="FooResponse" element="tns:FooResponse"/>
+	</message>
+	<portType name="InBandSoapHeaderPortType">
+		<operation name="Foo">
+			<input name="FooRequest" message="tns:FooRequest"/>
+			<output name="FooResponse" message="tns:FooResponse"/>
+		</operation>
+	</portType>
+	<binding name="InBandSoapHeaderSoapHttpBinding" type="tns:InBandSoapHeaderPortType">
+		<soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
+		<operation name="Foo">
+			<soap:operation/>
+			<input>
+				<soap:header message="tns:FooRequest" part="FooRequestHeader" use="literal"/>
+				<soap:body parts="FooRequest" use="literal"/>
+			</input>
+			<output>
+				<soap:header message="tns:FooResponse" part="FooResponseHeader" use="literal"/>
+				<!-- mmurphy - The follow line is from customer's original WSDL -->
+				<!-- <soap:body parts="FooCallbackPollResponse" use="literal"/>  -->
+				<!-- mmurphy - Replacing with suggestion from Seumas -->
+				<soap:body use="literal"/>
+			</output>
+		</operation>
+	</binding>
+
+	<service name="InBandSoapHeaderService">
+		<port name="InBandSoapHeaderSoapHttpPort" binding="tns:InBandSoapHeaderSoapHttpBinding">
+			<soap:address location="http://localhost:5640/InBand33MessageServiceProvider/InBandSoapHeaderSoapHttpPort"/>
+		</port>
+	</service>
+</definitions>

Propchange: cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Propchange: cxf/trunk/systests/jaxws/src/test/resources/wsdl_systest_jaxws/cxf4130.wsdl
------------------------------------------------------------------------------
    svn:mime-type = text/xml