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 2014/07/11 20:30:27 UTC

[1/5] git commit: [CXF-5871] Fix dispatch.invokeAsync not sending proper Action

Repository: cxf
Updated Branches:
  refs/heads/master 9be6ef67c -> a4e4ea126


[CXF-5871] Fix dispatch.invokeAsync not sending proper Action


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/1b3b938b
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/1b3b938b
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/1b3b938b

Branch: refs/heads/master
Commit: 1b3b938b02d491520377aa5fa020baa971025782
Parents: 388ee56
Author: Daniel Kulp <dk...@apache.org>
Authored: Fri Jul 11 12:44:03 2014 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Fri Jul 11 14:29:30 2014 -0400

----------------------------------------------------------------------
 .../java/org/apache/cxf/jaxws/DispatchImpl.java | 178 +++++++++++--------
 1 file changed, 99 insertions(+), 79 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/1b3b938b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
index 9c7d68e..968888c 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
@@ -40,11 +40,13 @@ import javax.xml.soap.SOAPMessage;
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import javax.xml.stream.XMLStreamWriter;
+import javax.xml.transform.Source;
 import javax.xml.ws.AsyncHandler;
 import javax.xml.ws.Binding;
 import javax.xml.ws.BindingProvider;
 import javax.xml.ws.Dispatch;
 import javax.xml.ws.EndpointReference;
+import javax.xml.ws.Holder;
 import javax.xml.ws.Response;
 import javax.xml.ws.Service;
 import javax.xml.ws.WebServiceException;
@@ -54,6 +56,7 @@ import javax.xml.ws.http.HTTPBinding;
 import javax.xml.ws.http.HTTPException;
 import javax.xml.ws.soap.SOAPBinding;
 import javax.xml.ws.soap.SOAPFaultException;
+
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
@@ -306,7 +309,6 @@ public class DispatchImpl<T> implements Dispatch<T>, BindingProvider, Closeable
                 getRequestContext().put("unwrap.jaxb.element", unwrapProperty);
             }
             QName opName = (QName)getRequestContext().get(MessageContext.WSDL_OPERATION);
-            boolean findDispatchOp = Boolean.TRUE.equals(getRequestContext().get("find.dispatch.operation"));
             
             boolean hasOpName;
             if (opName == null) {
@@ -320,95 +322,106 @@ public class DispatchImpl<T> implements Dispatch<T>, BindingProvider, Closeable
                     addInvokeOperation(opName, isOneWay);
                 }
             }
+            Holder<T> holder = new Holder<T>(obj);
+            opName = calculateOpName(holder, opName, hasOpName);
             
-            //CXF-2836 : find the operation for the dispatched object
-            // if findDispatchOp is already true, skip the addressing feature lookup.
-            // if the addressing feature is enabled, set findDispatchOp to true
-            if (!findDispatchOp) {
-                // the feature list to be searched is the endpoint and the bus's lists
-                List<Feature> endpointFeatures 
-                    = ((JaxWsClientEndpointImpl)client.getEndpoint()).getFeatures();
-                List<Feature> allFeatures;
-                if (client.getBus().getFeatures() != null) {
-                    allFeatures = new ArrayList<Feature>(endpointFeatures.size() 
-                        + client.getBus().getFeatures().size());
-                    allFeatures.addAll(endpointFeatures);
-                    allFeatures.addAll(client.getBus().getFeatures());
-                } else {
-                    allFeatures = endpointFeatures;
-                }
-                for (Feature feature : allFeatures) {
-                    if (feature instanceof WSAddressingFeature) {
-                        findDispatchOp = true; 
-                    }
+            Object ret[] = client.invokeWrapped(opName,
+                                                holder.value);
+            if (isOneWay || ret == null || ret.length == 0) {
+                return null;
+            }
+            return (T)ret[0];
+        } catch (Exception ex) {
+            throw mapException(ex);
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    private QName calculateOpName(Holder<T> holder, QName opName, boolean hasOpName) throws XMLStreamException {
+        boolean findDispatchOp = Boolean.TRUE.equals(getRequestContext().get("find.dispatch.operation"));
+
+        //CXF-2836 : find the operation for the dispatched object
+        // if findDispatchOp is already true, skip the addressing feature lookup.
+        // if the addressing feature is enabled, set findDispatchOp to true
+        if (!findDispatchOp) {
+            // the feature list to be searched is the endpoint and the bus's lists
+            List<Feature> endpointFeatures 
+                = ((JaxWsClientEndpointImpl)client.getEndpoint()).getFeatures();
+            List<Feature> allFeatures;
+            if (client.getBus().getFeatures() != null) {
+                allFeatures = new ArrayList<Feature>(endpointFeatures.size() 
+                    + client.getBus().getFeatures().size());
+                allFeatures.addAll(endpointFeatures);
+                allFeatures.addAll(client.getBus().getFeatures());
+            } else {
+                allFeatures = endpointFeatures;
+            }
+            for (Feature feature : allFeatures) {
+                if (feature instanceof WSAddressingFeature) {
+                    findDispatchOp = true; 
                 }
             }
-            Map<String, QName> payloadOPMap = createPayloadEleOpNameMap(
-                    client.getEndpoint().getBinding().getBindingInfo(), hasOpName);
-            if (findDispatchOp && !payloadOPMap.isEmpty()) {
-                QName payloadElementName = null;
-                if (obj instanceof javax.xml.transform.Source) {
-                    XMLStreamReader reader = null;
-                    try {
-                        reader = StaxUtils.createXMLStreamReader((javax.xml.transform.Source)obj);
-                        Document document = StaxUtils.read(reader);
-                        createdSource = new StaxSource(StaxUtils.createXMLStreamReader(document));
-                        payloadElementName = getPayloadElementName(document.getDocumentElement());
-                    } catch (Exception e) {                        
-                        // ignore, we are trying to get the operation name
-                    } finally {
-                        StaxUtils.close(reader);
-                    }
+        }
+        Source createdSource = null;
+        Map<String, QName> payloadOPMap = createPayloadEleOpNameMap(
+                client.getEndpoint().getBinding().getBindingInfo(), hasOpName);
+        if (findDispatchOp && !payloadOPMap.isEmpty()) {
+            QName payloadElementName = null;
+            if (holder.value instanceof javax.xml.transform.Source) {
+                XMLStreamReader reader = null;
+                try {
+                    reader = StaxUtils.createXMLStreamReader((javax.xml.transform.Source)holder.value);
+                    Document document = StaxUtils.read(reader);
+                    createdSource = new StaxSource(StaxUtils.createXMLStreamReader(document));
+                    payloadElementName = getPayloadElementName(document.getDocumentElement());
+                } catch (Exception e) {                        
+                    // ignore, we are trying to get the operation name
+                } finally {
+                    StaxUtils.close(reader);
                 }
-                if (obj instanceof SOAPMessage) {
-                    payloadElementName = getPayloadElementName((SOAPMessage)obj);
+            }
+            if (holder.value instanceof SOAPMessage) {
+                payloadElementName = getPayloadElementName((SOAPMessage)holder.value);
 
-                }
+            }
 
-                if (this.context != null) {
-                    payloadElementName = getPayloadElementName(obj);
-                }
+            if (this.context != null) {
+                payloadElementName = getPayloadElementName(holder.value);
+            }
 
-                if (payloadElementName != null) {
-                    if (hasOpName) {
-                        // Verify the payload element against the given operation name.
-                        // This allows graceful handling of non-standard WSDL definitions
-                        // where different operations have the same payload element.
-                        QName expectedElementName = payloadOPMap.get(opName.toString());
-                        if (expectedElementName == null || !expectedElementName.toString().equals(
-                                payloadElementName.toString())) {
-                            // Verification of the provided operation name failed.
-                            // Resolve the operation name from the payload element.
-                            hasOpName = false;
-                            payloadOPMap = createPayloadEleOpNameMap(
-                                    client.getEndpoint().getBinding().getBindingInfo(), hasOpName);
-                        }
+            if (payloadElementName != null) {
+                if (hasOpName) {
+                    // Verify the payload element against the given operation name.
+                    // This allows graceful handling of non-standard WSDL definitions
+                    // where different operations have the same payload element.
+                    QName expectedElementName = payloadOPMap.get(opName.toString());
+                    if (expectedElementName == null || !expectedElementName.toString().equals(
+                            payloadElementName.toString())) {
+                        // Verification of the provided operation name failed.
+                        // Resolve the operation name from the payload element.
+                        hasOpName = false;
+                        payloadOPMap = createPayloadEleOpNameMap(
+                                client.getEndpoint().getBinding().getBindingInfo(), hasOpName);
                     }
-                    QName dispatchedOpName = null;
-                    if (!hasOpName) {
-                        dispatchedOpName = payloadOPMap.get(payloadElementName.toString());
-                    }
-                    if (null != dispatchedOpName) {
-                        BindingOperationInfo dbop = client.getEndpoint().getBinding().getBindingInfo()
-                            .getOperation(dispatchedOpName);
-                        if (dbop != null) {
-                            opName = dispatchedOpName;
-                        }
+                }
+                QName dispatchedOpName = null;
+                if (!hasOpName) {
+                    dispatchedOpName = payloadOPMap.get(payloadElementName.toString());
+                }
+                if (null != dispatchedOpName) {
+                    BindingOperationInfo dbop = client.getEndpoint().getBinding().getBindingInfo()
+                        .getOperation(dispatchedOpName);
+                    if (dbop != null) {
+                        opName = dispatchedOpName;
                     }
                 }
-            } 
-            
-            Object ret[] = client.invokeWrapped(opName,
-                                                createdSource == null ? obj : createdSource);
-            if (isOneWay || ret == null || ret.length == 0) {
-                return null;
             }
-            return (T)ret[0];
-        } catch (Exception ex) {
-            throw mapException(ex);
         }
+        if (createdSource != null) {
+            holder.value = (T)createdSource;
+        }
+        return opName;
     }
-
   
     public Future<?> invokeAsync(T obj, AsyncHandler<T> asyncHandler) {
         checkError();
@@ -417,11 +430,15 @@ public class DispatchImpl<T> implements Dispatch<T>, BindingProvider, Closeable
         ClientCallback callback = new JaxwsClientCallback<T>(asyncHandler, this);
              
         Response<T> ret = new JaxwsResponseCallback<T>(callback);
-        try {
+        try {           
+            boolean hasOpName;
+            
             QName opName = (QName)getRequestContext().get(MessageContext.WSDL_OPERATION);
             if (opName == null) {
+                hasOpName = false;
                 opName = INVOKE_QNAME;
             } else {
+                hasOpName = true;
                 BindingOperationInfo bop = client.getEndpoint().getBinding()
                     .getBindingInfo().getOperation(opName);
                 if (bop == null) {
@@ -429,9 +446,12 @@ public class DispatchImpl<T> implements Dispatch<T>, BindingProvider, Closeable
                 }
             }
 
+            Holder<T> holder = new Holder<T>(obj);
+            opName = calculateOpName(holder, opName, hasOpName);
+            
             client.invokeWrapped(callback, 
                                  opName,
-                                 obj);
+                                 holder.value);
             
             return ret;
         } catch (Exception ex) {


[4/5] git commit: [CXF-5871] Fix checkstyle issue

Posted by dk...@apache.org.
[CXF-5871] Fix checkstyle issue


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/3aa9adf2
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/3aa9adf2
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/3aa9adf2

Branch: refs/heads/master
Commit: 3aa9adf217dd85280ba5e457eae50c986ce0a370
Parents: f4fbe42
Author: Daniel Kulp <dk...@apache.org>
Authored: Fri Jul 11 13:02:57 2014 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Fri Jul 11 14:29:31 2014 -0400

----------------------------------------------------------------------
 .../jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java      | 1 -
 1 file changed, 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/3aa9adf2/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
----------------------------------------------------------------------
diff --git a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
index 968888c..0a46dc8 100644
--- a/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
+++ b/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/DispatchImpl.java
@@ -296,7 +296,6 @@ public class DispatchImpl<T> implements Dispatch<T>, BindingProvider, Closeable
     
     @SuppressWarnings("unchecked")
     public T invoke(T obj, boolean isOneWay) {
-        StaxSource createdSource = null;
         checkError();        
         try {
             if (obj instanceof SOAPMessage) {


[2/5] git commit: [CXF-5872] Fix NPE when Dispatch clients trying to process a fault

Posted by dk...@apache.org.
[CXF-5872] Fix NPE when Dispatch clients trying to process a fault


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/388ee561
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/388ee561
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/388ee561

Branch: refs/heads/master
Commit: 388ee56113467653f48f02d1d927b91a8ce9de45
Parents: 9be6ef6
Author: Daniel Kulp <dk...@apache.org>
Authored: Fri Jul 11 12:43:21 2014 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Fri Jul 11 14:29:30 2014 -0400

----------------------------------------------------------------------
 .../java/org/apache/cxf/interceptor/ClientFaultConverter.java     | 3 +++
 1 file changed, 3 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/388ee561/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java
----------------------------------------------------------------------
diff --git a/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java b/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java
index fcaab3d..9f2a178 100644
--- a/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java
+++ b/core/src/main/java/org/apache/cxf/interceptor/ClientFaultConverter.java
@@ -169,6 +169,9 @@ public class ClientFaultConverter extends AbstractInDatabindingInterceptor {
             
             try {
                 Class<?> exClass = faultWanted.getProperty(Class.class.getName(), Class.class);
+                if (exClass == null) {
+                    return;
+                }
                 if (e == null) { 
                     Constructor<?> constructor = exClass.getConstructor(new Class[]{String.class});
                     e = constructor.newInstance(new Object[]{fault.getMessage()});


[3/5] git commit: [CXF-5873] Fix a problem of a ton of logs if the client pre-maturely closes a connection.

Posted by dk...@apache.org.
[CXF-5873] Fix a problem of a ton of logs if the client pre-maturely closes a connection.


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/f4fbe420
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/f4fbe420
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/f4fbe420

Branch: refs/heads/master
Commit: f4fbe4206eba213d60698e89bba47b1baff8dfd7
Parents: 1b3b938
Author: Daniel Kulp <dk...@apache.org>
Authored: Fri Jul 11 12:47:45 2014 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Fri Jul 11 14:29:31 2014 -0400

----------------------------------------------------------------------
 .../binding/soap/interceptor/SoapOutInterceptor.java   | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/f4fbe420/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java
index 4fde027..df17631 100644
--- a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java
+++ b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapOutInterceptor.java
@@ -20,6 +20,7 @@
 package org.apache.cxf.binding.soap.interceptor;
 
 
+import java.io.EOFException;
 import java.io.OutputStream;
 import java.util.List;
 import java.util.Map;
@@ -296,6 +297,7 @@ public class SoapOutInterceptor extends AbstractSoapInterceptor {
             try {
                 XMLStreamWriter xtw = message.getContent(XMLStreamWriter.class);
                 if (xtw != null) {
+                    // Write body end
                     xtw.writeEndElement();            
                     // Write Envelope end element
                     xtw.writeEndElement();
@@ -304,9 +306,14 @@ public class SoapOutInterceptor extends AbstractSoapInterceptor {
                     xtw.flush();
                 }
             } catch (XMLStreamException e) {
-                SoapVersion soapVersion = message.getVersion();
-                throw new SoapFault(new org.apache.cxf.common.i18n.Message("XML_WRITE_EXC", BUNDLE), e,
-                                    soapVersion.getSender());
+                if (e.getCause() instanceof EOFException) {
+                    //Nothing we can do about this, some clients will close the connection early if 
+                    //they fully parse everything they need
+                } else {
+                    SoapVersion soapVersion = message.getVersion();
+                    throw new SoapFault(new org.apache.cxf.common.i18n.Message("XML_WRITE_EXC", BUNDLE), e,
+                                        soapVersion.getSender());
+                }
             }
         }
     }


[5/5] git commit: [CXF-5874] Add ability to turn on a strict Action checking

Posted by dk...@apache.org.
[CXF-5874] Add ability to turn on a strict Action checking


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/a4e4ea12
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/a4e4ea12
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/a4e4ea12

Branch: refs/heads/master
Commit: a4e4ea126e7f68d4f7c5de02aad5eaab50ac2a96
Parents: 3aa9adf
Author: Daniel Kulp <dk...@apache.org>
Authored: Fri Jul 11 14:03:24 2014 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Fri Jul 11 14:29:31 2014 -0400

----------------------------------------------------------------------
 .../interceptor/SoapActionInInterceptor.java    | 98 +++++++++++++++-----
 .../apache/cxf/ws/addressing/soap/MAPCodec.java |  5 +-
 .../sts/symmetric/SymmetricBindingTest.java     |  2 +-
 3 files changed, 82 insertions(+), 23 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/a4e4ea12/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
----------------------------------------------------------------------
diff --git a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
index b62c83b..8a257c7 100644
--- a/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
+++ b/rt/bindings/soap/src/main/java/org/apache/cxf/binding/soap/interceptor/SoapActionInInterceptor.java
@@ -46,6 +46,7 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
     
     private static final Logger LOG = LogUtils.getL7dLogger(SoapActionInInterceptor.class);
     private static final String ALLOW_NON_MATCHING_TO_DEFAULT = "allowNonMatchingToDefaultSoapAction";
+    private static final String CALCULATED_WSA_ACTION = SoapActionInInterceptor.class.getName() + ".ACTION";
     
     public SoapActionInInterceptor() {
         super(Phase.READ);
@@ -110,6 +111,9 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
     }
     
     public static void getAndSetOperation(SoapMessage message, String action) {
+        getAndSetOperation(message, action, true);
+    }
+    public static void getAndSetOperation(SoapMessage message, String action, boolean strict) {
         if (StringUtils.isEmpty(action)) {
             return;
         }
@@ -133,11 +137,7 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
                     }
                     bindingOp = boi;
                 }
-                Object o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME);
-                if (o == null) {
-                    o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME);
-                }
-                if (o != null && action.equals(o.toString())) {
+                if (matchWSAAction(boi, action)) {
                     if (bindingOp != null && bindingOp != boi) {
                         //more than one op with the same action, will need to parse normally
                         return;
@@ -148,44 +148,100 @@ public class SoapActionInInterceptor extends AbstractSoapInterceptor {
         }
         
         if (bindingOp == null) {
-            //we didn't match the an operation, we'll try again later to make
-            //sure the incoming message did end up matching an operation.
-            //This could occur in some cases like WS-RM and WS-SecConv that will
-            //intercept the message with a new endpoint/operation
-            message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor());
+            if (strict) {
+                //we didn't match the an operation, we'll try again later to make
+                //sure the incoming message did end up matching an operation.
+                //This could occur in some cases like WS-RM and WS-SecConv that will
+                //intercept the message with a new endpoint/operation
+                message.getInterceptorChain().add(new SoapActionInAttemptTwoInterceptor(action));
+            }
             return;
         }
         
         ex.put(BindingOperationInfo.class, bindingOp);
         ex.put(OperationInfo.class, bindingOp.getOperationInfo());
     }
+    private static boolean matchWSAAction(BindingOperationInfo boi, String action) {
+        Object o = getWSAAction(boi);
+        if (o != null) {
+            String oa = o.toString();
+            if (action.equals(oa)
+                || action.equals(oa + "Request")
+                || oa.equals(action + "Request")) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private static String getWSAAction(BindingOperationInfo boi) {
+        Object o = boi.getOperationInfo().getInput().getProperty(CALCULATED_WSA_ACTION);
+        if (o == null) {
+            o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME);
+            if (o == null) {
+                o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME);
+            }
+            if (o == null) {
+                String start = getActionBaseUri(boi.getOperationInfo());
+                if (null == boi.getOperationInfo().getInputName()) {
+                    o = addPath(start, boi.getOperationInfo().getName().getLocalPart());
+                } else {
+                    o = addPath(start, boi.getOperationInfo().getInputName());
+                }
+            }
+            if (o != null) {
+                boi.getOperationInfo().getInput().setProperty(CALCULATED_WSA_ACTION, o);
+            }
+        }
+        return o == null ? null : o.toString();
+    }
+    private static String getActionBaseUri(final OperationInfo operation) {
+        String interfaceName = operation.getInterface().getName().getLocalPart();
+        return addPath(operation.getName().getNamespaceURI(), interfaceName);
+    }
+    private static String getDelimiter(String uri) {
+        if (uri.startsWith("urn")) {
+            return ":";
+        }
+        return "/";
+    }
+
+    private static String addPath(String uri, String path) {
+        StringBuilder buffer = new StringBuilder();
+        buffer.append(uri);
+        String delimiter = getDelimiter(uri);
+        if (!uri.endsWith(delimiter) && !path.startsWith(delimiter)) {
+            buffer.append(delimiter);
+        }
+        buffer.append(path);
+        return buffer.toString();
+    }
+
     
     public static class SoapActionInAttemptTwoInterceptor extends AbstractSoapInterceptor {
-        public SoapActionInAttemptTwoInterceptor() {
-            super(Phase.PRE_LOGICAL);
+        final String action;
+        public SoapActionInAttemptTwoInterceptor(String action) {
+            super(action, Phase.PRE_LOGICAL);
+            this.action = action;
         }
         public void handleMessage(SoapMessage message) throws Fault {
             BindingOperationInfo boi = message.getExchange().getBindingOperationInfo();
             if (boi == null) {
                 return;
             }
-            String action = getSoapAction(message);
             if (StringUtils.isEmpty(action)) {
                 return;
             }
             if (isActionMatch(message, boi, action)) {
                 return;
             }
-
-            Object o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAM_ACTION_QNAME);
-            if (o == null) {
-                o = boi.getOperationInfo().getInput().getExtensionAttribute(JAXWSAConstants.WSAW_ACTION_QNAME);
-            }
-            if (o != null && action.equals(o.toString())) {
+            if (matchWSAAction(boi, action)) {
                 return;
             }
-            
-            throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
+            boolean synthetic = Boolean.TRUE.equals(boi.getProperty("operation.is.synthetic"));
+            if (!synthetic) {
+                throw new Fault("SOAP_ACTION_MISMATCH", LOG, null, action);
+            }
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cxf/blob/a4e4ea12/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
----------------------------------------------------------------------
diff --git a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
index bae8019..e0a5bf6 100644
--- a/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
+++ b/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
@@ -181,7 +181,10 @@ public class MAPCodec extends AbstractSoapInterceptor {
                     //try and use the Action from the maps to find the operation
                     String action = maps.getAction().getValue();
                     if (action != null) {
-                        SoapActionInInterceptor.getAndSetOperation(message, action);
+                        boolean strict = MessageUtils.getContextualBoolean(message, 
+                                                                           "ws-addressing.strict.action.checking", 
+                                                                           false);
+                        SoapActionInInterceptor.getAndSetOperation(message, action, strict);
                     }
                 }
             }

http://git-wip-us.apache.org/repos/asf/cxf/blob/a4e4ea12/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
----------------------------------------------------------------------
diff --git a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
index 9b232a5..3359cc9 100644
--- a/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
+++ b/services/sts/systests/basic/src/test/java/org/apache/cxf/systest/sts/symmetric/SymmetricBindingTest.java
@@ -261,7 +261,7 @@ public class SymmetricBindingTest extends AbstractBusClientServerTestBase {
         QName portQName = new QName(NAMESPACE, "DoubleItSymmetricSAML2Port");
        
         Dispatch<DOMSource> dispatch = 
-            service.createDispatch(portQName, DOMSource.class, Service.Mode.PAYLOAD);
+            service.createDispatch(portQName, DOMSource.class, Service.Mode.PAYLOAD, new AddressingFeature());
         updateAddressPort(dispatch, test.getPort());
         
         // Setup STSClient