You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by em...@apache.org on 2012/08/13 12:54:41 UTC

svn commit: r1372358 - in /cxf/branches/2.4.x-fixes: parent/ rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/ rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/ rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/ rt/w...

Author: ema
Date: Mon Aug 13 10:54:40 2012
New Revision: 1372358

URL: http://svn.apache.org/viewvc?rev=1372358&view=rev
Log:
[CXF-4468]:Port the fix for faultTo request is not correctly transmitted to the specified address

Added:
    cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandler.java
    cxf/branches/2.4.x-fixes/rt/ws/addr/src/test/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandlerTest.java
    cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/FaultToEndpointServer.java
    cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/WSAFaultToClientServerTest.java
Removed:
    cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/OneWayDecoupledFaultHandler.java
    cxf/branches/2.4.x-fixes/rt/ws/addr/src/test/java/org/apache/cxf/ws/addressing/soap/OneWayDecoupledFaultHandlerTest.java
Modified:
    cxf/branches/2.4.x-fixes/parent/pom.xml
    cxf/branches/2.4.x-fixes/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultOutInterceptor.java
    cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/ContextUtils.java
    cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java

Modified: cxf/branches/2.4.x-fixes/parent/pom.xml
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/parent/pom.xml?rev=1372358&r1=1372357&r2=1372358&view=diff
==============================================================================
--- cxf/branches/2.4.x-fixes/parent/pom.xml (original)
+++ cxf/branches/2.4.x-fixes/parent/pom.xml Mon Aug 13 10:54:40 2012
@@ -93,13 +93,10 @@
         <cxf.stax.impl.version>${cxf.woodstox.core.version}</cxf.stax.impl.version>
         <cxf.woodstox.stax2-api.version>3.1.1</cxf.woodstox.stax2-api.version>
         <cxf.wsdl4j.version>1.6.2</cxf.wsdl4j.version>
-<<<<<<< HEAD
         <cxf.xmlbeans.version>2.4.0</cxf.xmlbeans.version>
         <cxf.xmlschema.version>2.0.2</cxf.xmlschema.version>
-=======
         <cxf.xmlbeans.version>2.5.0</cxf.xmlbeans.version>
         <cxf.xmlschema.version>2.0.3</cxf.xmlschema.version>
->>>>>>> 77a24d7... Merged revisions 1372095 via  git cherry-pick from
         <cxf.jibx.version>1.2.4.5</cxf.jibx.version>
         <cxf.axiom.version>1.2.10</cxf.axiom.version>
         <cxf.jettison.version>1.3.2</cxf.jettison.version>

Modified: cxf/branches/2.4.x-fixes/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultOutInterceptor.java?rev=1372358&r1=1372357&r2=1372358&view=diff
==============================================================================
--- cxf/branches/2.4.x-fixes/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultOutInterceptor.java (original)
+++ cxf/branches/2.4.x-fixes/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/Soap11FaultOutInterceptor.java Mon Aug 13 10:54:40 2012
@@ -85,7 +85,12 @@ public class Soap11FaultOutInterceptor e
     
                 writer.writeStartElement("faultstring");
                 if (fault.getMessage() != null) {
-                    writer.writeCharacters(fault.getMessage());
+                    if (message.get("forced.faultstring") != null) {
+                        writer.writeCharacters((String)message.get("forced.faultstring"));
+                    } else {
+                        writer.writeCharacters(fault.getMessage());
+                    }
+                    
                 } else {
                     writer.writeCharacters("Fault occurred while processing.");
                 }

Modified: cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/ContextUtils.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/ContextUtils.java?rev=1372358&r1=1372357&r2=1372358&view=diff
==============================================================================
--- cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/ContextUtils.java (original)
+++ cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/ContextUtils.java Mon Aug 13 10:54:40 2012
@@ -53,6 +53,7 @@ import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageImpl;
 import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.service.model.BindingFaultInfo;
 import org.apache.cxf.service.model.BindingOperationInfo;
 import org.apache.cxf.service.model.EndpointInfo;
@@ -372,22 +373,22 @@ public final class ContextUtils {
      * @param inMAPs the inbound MAPs
      * @param inMessage the current message
      */
+    //CHECKSTYLE:OFF  Max executable statement count limitation
     public static void rebaseResponse(EndpointReferenceType reference,
                                       AddressingProperties inMAPs,
                                       final Message inMessage) {
         
         String namespaceURI = inMAPs.getNamespaceURI();
-        if (!retrievePartialResponseSent(inMessage)) {
-            storePartialResponseSent(inMessage);
+        if (!ContextUtils.retrievePartialResponseSent(inMessage)) {
+            ContextUtils.storePartialResponseSent(inMessage);
             Exchange exchange = inMessage.getExchange();
             Message fullResponse = exchange.getOutMessage();
-            Message partialResponse = createMessage(exchange);
+            Message partialResponse = ContextUtils.createMessage(exchange);
             ensurePartialResponseMAPs(partialResponse, namespaceURI);
             
             // ensure the inbound MAPs are available in the partial response
             // message (used to determine relatesTo etc.)
-            propogateReceivedMAPs(inMAPs, partialResponse);
-            partialResponse.put(Message.PARTIAL_RESPONSE_MESSAGE, Boolean.TRUE);
+            ContextUtils.propogateReceivedMAPs(inMAPs, partialResponse);
             Destination target = inMessage.getDestination();
             if (target == null) {
                 return;
@@ -400,7 +401,67 @@ public final class ContextUtils {
                 Conduit backChannel = target.getBackChannel(inMessage,
                                                             partialResponse,
                                                             reference);
+                Exception exception = inMessage.getContent(Exception.class);
+                //Add this to handle two way faultTo
+                //TODO:Look at how to refactor 
+                if (backChannel != null && !inMessage.getExchange().isOneWay() 
+                    && ContextUtils.isFault(inMessage)) {
+                    // send the fault message to faultTo Endpoint
+                    exchange.setOutMessage(ContextUtils.createMessage(exchange));
+                    exchange.put(ConduitSelector.class, new NullConduitSelector());
+                    exchange.put("org.apache.cxf.http.no_io_exceptions", true);
+                    Destination destination = createDecoupledDestination(exchange, reference);
+                    exchange.setDestination(destination);
+
+                    if (ContextUtils.retrieveAsyncPostResponseDispatch(inMessage)) {
+                        DelegatingInputStream in = inMessage.getContent(DelegatingInputStream.class);
+                        if (in != null) {
+                            in.cacheInput();
+                        }
+                        inMessage.getInterceptorChain().reset();
+                        //cleanup pathinfo
+                        if (inMessage.get(Message.PATH_INFO) != null) {
+                            inMessage.remove(Message.PATH_INFO);
+                        }
+                        inMessage.getInterceptorChain().doIntercept(inMessage);
+
+                    }
+
+                    // send the partial response to requester
+                    partialResponse.put("forced.faultstring",
+                                        "The server sent HTTP status code :"
+                                            + inMessage.getExchange().get(Message.RESPONSE_CODE));
+                    partialResponse.setContent(Exception.class, exception);
+                    partialResponse.put(org.apache.cxf.message.Message.PROTOCOL_HEADERS,
+                                        inMessage.get(Message.PROTOCOL_HEADERS));
+                    partialResponse.put(org.apache.cxf.message.Message.ENCODING,
+                                        inMessage.get(Message.ENCODING));
+                    partialResponse.put(ContextUtils.ACTION, inMessage.get(ContextUtils.ACTION));
+                    partialResponse.put("javax.xml.ws.addressing.context.inbound",
+                                        inMessage.get("javax.xml.ws.addressing.context.inbound"));
+                    partialResponse.put("javax.xml.ws.addressing.context.outbound",
+                                        inMessage.get("javax.xml.ws.addressing.context.outbound"));
+                    exchange.setOutMessage(partialResponse);
+                    PhaseInterceptorChain newChian = ((PhaseInterceptorChain)inMessage.getInterceptorChain())
+                        .cloneChain();
+                    partialResponse.setInterceptorChain(newChian);
+                    exchange.setDestination(target);
+                    exchange.setOneWay(false);
+                    exchange.put(ConduitSelector.class,
+                                 new PreexistingConduitSelector(backChannel, exchange.get(Endpoint.class)));
+                    if (newChian != null && !newChian.doIntercept(partialResponse)
+                        && partialResponse.getContent(Exception.class) != null) {
+                        if (partialResponse.getContent(Exception.class) instanceof Fault) {
+                            throw (Fault)partialResponse.getContent(Exception.class);
+                        } else {
+                            throw new Fault(partialResponse.getContent(Exception.class));
+                        }
+                    }
+                    return;
+                }
+                
                 if (backChannel != null) {
+                    partialResponse.put(Message.PARTIAL_RESPONSE_MESSAGE, Boolean.TRUE);
                     boolean robust =
                         MessageUtils.isTrue(inMessage.getContextualProperty(Message.ROBUST_ONEWAY));
                     
@@ -422,12 +483,13 @@ public final class ContextUtils {
                         exchange.put(BindingOperationInfo.class, boi);
                     }
                     
+                    
                     // set up interceptor chains and send message
                     InterceptorChain chain =
                         fullResponse != null
                         ? fullResponse.getInterceptorChain()
                         : OutgoingChainInterceptor.getOutInterceptorChain(exchange);
-                    exchange.setOutMessage(partialResponse);                    
+                    exchange.setOutMessage(partialResponse);
                     partialResponse.setInterceptorChain(chain);
                     exchange.put(ConduitSelector.class,
                                  new PreexistingConduitSelector(backChannel,
@@ -447,7 +509,7 @@ public final class ContextUtils {
                     exchange.put(ConduitSelector.class, new NullConduitSelector());
                     
                     if (fullResponse == null) {
-                        fullResponse = createMessage(exchange);
+                        fullResponse = ContextUtils.createMessage(exchange);
                     }
                     exchange.setOutMessage(fullResponse);
                     
@@ -457,7 +519,7 @@ public final class ContextUtils {
                     exchange.setDestination(destination);
                          
                     
-                    if (retrieveAsyncPostResponseDispatch(inMessage)) {
+                    if (ContextUtils.retrieveAsyncPostResponseDispatch(inMessage) && !robust) {
                         //need to suck in all the data from the input stream as
                         //the transport might discard any data on the stream when this 
                         //thread unwinds or when the empty response is sent back
@@ -465,24 +527,25 @@ public final class ContextUtils {
                         if (in != null) {
                             in.cacheInput();
                         }
-                        try {
-                            if (!robust) {
-                                // async service invocation required *after* a response
-                                // has been sent (i.e. to a oneway, or a partial response
-                                // to a decoupled twoway)
                         
-        
-                                // pause dispatch on current thread ...
-                                inMessage.getInterceptorChain().pause();
-
+                        // async service invocation required *after* a response
+                        // has been sent (i.e. to a oneway, or a partial response
+                        // to a decoupled twoway)
+                        
+                        //cleanup pathinfo
+                        if (inMessage.get(Message.PATH_INFO) != null) {
+                            inMessage.remove(Message.PATH_INFO);
+                        }
+                        // pause dispatch on current thread ...
+                        inMessage.getInterceptorChain().pause();
 
-                                // ... and resume on executor thread
-                                getExecutor(inMessage).execute(new Runnable() {
-                                    public void run() {
-                                        inMessage.getInterceptorChain().resume();
-                                    }
-                                });
-                            } 
+                        try {
+                            // ... and resume on executor thread
+                            getExecutor(inMessage).execute(new Runnable() {
+                                public void run() {
+                                    inMessage.getInterceptorChain().resume();
+                                }
+                            });
                         } catch (RejectedExecutionException e) {
                             LOG.warning(
                                         "Executor queue is full, use the caller thread." 
@@ -496,13 +559,13 @@ public final class ContextUtils {
                             }
                         }
                     }
-                }
+                } 
             } catch (Exception e) {
                 LOG.log(Level.WARNING, "SERVER_TRANSPORT_REBASE_FAILURE_MSG", e);
             }
         }
     }
-
+    //CHECKSTYLE:ON
     public static Destination createDecoupledDestination(
         Exchange exchange, final EndpointReferenceType reference) {
 

Added: cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandler.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandler.java?rev=1372358&view=auto
==============================================================================
--- cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandler.java (added)
+++ cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandler.java Mon Aug 13 10:54:40 2012
@@ -0,0 +1,99 @@
+/**
+ * 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.ws.addressing.soap;
+
+import java.util.Iterator;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
+import org.apache.cxf.headers.Header;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.ContextUtils;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.apache.cxf.ws.addressing.Names;
+
+/**
+ * Utility interceptor for dealing with faults occurred during processing 
+ * the one way requests with WSA FaultTo EPR pointing to a decoupled destination.
+ * 
+ * Note that this interceptor is not currently installed by default. 
+ * It can be installed using @InInterceptors and @OutInterceptors
+ * annotations or explicitly added to the list of interceptors. 
+ */
+public class DecoupledFaultHandler extends AbstractSoapInterceptor {
+    
+    public static final String WSA_ACTION = "http://schemas.xmlsoap.org/wsdl/soap/envelope/fault";
+
+    public DecoupledFaultHandler() {
+        super(Phase.PRE_PROTOCOL);
+        addBefore(MAPCodec.class.getName());
+    } 
+
+    public void handleMessage(SoapMessage message) {
+        // complete
+    }
+
+    // Ideally, this code will instead be executed as part of the Fault chain
+    // but at the moment PhaseInterceptorChain needs to be tricked that this is
+    // a two way request for a fault chain be invoked
+    public void handleFault(SoapMessage message) {
+        if (!ContextUtils.isRequestor(message)) {
+            
+            Exchange exchange = message.getExchange();
+            Message inMessage = exchange.getInMessage();
+            final AddressingProperties maps = 
+                ContextUtils.retrieveMAPs(inMessage, false, false, true);
+            
+            if (maps != null && !ContextUtils.isGenericAddress(maps.getFaultTo())) {
+                //Just keep the wsa headers to remove the not understand headers
+                Iterator<Header> iterator = message.getHeaders().iterator();
+                while (iterator.hasNext()) {
+                    Header header = iterator.next();
+                    if (!isWSAHeader(header)) {
+                        iterator.remove();
+                    }
+                }
+                exchange.setOneWay(false);
+                exchange.setOutMessage(message);
+                //manually set the action
+                message.put(ContextUtils.ACTION, WSA_ACTION);
+                Destination destination = createDecoupledDestination(
+                                               exchange, maps.getFaultTo());
+                exchange.setDestination(destination);
+            }
+            
+        }
+    }
+    
+    protected Destination createDecoupledDestination(Exchange exchange, EndpointReferenceType epr) {
+        return ContextUtils.createDecoupledDestination(exchange, epr);
+    }
+    
+    private boolean isWSAHeader(Header header) {
+        if (header.getName().getNamespaceURI().startsWith(Names.WSA_NAMESPACE_NAME)) {
+            return true;
+        }
+        return false;
+    }
+}

Modified: cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java?rev=1372358&r1=1372357&r2=1372358&view=diff
==============================================================================
--- cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java (original)
+++ cxf/branches/2.4.x-fixes/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java Mon Aug 13 10:54:40 2012
@@ -78,8 +78,8 @@ public class MAPCodec extends AbstractSo
     private static final Logger LOG = LogUtils.getL7dLogger(MAPCodec.class);
     private static final String IS_REFERENCE_PARAM_ATTR_NAME = "IsReferenceParameter";
     private static final ResourceBundle BUNDLE = LOG.getResourceBundle();
-    private static final String ONE_WAY_DECOUPLED_FAULT_SUPPORT = 
-        "org.apache.cxf.ws.addressing.oneway.decoupled_fault_support";
+    private static final String DECOUPLED_FAULT_SUPPORT = 
+        "org.apache.cxf.ws.addressing.decoupled_fault_support";
     
     /**
      * REVISIT: map usage that the *same* interceptor instance 
@@ -152,9 +152,9 @@ public class MAPCodec extends AbstractSo
                 }
             }
         } else if (MessageUtils.getContextualBoolean(message, 
-                                                     ONE_WAY_DECOUPLED_FAULT_SUPPORT, 
+                                                     DECOUPLED_FAULT_SUPPORT, 
                                                      false)) {
-            new OneWayDecoupledFaultHandler().handleFault(message);
+            new DecoupledFaultHandler().handleFault(message);
         }
     }
 

Added: cxf/branches/2.4.x-fixes/rt/ws/addr/src/test/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandlerTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/rt/ws/addr/src/test/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandlerTest.java?rev=1372358&view=auto
==============================================================================
--- cxf/branches/2.4.x-fixes/rt/ws/addr/src/test/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandlerTest.java (added)
+++ cxf/branches/2.4.x-fixes/rt/ws/addr/src/test/java/org/apache/cxf/ws/addressing/soap/DecoupledFaultHandlerTest.java Mon Aug 13 10:54:40 2012
@@ -0,0 +1,73 @@
+/**
+ * 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.ws.addressing.soap;
+
+import javax.xml.namespace.QName;
+
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.headers.Header;
+import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
+import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.transport.Destination;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.AddressingPropertiesImpl;
+import org.apache.cxf.ws.addressing.AttributedURIType;
+import org.apache.cxf.ws.addressing.ContextUtils;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.easymock.EasyMock;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class DecoupledFaultHandlerTest extends Assert {
+
+    @Test
+    public void testOnewayFault() {
+        DecoupledFaultHandler handler = new DecoupledFaultHandler() {
+            protected Destination createDecoupledDestination(Exchange exchange, EndpointReferenceType epr) {
+                assertEquals("http://bar", epr.getAddress().getValue());
+                return EasyMock.createMock(Destination.class);
+            }    
+        };
+        
+        SoapMessage message = new SoapMessage(new MessageImpl());
+        QName qname = new QName("http://cxf.apache.org/mustunderstand", "TestMU");
+        message.getHeaders().add(new Header(qname, new Object()));
+        AddressingProperties maps = new AddressingPropertiesImpl();
+        
+        EndpointReferenceType faultTo = new EndpointReferenceType();
+        faultTo.setAddress(new AttributedURIType());
+        faultTo.getAddress().setValue("http://bar");
+        maps.setFaultTo(faultTo);
+        message.put(ContextUtils.getMAPProperty(false, false, false), 
+                    maps);
+        
+        Exchange exchange = new ExchangeImpl();
+        message.setExchange(exchange);
+        exchange.setInMessage(message);
+        exchange.setOneWay(true);
+        
+        handler.handleFault(message);
+        assertTrue(message.getHeaders().isEmpty());
+        assertFalse(exchange.isOneWay());
+        assertSame(message, exchange.getOutMessage());
+        assertNotNull(exchange.getDestination());
+    }
+    
+}

Added: cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/FaultToEndpointServer.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/FaultToEndpointServer.java?rev=1372358&view=auto
==============================================================================
--- cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/FaultToEndpointServer.java (added)
+++ cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/FaultToEndpointServer.java Mon Aug 13 10:54:40 2012
@@ -0,0 +1,238 @@
+/**
+ * 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.ws.addr_feature;
+
+import java.io.IOException;
+import java.util.concurrent.Future;
+
+import javax.jws.WebService;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.xml.ws.AsyncHandler;
+import javax.xml.ws.Endpoint;
+import javax.xml.ws.Response;
+import javax.xml.ws.soap.Addressing;
+
+import org.apache.cxf.BusFactory;
+import org.apache.cxf.jaxws.EndpointImpl;
+import org.apache.cxf.testutil.common.AbstractBusTestServerBase;
+import org.apache.cxf.ws.addressing.WSAddressingFeature;
+import org.apache.cxf.ws.addressing.soap.DecoupledFaultHandler;
+import org.apache.hello_world_soap_http.BadRecordLitFault;
+import org.apache.hello_world_soap_http.Greeter;
+import org.apache.hello_world_soap_http.NoSuchCodeLitFault;
+import org.apache.hello_world_soap_http.types.BareDocumentResponse;
+import org.apache.hello_world_soap_http.types.GreetMeLaterResponse;
+import org.apache.hello_world_soap_http.types.GreetMeResponse;
+import org.apache.hello_world_soap_http.types.GreetMeSometimeResponse;
+import org.apache.hello_world_soap_http.types.SayHiResponse;
+import org.apache.hello_world_soap_http.types.TestDocLitFaultResponse;
+import org.apache.hello_world_soap_http.types.TestNillableResponse;
+import org.eclipse.jetty.server.Request;
+import org.eclipse.jetty.server.handler.AbstractHandler;
+
+public class FaultToEndpointServer extends AbstractBusTestServerBase {  
+    static final String FAULT_PORT = allocatePort(FaultToEndpointServer.class);
+    static final String PORT = allocatePort(FaultToEndpointServer.class, 1);
+   
+    EndpointImpl ep;
+    private org.eclipse.jetty.server.Server faultToserver;
+    protected void run()  { 
+        faultToserver = new org.eclipse.jetty.server.Server(Integer.parseInt(FAULT_PORT));
+        faultToserver.setHandler(new HelloHandler());
+        try {
+            faultToserver.start();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+
+        
+        setBus(BusFactory.getDefaultBus());
+        Object implementor = new AddNumberImpl();
+        String address = "http://localhost:" + PORT + "/jaxws/add";
+
+        ep = (EndpointImpl) Endpoint.create(implementor);
+        ep.getInInterceptors().add(new DecoupledFaultHandler());
+        ep.getFeatures().add(new WSAddressingFeature());
+        ep.publish(address); 
+        
+        Object implementor2 = new GreeterImpl();
+        String address2 = "http://localhost:" + PORT + "/jaxws/greeter";
+        ep = (EndpointImpl) Endpoint.create(implementor2);
+        ep.getInInterceptors().add(new DecoupledFaultHandler());
+        ep.getFeatures().add(new WSAddressingFeature());
+        ep.publish(address2);
+    }
+    
+    public void tearDown() throws Exception {
+        if (faultToserver != null) {
+            faultToserver.stop();
+            faultToserver.destroy();
+            faultToserver = null;
+        }
+        
+        ep.stop();
+        ep = null;        
+    }
+
+    public static void main(String[] args) {
+        try {
+            FaultToEndpointServer server = new FaultToEndpointServer();
+            server.start();
+        } catch (Exception ex) {
+            ex.printStackTrace();
+            System.exit(-1);
+        } finally {
+            System.out.println("done!");
+        }
+    }
+       
+    
+
+
+    public static class HelloHandler extends AbstractHandler {
+        private static String faultRequestPath;
+
+        public void handle(String target, Request baseRequest, HttpServletRequest request,
+                           HttpServletResponse response) throws IOException, ServletException {
+            response.setContentType("text/html;charset=utf-8");
+            faultRequestPath = request.getPathInfo();
+            if ("/faultTo".equals(faultRequestPath)) {
+                response.setStatus(HttpServletResponse.SC_OK);
+            } else {
+                response.setStatus(HttpServletResponse.SC_NOT_FOUND);
+            }
+            baseRequest.setHandled(true);
+            response.getWriter().println("Received");
+        }
+
+        public static String getFaultRequestPath() {
+            return faultRequestPath;
+        }
+
+    }
+    
+    @WebService(serviceName = "SOAPServiceAddressing", 
+                portName = "SoapPort", 
+                endpointInterface = "org.apache.hello_world_soap_http.Greeter", 
+                targetNamespace = "http://apache.org/hello_world_soap_http",
+                wsdlLocation = "testutils/hello_world.wsdl")
+    @Addressing
+    public class GreeterImpl implements Greeter {
+
+        public String greetMe(String me) {
+            return "Hello " + me;
+        }
+
+        public String greetMeLater(long delay) {
+            if (delay > 0) {
+                try {
+                    Thread.sleep(delay);
+                } catch (InterruptedException ex) {
+                    // ignore
+                }
+            }
+            return "Hello, finally";
+        }
+
+        public void greetMeOneWay(String requestType) {
+            throw new RuntimeException("intended error"); 
+        }
+
+        public String sayHi() {
+            return null;
+        }
+        
+        public void testDocLitFault(String faultType) throws BadRecordLitFault, NoSuchCodeLitFault {
+        }
+
+        public BareDocumentResponse testDocLitBare(String in) {
+            return null;
+        }
+
+        public String greetMeSometime(String me) {
+            return null;
+        }
+        
+        public Future<?>  greetMeSometimeAsync(String requestType, 
+                                               AsyncHandler<GreetMeSometimeResponse> asyncHandler) { 
+            return null; 
+        }
+        
+        public Response<GreetMeSometimeResponse> greetMeSometimeAsync(String requestType) { 
+            return null; 
+        }
+        
+        public Response<TestDocLitFaultResponse> testDocLitFaultAsync(String faultType) {  
+            return null; 
+        }
+        
+        public Response<BareDocumentResponse> testDocLitBareAsync(String bare) {
+            return null;
+        }
+        
+        public Future<?> greetMeAsync(String requestType, AsyncHandler<GreetMeResponse> asyncHandler) { 
+            return null; 
+        }
+        
+        public Response<GreetMeResponse> greetMeAsync(String requestType) { 
+            return null; 
+        }
+        
+        public Future<?> greetMeLaterAsync(long requestType, AsyncHandler<GreetMeLaterResponse> asyncHandler) { 
+            return null; 
+        }
+        
+        public Response<GreetMeLaterResponse> greetMeLaterAsync(long requestType) { 
+            return null; 
+        }
+        
+        public Future<?> sayHiAsync(AsyncHandler<SayHiResponse> asyncHandler) { 
+            return null; 
+        }
+        
+        public Response<SayHiResponse> sayHiAsync() { 
+            return null; 
+        }
+
+        public String testNillable(String nillElem, int intElem) {
+            return null;
+        }
+
+        public Response<TestNillableResponse> testNillableAsync(String nillElem,
+                                                                int intElem) {
+            return null;
+        }
+        
+        public Future<?> testNillableAsync(String nillElem, 
+                                           int intElem,
+                                           AsyncHandler<TestNillableResponse> asyncHandler) {
+            return null;
+        }
+
+        public Future<?> testDocLitFaultAsync(String faultType,
+                                              AsyncHandler<TestDocLitFaultResponse> asyncHandler) {
+            return null;
+        }
+        
+    }
+}   
+
+

Added: cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/WSAFaultToClientServerTest.java
URL: http://svn.apache.org/viewvc/cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/WSAFaultToClientServerTest.java?rev=1372358&view=auto
==============================================================================
--- cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/WSAFaultToClientServerTest.java (added)
+++ cxf/branches/2.4.x-fixes/systests/ws-specs/src/test/java/org/apache/cxf/systest/ws/addr_feature/WSAFaultToClientServerTest.java Mon Aug 13 10:54:40 2012
@@ -0,0 +1,132 @@
+/**
+ * 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.ws.addr_feature;
+
+import java.io.ByteArrayOutputStream;
+import java.net.URL;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.BindingProvider;
+import javax.xml.ws.soap.AddressingFeature;
+
+import org.apache.cxf.systest.ws.AbstractWSATestBase;
+import org.apache.cxf.systest.ws.addr_feature.FaultToEndpointServer.HelloHandler;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.AddressingPropertiesImpl;
+import org.apache.cxf.ws.addressing.AttributedURIType;
+import org.apache.cxf.ws.addressing.EndpointReferenceType;
+import org.apache.cxf.ws.addressing.JAXWSAConstants;
+import org.apache.hello_world_soap_http.Greeter;
+import org.apache.hello_world_soap_http.SOAPService;
+
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class WSAFaultToClientServerTest  extends AbstractWSATestBase {
+
+    @Before
+    public void setUp() throws Exception {
+        createBus();
+    }
+
+    @BeforeClass
+    public static void startServers() throws Exception {
+        assertTrue("FaultTo server did not launch correctly", launchServer(FaultToEndpointServer.class, true));
+    }
+    
+    @Test
+    public void testOneWayFaultTo() throws Exception {
+        URL wsdl = getClass().getResource("/wsdl/hello_world.wsdl");
+        QName serviceName = new QName("http://apache.org/hello_world_soap_http", "SOAPServiceAddressing");
+
+        Greeter greeter = new SOAPService(wsdl, serviceName).getPort(Greeter.class, new AddressingFeature());
+        EndpointReferenceType faultTo = new EndpointReferenceType();
+        AddressingProperties addrProperties = new AddressingPropertiesImpl();
+        AttributedURIType epr = new AttributedURIType();
+        String faultToAddress = "http://localhost:" + FaultToEndpointServer.FAULT_PORT  + "/faultTo";
+        epr.setValue(faultToAddress);
+        faultTo.setAddress(epr);
+        addrProperties.setFaultTo(faultTo);
+        
+        BindingProvider provider = (BindingProvider) greeter;
+        Map<String, Object> requestContext = provider.getRequestContext();
+        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
+                           "http://localhost:" + FaultToEndpointServer.PORT + "/jaxws/greeter");
+        requestContext.put(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES, addrProperties);
+
+        greeter.greetMeOneWay("test");
+        //wait for the fault request
+        int i = 2;
+        while (HelloHandler.getFaultRequestPath() == null && i > 0) {
+            Thread.sleep(500);
+            i--;
+        }
+        assertTrue("FaultTo request fpath isn't expected", 
+                   "/faultTo".equals(HelloHandler.getFaultRequestPath()));
+    }
+    
+    @Test
+    public void testTwoWayFaultTo() throws Exception {
+        ByteArrayOutputStream input = setupInLogging();
+        AddNumbersPortType port = getTwoWayPort();
+
+        EndpointReferenceType faultTo = new EndpointReferenceType();
+        AddressingProperties addrProperties = new AddressingPropertiesImpl();
+        AttributedURIType epr = new AttributedURIType();
+        epr.setValue("http://localhost:" + FaultToEndpointServer.FAULT_PORT + "/faultTo");
+        faultTo.setAddress(epr);
+        addrProperties.setFaultTo(faultTo);
+        
+        BindingProvider provider = (BindingProvider) port;
+        Map<String, Object> requestContext = provider.getRequestContext();
+        requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
+                           "http://localhost:" + FaultToEndpointServer.PORT + "/jaxws/add");
+        requestContext.put(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES, addrProperties);
+
+        try {
+            port.addNumbers(-1, -2);
+            fail("Exception is expected");
+        } catch (Exception e) {
+            //do nothing
+        }
+               
+        assertTrue("The response from faultTo endpoint is expected and actual response is " 
+                   + new String(input.toByteArray()) , 
+                   new String(input.toByteArray()).indexOf("The server sent HTTP status code :200") > -1);
+        assertTrue("WS addressing header is expected", 
+                   new String(input.toByteArray()).indexOf("http://www.w3.org/2005/08/addressing") > -1);       
+        assertTrue("Fault deatil is expected", 
+                   new String(input.toByteArray()).indexOf("Negative numbers cant be added") > -1);
+    }
+     
+    private AddNumbersPortType getTwoWayPort() throws Exception {
+        URL wsdl = getClass().getResource("/wsdl_systest_wsspec/add_numbers.wsdl");
+        assertNotNull("WSDL is null", wsdl);
+        QName serviceName = new QName("http://apache.org/cxf/systest/ws/addr_feature/", "AddNumbersService");
+        AddNumbersService service = new AddNumbersService(wsdl, serviceName);
+        assertNotNull("Service is null ", service);
+        AddNumbersPortType port = service.getAddNumbersPort(new AddressingFeature());
+        //updateAddressPort(port, PORT);
+        return port;
+    }
+    
+    
+}