You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by eg...@apache.org on 2008/11/24 17:17:35 UTC

svn commit: r720218 - in /cxf/trunk: rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/ systests/src/test/java/org/apache/cxf/systest/handlers/

Author: eglynn
Date: Mon Nov 24 08:17:34 2008
New Revision: 720218

URL: http://svn.apache.org/viewvc?rev=720218&view=rev
Log:
Fix for handleMessage() being called instead of handleFault() on JAX-WS SOAPHandlers for incoming fault messages. Also fix for incomplete population of SAAJ model in the presence of faults.

Modified:
    cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultInInterceptor.java
    cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap12FaultInInterceptor.java
    cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java
    cxf/trunk/systests/src/test/java/org/apache/cxf/systest/handlers/HandlerInvocationTest.java

Modified: cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultInInterceptor.java?rev=720218&r1=720217&r2=720218&view=diff
==============================================================================
--- cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultInInterceptor.java (original)
+++ cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultInInterceptor.java Mon Nov 24 08:17:34 2008
@@ -41,12 +41,17 @@
     }
 
     public void handleMessage(SoapMessage message) throws Fault {
+        XMLStreamReader reader = message.getContent(XMLStreamReader.class);
+
+        message.setContent(Exception.class, unmarshalFault(message, reader));
+    }
+
+    public static SoapFault unmarshalFault(SoapMessage message, 
+                                           XMLStreamReader reader) {
         String exMessage = null;
         QName faultCode = null;
         String role = null;
         Element detail = null;
-
-        XMLStreamReader reader = message.getContent(XMLStreamReader.class);
         
         try {
             while (reader.nextTag() == XMLStreamReader.START_ELEMENT) {
@@ -70,8 +75,6 @@
         SoapFault fault = new SoapFault(exMessage, faultCode);
         fault.setDetail(detail);
         fault.setRole(role);
-
-        message.setContent(Exception.class, fault);
+        return fault;
     }
-
 }

Modified: cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap12FaultInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap12FaultInInterceptor.java?rev=720218&r1=720217&r2=720218&view=diff
==============================================================================
--- cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap12FaultInInterceptor.java (original)
+++ cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap12FaultInInterceptor.java Mon Nov 24 08:17:34 2008
@@ -50,6 +50,12 @@
     }
 
     public void handleMessage(SoapMessage message) throws Fault {
+        XMLStreamReader reader = message.getContent(XMLStreamReader.class);
+        message.setContent(Exception.class, unmarshalFault(message, reader));
+    }
+
+    public static SoapFault unmarshalFault(SoapMessage message, 
+                                           XMLStreamReader reader) {
         String exMessage = null;
         QName faultCode = null;
         QName subCode = null;
@@ -57,7 +63,6 @@
         String node = null;
         Element detail = null;
 
-        XMLStreamReader reader = message.getContent(XMLStreamReader.class);
         Map<String, String> ns = new HashMap<String, String>();
         ns.put("s", Soap12.SOAP_NAMESPACE);
         XPathUtils xu = new XPathUtils(ns);        
@@ -106,8 +111,7 @@
         fault.setDetail(detail);
         fault.setRole(role);
         fault.setNode(node);
-
-        message.setContent(Exception.class, fault);
+        return fault;
     }
 
 }

Modified: cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java?rev=720218&r1=720217&r2=720218&view=diff
==============================================================================
--- cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java (original)
+++ cxf/trunk/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/saaj/SAAJInInterceptor.java Mon Nov 24 08:17:34 2008
@@ -28,6 +28,7 @@
 import javax.xml.soap.MessageFactory;
 import javax.xml.soap.SOAPConstants;
 import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPFault;
 import javax.xml.soap.SOAPHeader;
 import javax.xml.soap.SOAPMessage;
 import javax.xml.soap.SOAPPart;
@@ -45,6 +46,8 @@
 import org.apache.cxf.binding.soap.SoapHeader;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
+import org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor;
+import org.apache.cxf.binding.soap.interceptor.Soap12FaultInInterceptor;
 import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.databinding.DataBinding;
 import org.apache.cxf.headers.Header;
@@ -107,11 +110,38 @@
             }
             
             XMLStreamReader xmlReader = message.getContent(XMLStreamReader.class);
-            StaxUtils.readDocElements(soapMessage.getSOAPBody(), xmlReader, true);
-            DOMSource bodySource = new DOMSource(soapMessage.getSOAPPart().getEnvelope().getBody());
-            xmlReader = StaxUtils.createXMLStreamReader(bodySource);
-            xmlReader.nextTag();
-            xmlReader.nextTag(); // move past body tag
+
+            if (hasFault(message, xmlReader)) {
+                SOAPFault soapFault = 
+                    soapMessage.getSOAPPart().getEnvelope().getBody().addFault();
+                SoapFault fault = 
+                    message.getVersion() instanceof Soap11 
+                    ? Soap11FaultInInterceptor.unmarshalFault(message, xmlReader)
+                    : Soap12FaultInInterceptor.unmarshalFault(message, xmlReader);
+                if (fault.getFaultCode() != null) {
+                    soapFault.setFaultCode(fault.getFaultCode());
+                }
+                if (fault.getMessage() != null) {
+                    soapFault.setFaultString(fault.getMessage());
+                }
+                if (fault.getRole() != null) {
+                    soapFault.setFaultActor(fault.getRole());
+                }
+                if (fault.getDetail() != null) {
+                    soapFault.addDetail().appendChild(
+                        soapMessage.getSOAPPart().importNode(
+                            fault.getDetail().getFirstChild(), true));
+                }
+
+                DOMSource bodySource = new DOMSource(soapFault);
+                xmlReader = StaxUtils.createXMLStreamReader(bodySource);
+            } else { 
+                StaxUtils.readDocElements(soapMessage.getSOAPBody(), xmlReader, true);
+                DOMSource bodySource = new DOMSource(soapMessage.getSOAPPart().getEnvelope().getBody());
+                xmlReader = StaxUtils.createXMLStreamReader(bodySource);
+                xmlReader.nextTag();
+                xmlReader.nextTag(); // move past body tag
+            }
             message.setContent(XMLStreamReader.class, xmlReader);           
         } catch (SOAPException soape) {
             throw new SoapFault(new org.apache.cxf.common.i18n.Message(
@@ -170,4 +200,14 @@
         }
     }
 
+
+    private static boolean hasFault(SoapMessage message, 
+                                    XMLStreamReader xmlReader) {
+        try {
+            QName name = xmlReader.getName();
+            return message.getVersion().getFault().equals(name);
+        } catch (Exception e) {
+            return false;
+        }
+    }
 }

Modified: cxf/trunk/systests/src/test/java/org/apache/cxf/systest/handlers/HandlerInvocationTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/handlers/HandlerInvocationTest.java?rev=720218&r1=720217&r2=720218&view=diff
==============================================================================
--- cxf/trunk/systests/src/test/java/org/apache/cxf/systest/handlers/HandlerInvocationTest.java (original)
+++ cxf/trunk/systests/src/test/java/org/apache/cxf/systest/handlers/HandlerInvocationTest.java Mon Nov 24 08:17:34 2008
@@ -20,6 +20,7 @@
 
 
 import java.io.InputStream;
+import java.io.StringWriter;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Iterator;
@@ -31,9 +32,15 @@
 import javax.xml.soap.MessageFactory;
 import javax.xml.soap.SOAPBody;
 import javax.xml.soap.SOAPConstants;
+import javax.xml.soap.SOAPEnvelope;
 import javax.xml.soap.SOAPFault;
 import javax.xml.soap.SOAPMessage;
+import javax.xml.transform.OutputKeys;
 import javax.xml.transform.Source;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.stream.StreamResult;
 import javax.xml.ws.Binding;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.Dispatch;
@@ -813,6 +820,7 @@
     
     @Test
     public void testSOAPHandlerHandleFaultThrowsSOAPFaultExceptionServerOutbound() throws PingException {
+
         try {
             handlerTest.pingWithArgs("soapHandler3 inbound throw ProtocolException "
                                      + "soapHandler4HandleFaultThrowsSOAPFaultException");
@@ -944,6 +952,97 @@
                 .indexOf("RemoteException with nested RuntimeException") > -1);*/
         }        
     }
+
+
+    @Test
+    public void testServerEndpointRemoteFault() throws PingException {
+
+        TestHandler<LogicalMessageContext> handler1 = new TestHandler<LogicalMessageContext>(false);
+        TestHandler<LogicalMessageContext> handler2 = new TestHandler<LogicalMessageContext>(false) {
+            public boolean handleFault(LogicalMessageContext ctx) {
+                super.handleFault(ctx);
+                try {
+                    Boolean outbound = (Boolean)
+                        ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+                    if (!outbound) {
+                        LogicalMessage msg = ctx.getMessage();
+                        String payload = convertDOMToString(msg.getPayload());
+                        assertTrue(payload.indexOf(
+                            "<faultstring>"
+                            + "servant throws SOAPFaultException"
+                            + "</faultstring>") > -1);
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    fail(e.toString());
+                }
+                return true;
+            }
+
+            private String convertDOMToString(Source s) 
+                throws TransformerException {
+                StringWriter stringWriter = new StringWriter();
+                StreamResult streamResult = new StreamResult(stringWriter);
+                TransformerFactory transformerFactory = 
+                    TransformerFactory.newInstance();
+                Transformer transformer = transformerFactory.newTransformer();
+                transformer.setOutputProperty(OutputKeys.INDENT, "no");
+                transformer.setOutputProperty(
+                    "{http://xml.apache.org/xslt}indent-amount", 
+                    "2");
+                transformer.setOutputProperty(OutputKeys.METHOD, "xml");
+                transformer.transform(s, streamResult);
+                return stringWriter.toString();
+            }
+        };
+       
+        TestSOAPHandler soapHandler1 = new TestSOAPHandler(false);
+        TestSOAPHandler soapHandler2 = new TestSOAPHandler(false) {
+            public boolean handleFault(SOAPMessageContext ctx) {
+                super.handleFault(ctx);
+                try {
+                    Boolean outbound = (Boolean)
+                        ctx.get(MessageContext.MESSAGE_OUTBOUND_PROPERTY);
+                    if (!outbound) {
+                        SOAPEnvelope env =
+                            ctx.getMessage().getSOAPPart().getEnvelope();
+                        assertTrue("expected SOAPFault in SAAJ model",
+                                   env.getBody().hasFault());
+                    }
+                } catch (Exception e) {
+                    e.printStackTrace();
+                    fail(e.toString());
+                }
+                return true;
+            }
+        };
+
+        addHandlersToChain((BindingProvider)handlerTest, handler1, handler2, soapHandler1, soapHandler2);
+
+        try {
+            handlerTest.pingWithArgs("servant throw SOAPFaultException");
+            fail("did not get expected Exception");
+        } catch (SOAPFaultException sfe) {
+            // expected
+        }        
+
+        assertEquals(1, handler1.getHandleMessageInvoked());
+        assertEquals(1, handler2.getHandleMessageInvoked());
+        assertEquals(1, soapHandler1.getHandleMessageInvoked());
+        assertEquals(1, soapHandler2.getHandleMessageInvoked());
+        
+        assertEquals(1, handler2.getHandleFaultInvoked());
+        assertEquals(1, handler1.getHandleFaultInvoked());
+        assertEquals(1, soapHandler1.getHandleFaultInvoked());
+        assertEquals(1, soapHandler2.getHandleFaultInvoked());
+
+        assertEquals(1, handler1.getCloseInvoked());
+        assertEquals(1, handler2.getCloseInvoked());
+        assertEquals(1, soapHandler1.getCloseInvoked());
+        assertEquals(1, soapHandler2.getCloseInvoked());
+        assertTrue(handler2.getInvokeOrderOfClose()
+                   < handler1.getInvokeOrderOfClose());   
+    }
  
     /*-------------------------------------------------------
      * This is the expected order