You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by an...@apache.org on 2007/04/27 20:56:32 UTC

svn commit: r533191 [1/2] - in /incubator/cxf/trunk: rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/ rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/ rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/ rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/...

Author: andreasmyth
Date: Fri Apr 27 11:56:29 2007
New Revision: 533191

URL: http://svn.apache.org/viewvc?view=rev&rev=533191
Log:
[JIRA CXF-349] Improved error handling in case messages are delivered multiple times and delivery assurance is AtMostOnce.
Proper encoding of RM faults as soap faults (in case of Soap 1.1 with a SequenceFault header).

Added:
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java   (with props)
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java   (with props)
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java   (with props)
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java   (with props)
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/SoapFaultFactoryTest.java   (with props)
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/rm/atmostonce.xml   (with props)
Modified:
    incubator/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractEndpoint.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractRMInterceptor.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Destination.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/DestinationSequence.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Messages.properties
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMConstants.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMContextUtils.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMInInterceptor.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMManager.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMOutInterceptor.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFault.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFaultFactory.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/Messages.properties
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java
    incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RetransmissionQueueImpl.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractEndpointTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractRMInterceptorTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationSequenceTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMContextUtilsTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMInInterceptorTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMManagerTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMOutInterceptorTest.java
    incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptorTest.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/rm/ControlImpl.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/rm/MessageLossSimulator.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/rm/SequenceTest.java
    incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/ws/util/MessageFlow.java
    incubator/cxf/trunk/testutils/src/main/java/org/apache/cxf/greeter_control/AbstractGreeterImpl.java
    incubator/cxf/trunk/testutils/src/main/java/org/apache/cxf/greeter_control/ControlImpl.java

Modified: incubator/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java (original)
+++ incubator/cxf/trunk/rt/ws/addr/src/main/java/org/apache/cxf/ws/addressing/soap/MAPCodec.java Fri Apr 27 11:56:29 2007
@@ -339,7 +339,7 @@
                                                        headerElement, 
                                                        unmarshaller));
                             }
-                        } else if (null != headerElement.getAttribute(IS_REFERENCE_PARAM_ATTR_NAME)) {
+                        } else if (headerElement.hasAttribute(IS_REFERENCE_PARAM_ATTR_NAME)) {
                             if (null == referenceParameterHeaders) {
                                 referenceParameterHeaders = new HashSet<Element>();
                             }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractEndpoint.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractEndpoint.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractEndpoint.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractEndpoint.java Fri Apr 27 11:56:29 2007
@@ -62,9 +62,6 @@
      * @return the sequence identifier.
      */
     public Identifier generateSequenceIdentifier() {
-        String sequenceID = RMContextUtils.generateUUID();
-        Identifier sid = RMUtils.getWSRMFactory().createIdentifier();
-        sid.setValue(sequenceID);        
-        return sid;
+        return reliableEndpoint.getManager().getIdGenerator().generateSequenceIdentifier();
     }
 }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractRMInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractRMInterceptor.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractRMInterceptor.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/AbstractRMInterceptor.java Fri Apr 27 11:56:29 2007
@@ -24,7 +24,9 @@
 import java.util.logging.Logger;
 
 import org.apache.cxf.Bus;
+import org.apache.cxf.binding.Binding;
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.interceptor.Fault;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
@@ -41,7 +43,7 @@
  */
 public abstract class AbstractRMInterceptor<T extends Message> extends AbstractPhaseInterceptor<T> {
 
-    private static final Logger LOG = LogUtils.getL7dLogger(AbstractRMInterceptor.class);      
+    private static final Logger LOG = LogUtils.getL7dLogger(AbstractRMInterceptor.class); 
     private RMManager manager;
     private Bus bus;
     
@@ -74,8 +76,25 @@
         
         try {
             handle(msg);
-        } catch (SequenceFault ex) {
-            LOG.log(Level.SEVERE, "SequenceFault", ex);
+        } catch (SequenceFault sf) {
+            
+            // log the fault as it may not be reported back to the client
+            
+            Endpoint e = msg.getExchange().get(Endpoint.class);
+            Binding b = null;
+            if (null != e) {
+                b = e.getBinding();
+            }
+            if (null != b) {
+                RMManager m = getManager();
+                LOG.fine("Manager: " + m);
+                BindingFaultFactory bff = m.getBindingFaultFactory(b);
+                Fault f = bff.createFault(sf);
+                LogUtils.log(LOG, Level.SEVERE, "SEQ_FAULT_MSG", bff.toString(f));
+                throw f;
+            }
+            throw new Fault(sf);
+        }  catch (RMException ex) {
             throw new Fault(ex);
         }
     }
@@ -102,6 +121,6 @@
         }
     }
     
-    protected abstract void handle(Message message) throws SequenceFault;
+    protected abstract void handle(Message message) throws SequenceFault, RMException;
 
 }

Added: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java?view=auto&rev=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java (added)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java Fri Apr 27 11:56:29 2007
@@ -0,0 +1,33 @@
+/**
+ * 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.rm;
+
+import org.apache.cxf.interceptor.Fault;
+
+/**
+ * 
+ */
+public interface BindingFaultFactory {
+      
+    Fault createFault(SequenceFault sf);
+    
+    String toString(Fault f);
+    
+}

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/BindingFaultFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Destination.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Destination.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Destination.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Destination.java Fri Apr 27 11:56:29 2007
@@ -32,31 +32,30 @@
 import org.apache.cxf.ws.addressing.AddressingPropertiesImpl;
 import org.apache.cxf.ws.rm.persistence.RMStore;
 
-
 public class Destination extends AbstractEndpoint {
 
     private static final Logger LOG = LogUtils.getL7dLogger(Destination.class);
-    
+
     private Map<String, DestinationSequence> map;
-    
+
     Destination(RMEndpoint reliableEndpoint) {
         super(reliableEndpoint);
-        map = new HashMap<String, DestinationSequence>();    
-    }  
-    
-    public DestinationSequence getSequence(Identifier id) {        
+        map = new HashMap<String, DestinationSequence>();
+    }
+
+    public DestinationSequence getSequence(Identifier id) {
         return map.get(id.getValue());
     }
-    
-    public Collection<DestinationSequence> getAllSequences() {  
+
+    public Collection<DestinationSequence> getAllSequences() {
         return CastUtils.cast(map.values());
     }
-    
+
     public void addSequence(DestinationSequence seq) {
         addSequence(seq, true);
     }
-    
-    public void addSequence(DestinationSequence seq, boolean persist) {  
+
+    public void addSequence(DestinationSequence seq, boolean persist) {
         seq.setDestination(this);
         map.put(seq.getIdentifier().getValue(), seq);
         if (persist) {
@@ -66,51 +65,58 @@
             }
         }
     }
-    
-    public void removeSequence(DestinationSequence seq) {        
+
+    public void removeSequence(DestinationSequence seq) {
         map.remove(seq.getIdentifier().getValue());
         RMStore store = getReliableEndpoint().getManager().getStore();
         if (null != store) {
             store.removeDestinationSequence(seq.getIdentifier());
         }
     }
-  
-   /**
-    * Acknowledges receipt of a message. If the message is the last in the sequence, 
-    * sends an out-of-band SequenceAcknowledgement unless there a response will be sent
-    * to the acksTo address onto which the acknowldegment can be piggybacked. 
-    *  
-    * @param sequenceType the sequenceType object that includes identifier and message number
-    * (and possibly a lastMessage element) for the message to be acknowledged)
-    * @param replyToAddress the replyTo address of the message that carried this sequence information
-    * @throws SequenceFault if the sequence specified in <code>sequenceType</code> does not exist
-    */
-    public void acknowledge(Message message) 
-        throws SequenceFault {
+
+    /**
+     * Acknowledges receipt of a message. If the message is the last in the
+     * sequence, sends an out-of-band SequenceAcknowledgement unless there a
+     * response will be sent to the acksTo address onto which the acknowldegment
+     * can be piggybacked.
+     * 
+     * @param sequenceType the sequenceType object that includes identifier and
+     *            message number (and possibly a lastMessage element) for the
+     *            message to be acknowledged)
+     * @param replyToAddress the replyTo address of the message that carried
+     *            this sequence information
+     * @throws SequenceFault if the sequence specified in
+     *             <code>sequenceType</code> does not exist
+     */
+    public void acknowledge(Message message) throws SequenceFault, RMException {
         SequenceType sequenceType = RMContextUtils.retrieveRMProperties(message, false).getSequence();
         if (null == sequenceType) {
             return;
         }
         DestinationSequence seq = getSequence(sequenceType.getIdentifier());
+
         if (null != seq) {
+            seq.applyDeliveryAssurance(sequenceType.getMessageNumber());
             seq.acknowledge(message);
-            
+
             if (null != sequenceType.getLastMessage()) {
-                
+
                 seq.setLastMessageNumber(sequenceType.getMessageNumber());
-                
+
                 seq.scheduleImmediateAcknowledgement();
-                
-                // if we cannot expect an outgoing message to which the acknowledgement
-                // can be added we need to send an out-of-band SequenceAcknowledgement message
-                
+
+                // if we cannot expect an outgoing message to which the
+                // acknowledgement
+                // can be added we need to send an out-of-band
+                // SequenceAcknowledgement message
+
                 AddressingPropertiesImpl maps = RMContextUtils.retrieveMAPs(message, false, false);
                 String replyToAddress = null;
-                if (null != maps.getReplyTo()) { 
+                if (null != maps.getReplyTo()) {
                     replyToAddress = maps.getReplyTo().getAddress().getValue();
                 }
-                if (!(seq.getAcksTo().getAddress().getValue().equals(replyToAddress)
-                    || seq.canPiggybackAckOnPartialResponse())) {
+                if (!(seq.getAcksTo().getAddress().getValue().equals(replyToAddress) || seq
+                    .canPiggybackAckOnPartialResponse())) {
                     try {
                         getReliableEndpoint().getProxy().acknowledge(seq);
                     } catch (IOException ex) {
@@ -124,6 +130,5 @@
             throw sff.createUnknownSequenceFault(sequenceType.getIdentifier());
         }
     }
-    
-    
+
 }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/DestinationSequence.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/DestinationSequence.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/DestinationSequence.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/DestinationSequence.java Fri Apr 27 11:56:29 2007
@@ -29,7 +29,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-// import org.apache.cxf.common.i18n.Message;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.ws.addressing.v200408.EndpointReferenceType;
@@ -111,12 +110,8 @@
         BigInteger messageNumber = st.getMessageNumber();
         LOG.fine("Acknowledging message: " + messageNumber);
         if (null != lastMessageNumber && messageNumber.compareTo(lastMessageNumber) > 0) {
-            SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
-            sf.setFaultCode(RMConstants.getLastMessageNumberExceededFaultCode());
-            org.apache.cxf.common.i18n.Message msg = 
-                new org.apache.cxf.common.i18n.Message("LAST_MESSAGE_NUMBER_EXCEEDED_EXC", LOG, this);
-            throw new SequenceFault(msg.toString(), sf);
-        }
+            throw new SequenceFaultFactory().createLastMessageNumberExceededFault(st.getIdentifier());
+        }        
         
         monitor.acknowledgeMessage();
         
@@ -213,14 +208,15 @@
      * delivered.
      * 
      * @param s the SequenceType object including identifier and message number
+     * @throws Fault if message had already been acknowledged
      */
-    boolean applyDeliveryAssurance(BigInteger mn) {
+    void applyDeliveryAssurance(BigInteger mn) throws RMException {
         DeliveryAssuranceType da = destination.getManager().getDeliveryAssurance();
-        if (da.isSetAtMostOnce() && isAcknowledged(mn)) {
+        if (da.isSetAtMostOnce() && isAcknowledged(mn)) {            
             org.apache.cxf.common.i18n.Message msg = new org.apache.cxf.common.i18n.Message(
-                "MESSAGE_ALREADY_DELIVERED", LOG, mn, getIdentifier().getValue());
+                "MESSAGE_ALREADY_DELIVERED_EXC", LOG, mn, getIdentifier().getValue());
             LOG.log(Level.SEVERE, msg.toString());
-            return false;
+            throw new RMException(msg);
         } 
         if (da.isSetInOrder() && da.isSetAtLeastOnce()) {
             synchronized (this) {
@@ -235,7 +231,6 @@
                 }
             }
         }
-        return true;
     }
     
     synchronized boolean allPredecessorsAcknowledged(BigInteger mn) {

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Messages.properties
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Messages.properties?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Messages.properties (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/Messages.properties Fri Apr 27 11:56:29 2007
@@ -25,13 +25,22 @@
 
 POLICY_PROVIDER_CREATION_EXC = Failed to create provider for RM assertion.
 POLICY_REFERENCE_RESOLUTION_EXC = Policy reference {0} cannot be resolved.
-UNKNOWN_SEQUENCE_EXC = Unknown sequence {0}.
-LAST_MESSAGE_NUMBER_EXCEEDED_EXC = Last message number exceeded in sequence {0}.
+
+SEQ_TERMINATED_EXC = The Sequence has been terminated due to an unrecoverable error.
+UNKNOWN_SEQ_EXC = The value of wsrm:Identifier is not a known Sequence identifier.
+INVALID_ACK_EXC = The SequenceAcknowledgement violates the cumulative acknowledgement invariant.
+MESSAGE_NR_ROLLOVER_EXC = The maximim value for wsrm:MessageNumber has been exceeded.
+LAST_MESSAGE_NUMBER_EXCEEDED_EXC = The value for wsrm:MessageNumber exceeds the vaue of the MessageNumber accompanying a LastMessage element in this Sequence.
+CREATE_SEQ_REFUSED = The create sequence request has been refused by the RM destination.
+
+SEQ_FAULT_MSG = Interceptor encountered a SequenceFault: {0}.
+MAPS_RETRIEVAL_FAILURE_MSG = Failed to retrieve message addressing properties from context - not ensuring reliable delivery.
+RUNTIME_FAULT_MSG = Not ensuring reliability for the transmission of a runtime fault.
+
 LAST_MESSAGE_SEND_EXC = Failed to send an last message for sequence {0}.
 SEQ_ACK_SEND_EXC = Failed to send an acknowledgment for sequence {0}.
 ACK_REQUESTED_SEND_EXC = Failed to send a sequence acknowledgment request.
 RMASSERTION_UNMARSHAL_EXC = Failed to unmarshal RMAssertion element.
 
-MESSAGE_ALREADY_DELIVERED = Message with number {0} in sequence {1} has already been delivered.
-
+MESSAGE_ALREADY_DELIVERED_EXC = Message with number {0} in sequence {1} has already been delivered.
 

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMConstants.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMConstants.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMConstants.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMConstants.java Fri Apr 27 11:56:29 2007
@@ -47,11 +47,17 @@
     
   
     private static final String WSRM_SEQUENCE_NAME =
-        "Sequence";
+        "Sequence";    
     
     private static final QName WSRM_SEQUENCE_QNAME =
         new QName(WSRM_NAMESPACE_NAME, WSRM_SEQUENCE_NAME);
     
+    private static final String WSRM_SEQUENCE_FAULT_NAME =
+        "SequenceFault";
+    
+    private static final QName WSRM_SEQUENCE_FAULT_QNAME =
+        new QName(WSRM_NAMESPACE_NAME, WSRM_SEQUENCE_FAULT_NAME);
+    
     private static final String WSRM_SEQUENCE_ACK_NAME =
         "SequenceAcknowledgement";
     
@@ -182,6 +188,14 @@
     
     public static QName getSequenceQName() {
         return WSRM_SEQUENCE_QNAME;
+    }
+    
+    public static String getSequenceFaultName() {
+        return WSRM_SEQUENCE_FAULT_NAME;
+    }
+    
+    public static QName getSequenceFaultQName() {
+        return WSRM_SEQUENCE_FAULT_QNAME;
     }
     
     public static String getSequenceAckName() {

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMContextUtils.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMContextUtils.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMContextUtils.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMContextUtils.java Fri Apr 27 11:56:29 2007
@@ -53,23 +53,20 @@
     public static boolean isServerSide(Message message) {
         return message.getExchange().getDestination() != null;
     }
-
+    
     /**
-     * Checks if the action String belongs to an application message.
+     * Checks if the action String belongs to an RM protocol message.
      * 
      * @param action the action
      * @return true iff the action is not one of the RM protocol actions.
      */
-    public static boolean isAplicationMessage(String action) {
-        if (RMConstants.getCreateSequenceAction().equals(action)
+    public static boolean isRMProtocolMessage(String action) {
+        return RMConstants.getCreateSequenceAction().equals(action)
             || RMConstants.getCreateSequenceResponseAction().equals(action)
             || RMConstants.getTerminateSequenceAction().equals(action)
             || RMConstants.getLastMessageAction().equals(action)
             || RMConstants.getSequenceAcknowledgmentAction().equals(action)
-            || RMConstants.getSequenceInfoAction().equals(action)) {
-            return false;
-        }
-        return true;
+            || RMConstants.getSequenceInfoAction().equals(action);
     }
 
     /**

Added: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java?view=auto&rev=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java (added)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java Fri Apr 27 11:56:29 2007
@@ -0,0 +1,43 @@
+/**
+ * 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.rm;
+
+import org.apache.cxf.common.i18n.Exception;
+import org.apache.cxf.common.i18n.Message;
+
+/**
+ * PolicyException is the type of RuntimeException thrown by any exceptions encountered
+ * by the policy framework.
+ */
+public class RMException extends Exception {
+    
+    public RMException(Message msg, Throwable t) {
+        super(msg, t);
+    }
+
+    public RMException(Message msg) {
+        super(msg);
+    }
+
+    public RMException(Throwable cause) {
+        super(cause);
+    }
+
+}
\ No newline at end of file

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMException.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMInInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMInInterceptor.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMInInterceptor.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMInInterceptor.java Fri Apr 27 11:56:29 2007
@@ -36,18 +36,21 @@
     private static final Logger LOG = LogUtils.getL7dLogger(RMInInterceptor.class);
   
     public RMInInterceptor() {
+ 
         addBefore(MAPAggregator.class.getName());
     }
    
-    protected void handle(Message message) throws SequenceFault {
+    protected void handle(Message message) throws SequenceFault, RMException {
         LOG.entering(getClass().getName(), "handleMessage");
         
         RMProperties rmps = RMContextUtils.retrieveRMProperties(message, false);
         
-        // message.getExchange().put(Bus.class, getBus());
-        
+        // message addressing properties may be null, e.g. in case of a runtime fault 
+        // on the server side
         final AddressingPropertiesImpl maps = RMContextUtils.retrieveMAPs(message, false, false);
-        assert null != maps;
+        if (null == maps) {
+            return;
+        }
 
         String action = null;
         if (null != maps.getAction()) {
@@ -70,7 +73,7 @@
         
         boolean isServer = RMContextUtils.isServerSide(message);
         LOG.fine("isServerSide: " + isServer);
-        boolean isApplicationMessage = RMContextUtils.isAplicationMessage(action);       
+        boolean isApplicationMessage = !RMContextUtils.isRMProtocolMessage(action);       
         LOG.fine("isApplicationMessage: " + isApplicationMessage);
         
         // for application AND out of band messages
@@ -119,7 +122,7 @@
     }
     
     void processSequence(Destination destination, Message message) 
-        throws SequenceFault {
+        throws SequenceFault, RMException {
 
         destination.acknowledge(message);
     }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMManager.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMManager.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMManager.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMManager.java Fri Apr 27 11:56:29 2007
@@ -33,6 +33,7 @@
 import javax.xml.namespace.QName;
 
 import org.apache.cxf.Bus;
+import org.apache.cxf.binding.Binding;
 import org.apache.cxf.common.logging.LogUtils;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.message.Message;
@@ -49,6 +50,7 @@
 import org.apache.cxf.ws.rm.policy.RMAssertion;
 import org.apache.cxf.ws.rm.policy.RMAssertion.BaseRetransmissionInterval;
 import org.apache.cxf.ws.rm.soap.RetransmissionQueueImpl;
+import org.apache.cxf.ws.rm.soap.SoapFaultFactory;
 
 /**
  * 
@@ -59,6 +61,7 @@
     
     private Bus bus;
     private RMStore store;
+    private SequenceIdentifierGenerator idGenerator;
     private RetransmissionQueue retransmissionQueue;
     private Map<Endpoint, RMEndpoint> reliableEndpoints = new HashMap<Endpoint, RMEndpoint>();
     private Map<String, SourceSequence> sourceSequences;
@@ -95,11 +98,23 @@
     public void setRetransmissionQueue(RetransmissionQueue rq) {
         retransmissionQueue = rq;
     }
+    
+    public SequenceIdentifierGenerator getIdGenerator() {
+        return idGenerator;
+    }
+
+    public void setIdGenerator(SequenceIdentifierGenerator generator) {
+        idGenerator = generator;
+    }
 
     public Timer getTimer() {
         return timer;
     }
     
+    public BindingFaultFactory getBindingFaultFactory(Binding binding) {
+        return new SoapFaultFactory(binding);
+    }
+    
     public synchronized RMEndpoint getReliableEndpoint(Message message) {
         Endpoint endpoint = message.getExchange().get(Endpoint.class);
         if (LOG.isLoggable(Level.FINE)) {
@@ -256,6 +271,9 @@
         if (null == retransmissionQueue) {
             retransmissionQueue = new RetransmissionQueueImpl(this);
         }
+        if (null == idGenerator) {
+            idGenerator = new DefaultSequenceIdentifierGenerator();
+        }
     }
     
     void addSourceSequence(SourceSequence ss) {
@@ -269,5 +287,15 @@
         if (null != sourceSequences) {
             sourceSequences.remove(id.getValue());
         }
-    }  
+    } 
+    
+    class DefaultSequenceIdentifierGenerator implements SequenceIdentifierGenerator {
+
+        public Identifier generateSequenceIdentifier() {
+            String sequenceID = RMContextUtils.generateUUID();
+            Identifier sid = RMUtils.getWSRMFactory().createIdentifier();
+            sid.setValue(sequenceID);        
+            return sid;
+        }   
+    }
 }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMOutInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMOutInterceptor.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMOutInterceptor.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/RMOutInterceptor.java Fri Apr 27 11:56:29 2007
@@ -25,6 +25,7 @@
 import java.util.logging.Logger;
 
 import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.message.FaultMode;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.ws.addressing.AddressingProperties;
@@ -45,9 +46,22 @@
     
     protected void handle(Message message) throws SequenceFault {
         LOG.entering(getClass().getName(), "handleMessage");
+        
+        if (isRuntimeFault(message)) {
+            LogUtils.log(LOG, Level.WARNING, "RUNTIME_FAULT_MSG");
+            // TODO: in case of a SequenceFault need to set action
+            // to http://schemas.xmlsoap.org/ws/2004/a08/addressing/fault
+            // but: need to defer propagation of received MAPS to oubound chain            
+            return;
+        }
        
         AddressingProperties maps =
             RMContextUtils.retrieveMAPs(message, false, true);
+        if (null == maps) {
+            LogUtils.log(LOG, Level.WARNING, "MAPS_RETRIEVAL_FAILURE_MSG");
+            return;
+        }
+        
         RMContextUtils.ensureExposedVersion(maps);
         
         Source source = getManager().getSource(message);
@@ -62,7 +76,7 @@
             LOG.fine("Action: " + action);
         }
 
-        boolean isApplicationMessage = RMContextUtils.isAplicationMessage(action);
+        boolean isApplicationMessage = !RMContextUtils.isRMProtocolMessage(action);
         boolean isPartialResponse = MessageUtils.isPartialResponse(message);
         LOG.fine("isApplicationMessage: " + isApplicationMessage);
         LOG.fine("isPartialResponse: " + isPartialResponse);
@@ -179,5 +193,13 @@
                 LOG.fine("Added " + acks.size() + " acknowledgements.");
             }
         }
+    }
+    
+    boolean isRuntimeFault(Message message) {
+        FaultMode mode = MessageUtils.getFaultMode(message);
+        if (null == mode) {
+            return false;
+        }
+        return FaultMode.CHECKED_APPLICATION_FAULT != mode;
     }
 }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFault.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFault.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFault.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFault.java Fri Apr 27 11:56:29 2007
@@ -19,6 +19,8 @@
 
 package org.apache.cxf.ws.rm;
 
+import javax.xml.namespace.QName;
+
 /**
  * 
  */
@@ -26,22 +28,46 @@
 public class SequenceFault extends Exception {
     
     private SequenceFaultType sequenceFault;
+    private boolean sender;
+    private Object detail;
 
     public SequenceFault(String message) {
         super(message);
     }
 
-    public SequenceFault(String message, SequenceFaultType sequenceFault) {
-        super(message);
-        this.sequenceFault = sequenceFault;
-    }
-
-    public SequenceFault(String message, SequenceFaultType sequenceFault, Throwable cause) {
+    public SequenceFault(String message, Throwable cause) {
         super(message, cause);
-        this.sequenceFault = sequenceFault;
     }
 
-    public SequenceFaultType getFaultInfo() {
-        return this.sequenceFault;
+    public SequenceFaultType getSequenceFault() {
+        return sequenceFault;
+    }
+    
+    public void setSequenceFault(SequenceFaultType sf) {
+        sequenceFault = sf;
+    }
+    
+    public boolean isSender() {
+        return sender;
+    }
+    
+    public void setSender(boolean s) {
+        sender = s;
+    }
+    
+    public QName getSubCode() {
+        return sequenceFault.faultCode;
+    }
+    
+    public String getReason() {
+        return getMessage();
+    }
+    
+    public void setDetail(Object d) {
+        detail = d;
+    }
+    
+    public Object getDetail() {
+        return detail;
     }
 }

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFaultFactory.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFaultFactory.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFaultFactory.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceFaultFactory.java Fri Apr 27 11:56:29 2007
@@ -19,10 +19,10 @@
 
 package org.apache.cxf.ws.rm;
 
-import java.util.logging.Logger;
+import java.util.ResourceBundle;
 
+import org.apache.cxf.common.i18n.BundleUtils;
 import org.apache.cxf.common.i18n.Message;
-import org.apache.cxf.common.logging.LogUtils;
 
 /**
  * Utility class to construct SequenceFaults.
@@ -30,12 +30,72 @@
 
 class SequenceFaultFactory { 
 
-    private static final Logger LOG = LogUtils.getL7dLogger(SequenceFaultFactory.class);
-
+    private static final ResourceBundle BUNDLE = BundleUtils.getBundle(SequenceFaultFactory.class);
+    
     SequenceFault createUnknownSequenceFault(Identifier sid) {
         SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
         sf.setFaultCode(RMConstants.getUnknownSequenceFaultCode());
-        Message msg = new Message("UNKNOWN_SEQUENCE_EXC", LOG, sid.getValue());
-        return new SequenceFault(msg.toString(), sf);
-    }    
+        Message msg = new Message("UNKNOWN_SEQ_EXC", BUNDLE);
+        SequenceFault fault = new SequenceFault(msg.toString());
+        fault.setSequenceFault(sf);
+        fault.setDetail(sid);
+        fault.setSender(true);
+        return fault;
+    } 
+    
+    SequenceFault createSequenceTerminatedFault(Identifier sid, boolean sender) {
+        SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
+        sf.setFaultCode(RMConstants.getSequenceTerminatedFaultCode());
+        Message msg = new Message("SEQ_TERMINATED_EXC", BUNDLE);
+        SequenceFault fault = new SequenceFault(msg.toString());
+        fault.setSequenceFault(sf);
+        fault.setDetail(sid);
+        fault.setSender(sender);
+        return fault;
+    }
+    
+    SequenceFault createInvalidAcknowledgementFault(SequenceAcknowledgement ack) {
+        SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
+        sf.setFaultCode(RMConstants.getInvalidAcknowledgmentFaultCode());
+        Message msg = new Message("INVALID_ACK_EXC", BUNDLE);
+        SequenceFault fault = new SequenceFault(msg.toString());
+        fault.setSequenceFault(sf);
+        fault.setDetail(ack);
+        fault.setSender(true);
+        return fault;
+    }
+    
+    SequenceFault createMessageNumberRolloverFault(Identifier sid) {
+        SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
+        sf.setFaultCode(RMConstants.getMessageNumberRolloverFaultCode());
+        Message msg = new Message("MESSAGE_NR_ROLLOVER_EXC", BUNDLE);
+        SequenceFault fault = new SequenceFault(msg.toString());
+        fault.setSequenceFault(sf);
+        fault.setDetail(sid);
+        fault.setSender(true);
+        return fault;
+    }
+    
+    SequenceFault createLastMessageNumberExceededFault(Identifier sid) {
+        SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
+        sf.setFaultCode(RMConstants.getLastMessageNumberExceededFaultCode());
+        Message msg = new Message("LAST_MESSAGE_NUMBER_EXCEEDED_EXC", BUNDLE);
+        SequenceFault fault = new SequenceFault(msg.toString());
+        fault.setSequenceFault(sf);
+        fault.setDetail(sid);
+        fault.setSender(true);
+        return fault;
+    }
+    
+    SequenceFault createCreateSequenceRefusedFault() {
+        SequenceFaultType sf = RMUtils.getWSRMFactory().createSequenceFaultType();
+        sf.setFaultCode(RMConstants.getCreateSequenceRefusedFaultCode());
+        Message msg = new Message("CREATE_SEQ_REFUSED", BUNDLE);
+        SequenceFault fault = new SequenceFault(msg.toString());
+        fault.setSequenceFault(sf);
+        fault.setSender(true);
+        return fault;
+    }
+    
+    
 }

Added: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java?view=auto&rev=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java (added)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java Fri Apr 27 11:56:29 2007
@@ -0,0 +1,27 @@
+/**
+ * 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.rm;
+
+/**
+ * 
+ */
+public interface SequenceIdentifierGenerator {
+    Identifier generateSequenceIdentifier();
+}

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/SequenceIdentifierGenerator.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/Messages.properties
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/Messages.properties?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/Messages.properties (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/Messages.properties Fri Apr 27 11:56:29 2007
@@ -25,3 +25,5 @@
 SCHEDULE_RESEND_FAILED_MSG = Scheduling of WS-RM retransmission failed.
 RESEND_INITIATION_FAILED_MSG = Failed to initiate retransmission.
 NO_TRANSPORT_FOR_RESEND_MSG = No transport available for WS-RM retransmission.
+MARSHAL_FAULT_DETAIL_EXC = Failed to marshal fault detail.
+SEQ_FAULT_MSG = Reason: {0}, code: {1}, subCode: {2}
\ No newline at end of file

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java Fri Apr 27 11:56:29 2007
@@ -41,6 +41,7 @@
 import org.w3c.dom.NodeList;
 
 import org.apache.cxf.binding.Binding;
+import org.apache.cxf.binding.soap.SoapFault;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
 import org.apache.cxf.common.logging.LogUtils;
@@ -73,6 +74,8 @@
 import org.apache.cxf.ws.rm.RMMessageConstants;
 import org.apache.cxf.ws.rm.RMProperties;
 import org.apache.cxf.ws.rm.SequenceAcknowledgement;
+import org.apache.cxf.ws.rm.SequenceFault;
+import org.apache.cxf.ws.rm.SequenceFaultType;
 import org.apache.cxf.ws.rm.SequenceType;
 
 
@@ -157,11 +160,15 @@
     
     void encode(SoapMessage message) {
         RMProperties rmps = RMContextUtils.retrieveRMProperties(message, true);
-        if (null == rmps) {
-            // nothing to encode
-            return;
+        if (null != rmps) {
+            encode(message, rmps);
+        } else if (MessageUtils.isFault(message)) {
+            Exception ex = message.getContent(Exception.class);
+            if (ex instanceof SoapFault && ex.getCause() instanceof SequenceFault) {
+                encodeFault(message, (SequenceFault)ex.getCause());
+            }
         }
-        encode(message, rmps);
+        
     }
 
     /**
@@ -170,7 +177,6 @@
      * @param message the SOAP message.
      * @param rmps the current RM properties.
      */
-
     public static void encode(SoapMessage message, RMProperties rmps) {
         if (null == rmps) {
             return;
@@ -225,6 +231,41 @@
     }
     
     /**
+     * Encode the SeuqnceFault in protocol-specific header.
+     *
+     * @param message the SOAP message.
+     * @param sf the SequenceFault.
+     */
+    public static void encodeFault(SoapMessage message, SequenceFault sf) {
+        if (null == sf.getSequenceFault()) {
+            return;
+        }
+        LOG.log(Level.FINE, "Encoding SequenceFault in SOAP header");
+        try {
+            Element header = message.getHeaders(Element.class);
+            discardRMHeaders(header);
+            
+            // add WSRM namespace declaration to header, instead of
+            // repeating in each individual child node
+            header.setAttributeNS("http://www.w3.org/2000/xmlns/",
+                                  "xmlns:" + RMConstants.getNamespacePrefix(),
+                                 RMConstants.getNamespace());
+            Marshaller marshaller = getJAXBContext().createMarshaller();
+            marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
+
+            encodeProperty(sf.getSequenceFault(), 
+                           RMConstants.getSequenceFaultQName(), 
+                           SequenceFaultType.class, 
+                           header, 
+                           marshaller);
+        } catch (SOAPException se) {
+            LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", se); 
+        } catch (JAXBException je) {
+            LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je);
+        }        
+    }
+    
+    /**
      * Decode the RM properties from protocol-specific headers
      * and store them in the message.
      *  
@@ -233,6 +274,7 @@
     void decode(SoapMessage message) {
         RMProperties rmps = unmarshalRMProperties(message);
         RMContextUtils.storeRMProperties(message, rmps, false);
+        // TODO: decode SequenceFault ?
     }
     
     /**

Modified: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RetransmissionQueueImpl.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RetransmissionQueueImpl.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RetransmissionQueueImpl.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RetransmissionQueueImpl.java Fri Apr 27 11:56:29 2007
@@ -291,7 +291,8 @@
             c.prepare(message);
 
             os = message.getContent(OutputStream.class);
-            if (os instanceof AbstractCachedOutputStream && callbacks.size() > 1) {
+            if (os instanceof AbstractCachedOutputStream
+                && null != callbacks && callbacks.size() > 1) {
                 for (CachedOutputStreamCallback cb : callbacks) {
                     if (!(cb instanceof RetransmissionCallback)) {
                         ((AbstractCachedOutputStream)os).registerCallback(cb);
@@ -356,8 +357,11 @@
             Executor executor = ep.getExecutor();
             if (null == executor) {
                 executor = ep.getService().getExecutor();
+                LOG.log(Level.FINE, "Using service executor {0}", executor.getClass().getName());
+            } else {
+                LOG.log(Level.FINE, "Using endpoint executor {0}", executor.getClass().getName());
             }
-            LOG.log(Level.FINE, "Using executor {0}", executor.getClass().getName());
+            
             try {
                 executor.execute(this);
             } catch (RejectedExecutionException ex) {

Added: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java?view=auto&rev=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java (added)
+++ incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java Fri Apr 27 11:56:29 2007
@@ -0,0 +1,127 @@
+/**
+ * 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.rm.soap;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.Marshaller;
+import javax.xml.parsers.DocumentBuilderFactory;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+import org.apache.cxf.binding.Binding;
+import org.apache.cxf.binding.soap.Soap11;
+import org.apache.cxf.binding.soap.SoapBinding;
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.binding.soap.SoapVersion;
+import org.apache.cxf.common.i18n.Message;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.common.util.PackageUtils;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.ws.rm.BindingFaultFactory;
+import org.apache.cxf.ws.rm.Identifier;
+import org.apache.cxf.ws.rm.RMConstants;
+import org.apache.cxf.ws.rm.SequenceAcknowledgement;
+import org.apache.cxf.ws.rm.SequenceFault;
+import org.apache.cxf.ws.rm.SequenceType;
+
+
+
+/**
+ * 
+ */
+public class SoapFaultFactory implements BindingFaultFactory {
+
+    private static final Logger LOG = LogUtils.getL7dLogger(SoapFaultFactory.class); 
+    private static final String WS_RM_PACKAGE = 
+        PackageUtils.getPackageName(SequenceType.class);
+    
+    private SoapVersion version;
+    
+    public SoapFaultFactory(Binding binding) {
+        version = ((SoapBinding)binding).getSoapVersion();
+    }
+    
+    public Fault createFault(SequenceFault sf) {
+        Fault f = null;
+        if (version == Soap11.getInstance()) {
+            f = createSoap11Fault(sf);
+            // so we can encode the SequenceFault as header   
+            f.initCause(sf);
+        } else {
+            f = createSoap12Fault(sf);
+        }
+        return f;
+    }
+    
+    Fault createSoap11Fault(SequenceFault sf) {
+        SoapFault fault = new SoapFault(sf.getReason(),
+            sf.isSender() ? version.getSender() : version.getReceiver());
+        fault.setSubCode(sf.getSubCode());
+        return fault;
+    }
+    
+    Fault createSoap12Fault(SequenceFault sf) {
+        SoapFault fault = (SoapFault)createSoap11Fault(sf);
+        Object detail = sf.getDetail();
+        if (null == detail) {
+            return fault;
+        }
+
+        try {
+            setDetail(fault, detail);
+        } catch (Exception ex) {
+            LogUtils.log(LOG, Level.SEVERE, "MARSHAL_FAULT_DETAIL_EXC", ex); 
+            ex.printStackTrace();
+        }
+        return fault;
+    }
+    
+    void setDetail(SoapFault fault, Object detail) throws Exception {
+        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+        factory.setNamespaceAware(true);
+        Document doc = factory.newDocumentBuilder().newDocument();
+        Element elem = null;
+        
+        JAXBContext ctx = JAXBContext.newInstance(WS_RM_PACKAGE);
+        Marshaller m = ctx.createMarshaller();
+        if (RMConstants.getInvalidAcknowledgmentFaultCode().equals(fault.getSubCode())) {
+            SequenceAcknowledgement ack = (SequenceAcknowledgement)detail;
+            m.marshal(ack, doc);
+        } else if (!RMConstants.getCreateSequenceRefusedFaultCode().equals(fault.getSubCode())) {
+            Identifier id = (Identifier)detail;  
+            m.marshal(id, doc);            
+        }
+        elem = (Element)doc.getChildNodes().item(0);
+        fault.setDetail(elem);
+    }
+    
+    public String toString(Fault f) {
+        SoapFault sf = (SoapFault)f;
+        Message msg = new Message("SEQ_FAULT_MSG", LOG, 
+            new Object[] {sf.getReason(), sf.getFaultCode(), sf.getSubCode()});
+        return msg.toString();
+    }
+        
+
+}

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/SoapFaultFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractEndpointTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractEndpointTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractEndpointTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractEndpointTest.java Fri Apr 27 11:56:29 2007
@@ -63,16 +63,4 @@
         assertSame(ae, tested.getEndpoint());
         assertSame(mgr, tested.getManager());
     }
-    
-    @Test
-    public void testGenerateSequenceIdentifier() {
-        AbstractEndpoint tested = new AbstractEndpoint(null);
-        Identifier id1 = tested.generateSequenceIdentifier();
-        assertNotNull(id1);
-        assertNotNull(id1.getValue());
-        Identifier id2 = tested.generateSequenceIdentifier();
-        assertTrue(id1 != id2);
-        assertTrue(!id1.getValue().equals(id2.getValue()));     
-        control.replay();
-    }
 }

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractRMInterceptorTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractRMInterceptorTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractRMInterceptorTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/AbstractRMInterceptorTest.java Fri Apr 27 11:56:29 2007
@@ -23,7 +23,10 @@
 import java.util.Collection;
 
 import org.apache.cxf.Bus;
+import org.apache.cxf.binding.Binding;
+import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.Phase;
 import org.apache.cxf.ws.policy.AssertionInfo;
@@ -75,15 +78,29 @@
     public void testHandleMessage() {
         RMInterceptor interceptor = new RMInterceptor();
         Message message = control.createMock(Message.class);
+        SequenceFault sf = control.createMock(SequenceFault.class);
+        interceptor.setSequenceFault(sf);
+        Exchange ex = control.createMock(Exchange.class);
+        EasyMock.expect(message.getExchange()).andReturn(ex);
+        Endpoint e = control.createMock(Endpoint.class);
+        EasyMock.expect(ex.get(Endpoint.class)).andReturn(e);
+        Binding b = control.createMock(Binding.class);
+        EasyMock.expect(e.getBinding()).andReturn(b);        
+        RMManager mgr = control.createMock(RMManager.class);
+        interceptor.setManager(mgr);
+        BindingFaultFactory bff = control.createMock(BindingFaultFactory.class);
+        EasyMock.expect(mgr.getBindingFaultFactory(b)).andReturn(bff);
+        Fault fault = control.createMock(Fault.class);
+        EasyMock.expect(bff.createFault(sf)).andReturn(fault);
+        EasyMock.expect(bff.toString(fault)).andReturn("f");
         control.replay();
-        interceptor.handleMessage(message);
-        interceptor.setThrow(true);
         try {
             interceptor.handleMessage(message);
             fail("Expected Fault not thrown.");
         } catch (Fault f) {
-            assertTrue(f.getCause() instanceof SequenceFault);
+            assertSame(f, fault);            
         }
+        control.verify();
     }
     
     @Test
@@ -109,16 +126,16 @@
 
     class RMInterceptor extends AbstractRMInterceptor {
 
-        private boolean doThrow;
+        private SequenceFault sequenceFault;
         
-        void setThrow(boolean t) {
-            doThrow = t;
+        void setSequenceFault(SequenceFault sf) {
+            sequenceFault = sf;
         }
         
         @Override
         protected void handle(Message msg) throws SequenceFault {
-            if (doThrow) {
-                throw new SequenceFault("");
+            if (null != sequenceFault) { 
+                throw sequenceFault;
             }
         }     
     }

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationSequenceTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationSequenceTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationSequenceTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationSequenceTest.java Fri Apr 27 11:56:29 2007
@@ -176,7 +176,7 @@
             seq.acknowledge(message2);
             fail("Expected SequenceFault not thrown.");
         } catch (SequenceFault sf) {
-            assertEquals("LastMessageNumberExceeded", sf.getFaultInfo().getFaultCode().getLocalPart());
+            assertEquals("LastMessageNumberExceeded", sf.getSequenceFault().getFaultCode().getLocalPart());
         }
         
         control.verify();
@@ -437,7 +437,7 @@
     }
     
     @Test
-    public void testApplyDeliveryAssuranceAtMostOnce() {
+    public void testApplyDeliveryAssuranceAtMostOnce() throws RMException {
         setUpDestination();
         
         BigInteger mn = BigInteger.TEN;        
@@ -452,7 +452,7 @@
         control.replay();        
         DestinationSequence ds = new DestinationSequence(id, ref, null, ack);
         ds.setDestination(destination);
-        assertTrue("message had already been delivered", ds.applyDeliveryAssurance(mn));
+        ds.applyDeliveryAssurance(mn);
         control.verify();
         
         control.reset();
@@ -463,14 +463,20 @@
         EasyMock.expect(ack.getAcknowledgementRange()).andReturn(ranges);
         EasyMock.expect(r.getLower()).andReturn(new BigInteger("5"));
         EasyMock.expect(r.getUpper()).andReturn(new BigInteger("15"));
-        control.replay();        
-        assertTrue("message has not yet been delivered", !ds.applyDeliveryAssurance(mn));
+        control.replay();     
+        try {
+            ds.applyDeliveryAssurance(mn);
+            fail("Expected Fault not thrown.");
+        } catch (RMException ex) {
+            assertEquals("MESSAGE_ALREADY_DELIVERED_EXC", ex.getCode());
+        }
+          
         control.verify();
 
     }
     
     @Test
-    public void testInOrderNoWait() {
+    public void testInOrderNoWait() throws RMException {
         setUpDestination();
 
         BigInteger mn = BigInteger.TEN;
@@ -493,7 +499,7 @@
         
         DestinationSequence ds = new DestinationSequence(id, ref, null, ack);
         ds.setDestination(destination);
-        assertTrue(ds.applyDeliveryAssurance(mn));
+        ds.applyDeliveryAssurance(mn);
         control.verify();
     }
     
@@ -534,7 +540,7 @@
                 try {
                     ds.acknowledge(message);
                     ds.applyDeliveryAssurance(messageNr);
-                } catch (SequenceFault ex) {
+                } catch (Exception ex) {
                     // ignore
                 }
             }            

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/DestinationTest.java Fri Apr 27 11:56:29 2007
@@ -100,7 +100,7 @@
     }
     
     @Test
-    public void testAcknowledgeNoSequence() throws SequenceFault {
+    public void testAcknowledgeNoSequence() throws SequenceFault, RMException {
         Message message = setupMessage();
         RMProperties rmps = control.createMock(RMProperties.class);
         EasyMock.expect(message.get(RMMessageConstants.RM_PROPERTIES_INBOUND)).andReturn(rmps);
@@ -110,7 +110,7 @@
     }
     
     @Test
-    public void testAcknowledgeUnknownSequence() {
+    public void testAcknowledgeUnknownSequence() throws RMException {
         Message message = setupMessage();
         RMProperties rmps = control.createMock(RMProperties.class);
         EasyMock.expect(message.get(RMMessageConstants.RM_PROPERTIES_INBOUND)).andReturn(rmps);
@@ -119,18 +119,48 @@
         Identifier id = control.createMock(Identifier.class);
         EasyMock.expect(st.getIdentifier()).andReturn(id).times(2);
         String sid = "sid";
-        EasyMock.expect(id.getValue()).andReturn(sid).times(2); 
+        EasyMock.expect(id.getValue()).andReturn(sid); 
         control.replay();
         try {
             destination.acknowledge(message);   
             fail("Expected SequenceFault not thrown.");
         } catch (SequenceFault ex) {
-            assertEquals(RMConstants.getUnknownSequenceFaultCode(), ex.getFaultInfo().getFaultCode());
+            assertEquals(RMConstants.getUnknownSequenceFaultCode(), ex.getSequenceFault().getFaultCode());
         }
     }
     
     @Test
-    public void testAcknowledgeLastMessage() throws NoSuchMethodException, SequenceFault, IOException {
+    public void testAcknowledgeAlreadyAcknowledgedMessage() throws SequenceFault, RMException, 
+    NoSuchMethodException {
+        
+        Method m1 = Destination.class.getDeclaredMethod("getSequence", new Class[] {Identifier.class});
+        destination = control.createMock(Destination.class, new Method[] {m1});
+        Message message = setupMessage();
+        RMProperties rmps = control.createMock(RMProperties.class);
+        EasyMock.expect(message.get(RMMessageConstants.RM_PROPERTIES_INBOUND)).andReturn(rmps);
+        SequenceType st = control.createMock(SequenceType.class);
+        EasyMock.expect(rmps.getSequence()).andReturn(st);
+        Identifier id = control.createMock(Identifier.class);
+        EasyMock.expect(st.getIdentifier()).andReturn(id);
+        DestinationSequence ds = control.createMock(DestinationSequence.class);
+        EasyMock.expect(destination.getSequence(id)).andReturn(ds);
+        BigInteger nr = BigInteger.TEN;
+        EasyMock.expect(st.getMessageNumber()).andReturn(nr);  
+        RMException ex = new RMException(new RuntimeException("already acknowledged"));
+        ds.applyDeliveryAssurance(nr);
+        EasyMock.expectLastCall().andThrow(ex);
+        control.replay();
+        try {
+            destination.acknowledge(message); 
+            fail("Expected RMEcception not thrown.");
+        } catch (RMException e) {
+            assertSame(ex, e);
+        }
+        
+    }
+    
+    @Test
+    public void testAcknowledgeLastMessage() throws Exception {
         
         Method m1 = Destination.class.getDeclaredMethod("getSequence", new Class[] {Identifier.class});
         Method m2 = Destination.class.getMethod("getReliableEndpoint", new Class[] {});
@@ -143,14 +173,16 @@
         EasyMock.expect(rmps.getSequence()).andReturn(st);
         Identifier id = control.createMock(Identifier.class);
         EasyMock.expect(st.getIdentifier()).andReturn(id); 
+        BigInteger nr = BigInteger.TEN;
+        EasyMock.expect(st.getMessageNumber()).andReturn(nr).times(2);
         DestinationSequence ds = control.createMock(DestinationSequence.class);
-        EasyMock.expect(destination.getSequence(id)).andReturn(ds);        
+        EasyMock.expect(destination.getSequence(id)).andReturn(ds);   
+        ds.applyDeliveryAssurance(nr);
+        EasyMock.expectLastCall();
         ds.acknowledge(message);
         EasyMock.expectLastCall();
         SequenceType.LastMessage lm = control.createMock(SequenceType.LastMessage.class);
         EasyMock.expect(st.getLastMessage()).andReturn(lm);
-        BigInteger nr = BigInteger.TEN;
-        EasyMock.expect(st.getMessageNumber()).andReturn(nr);
         ds.setLastMessageNumber(nr);
         EasyMock.expectLastCall();
         ds.scheduleImmediateAcknowledgement();

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMContextUtilsTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMContextUtilsTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMContextUtilsTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMContextUtilsTest.java Fri Apr 27 11:56:29 2007
@@ -71,16 +71,16 @@
     }
     
     @Test
-    public void testIsApplicationMessage() {
+    public void testIsRmPrtocolMessage() {
         control.replay();
         String action = null;
-        assertTrue(RMContextUtils.isAplicationMessage(action));
+        assertTrue(!RMContextUtils.isRMProtocolMessage(action));
         action = "";
-        assertTrue(RMContextUtils.isAplicationMessage(action));
+        assertTrue(!RMContextUtils.isRMProtocolMessage(action));
         action = "greetMe";
-        assertTrue(RMContextUtils.isAplicationMessage(action));
+        assertTrue(!RMContextUtils.isRMProtocolMessage(action));
         action = RMConstants.getCreateSequenceAction();
-        assertTrue(!RMContextUtils.isAplicationMessage(action));        
+        assertTrue(RMContextUtils.isRMProtocolMessage(action));        
     }
     
     @Test

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMInInterceptorTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMInInterceptorTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMInInterceptorTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMInInterceptorTest.java Fri Apr 27 11:56:29 2007
@@ -70,11 +70,12 @@
         Iterator it = chain.iterator();
         assertSame("Unexpected order.", rmi, it.next());
         assertSame("Unexpected order.", map, it.next());
+        
     } 
     
     
     @Test
-    public void testHandleCreateSequenceOnServer() throws SequenceFault {
+    public void testHandleCreateSequenceOnServer() throws SequenceFault, RMException {
         RMInInterceptor interceptor = new RMInInterceptor();         
         Message message = setupInboundMessage(RMConstants.getCreateSequenceAction(), true);   
         EasyMock.expect(message.get(AssertionInfoMap.class)).andReturn(null);
@@ -84,7 +85,7 @@
     }
     
     @Test
-    public void testHandleCreateSequenceOnClient() throws SequenceFault {
+    public void testHandleCreateSequenceOnClient() throws SequenceFault, RMException {
         RMInInterceptor interceptor = new RMInInterceptor();         
         Message message = setupInboundMessage(RMConstants.getCreateSequenceAction(), false);       
         RMManager manager = control.createMock(RMManager.class);
@@ -105,16 +106,17 @@
     }
     
     @Test
-    public void testHandleSequenceAckOnClient() throws SequenceFault, NoSuchMethodException {
+    public void testHandleSequenceAckOnClient() throws SequenceFault, RMException, NoSuchMethodException {
         testHandleSequenceAck(false);
     }
     
     @Test
-    public void testHandleSequenceAckOnServer() throws SequenceFault, NoSuchMethodException {
+    public void testHandleSequenceAckOnServer() throws SequenceFault, RMException, NoSuchMethodException {
         testHandleSequenceAck(true);
     }
     
-    private void testHandleSequenceAck(boolean onServer) throws SequenceFault, NoSuchMethodException {
+    private void testHandleSequenceAck(boolean onServer) throws SequenceFault, RMException, 
+    NoSuchMethodException {
         Method m = RMInInterceptor.class.getDeclaredMethod("processAcknowledgments",
             new Class[] {RMProperties.class});
         RMInInterceptor interceptor = control.createMock(RMInInterceptor.class, new Method[] {m});
@@ -128,16 +130,16 @@
     }
     
     @Test
-    public void testHandleTerminateSequenceOnServer() throws SequenceFault {
+    public void testHandleTerminateSequenceOnServer() throws SequenceFault, RMException {
         testHandleTerminateSequence(true);        
     }
     
     @Test
-    public void testHandleTerminateSequenceOnClient() throws SequenceFault {
+    public void testHandleTerminateSequenceOnClient() throws SequenceFault, RMException {
         testHandleTerminateSequence(false);        
     }
     
-    private void testHandleTerminateSequence(boolean onServer) throws SequenceFault {
+    private void testHandleTerminateSequence(boolean onServer) throws SequenceFault, RMException {
         RMInInterceptor interceptor = new RMInInterceptor();
         Message message = setupInboundMessage(RMConstants.getTerminateSequenceAction(), onServer);
         EasyMock.expectLastCall();
@@ -148,16 +150,16 @@
     }
     
     @Test
-    public void testAppRequest() throws SequenceFault, NoSuchMethodException {
+    public void testAppRequest() throws SequenceFault, RMException, NoSuchMethodException {
         testAppMessage(true);
     }
     
     @Test
-    public void testAppResponse() throws SequenceFault, NoSuchMethodException {
+    public void testAppResponse() throws SequenceFault, RMException, NoSuchMethodException {
         testAppMessage(false);
     }
     
-    private void testAppMessage(boolean onServer) throws SequenceFault, NoSuchMethodException {
+    private void testAppMessage(boolean onServer) throws SequenceFault, RMException, NoSuchMethodException {
         Method m1 = RMInInterceptor.class.getDeclaredMethod("processAcknowledgments",
                                                             new Class[] {RMProperties.class});
         Method m2 = RMInInterceptor.class.getDeclaredMethod("processAcknowledgmentRequests",
@@ -207,14 +209,13 @@
         Identifier id2 = control.createMock(Identifier.class);
         EasyMock.expect(ack2.getIdentifier()).andReturn(id2);
         EasyMock.expect(manager.getSourceSequence(id2)).andReturn(null);
-        EasyMock.expect(id2.getValue()).andReturn("s2");
-        
+  
         control.replay();
         try {
             interceptor.processAcknowledgments(rmps);
             fail("Expected SequenceFault not thrown");
         } catch (SequenceFault sf) {
-            assertEquals(RMConstants.getUnknownSequenceFaultCode(), sf.getFaultInfo().getFaultCode());
+            assertEquals(RMConstants.getUnknownSequenceFaultCode(), sf.getSequenceFault().getFaultCode());
         }
     }
     
@@ -225,7 +226,7 @@
     }
     
     @Test
-    public void testProcessSequence() throws SequenceFault {
+    public void testProcessSequence() throws SequenceFault, RMException {
         Destination destination = control.createMock(Destination.class);
         Message message = control.createMock(Message.class);
         destination.acknowledge(message);

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMManagerTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMManagerTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMManagerTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMManagerTest.java Fri Apr 27 11:56:29 2007
@@ -253,5 +253,21 @@
             // expected
         }
     }
+    
+    @Test
+    public void testDefaultSequenceIdentifierGenerator() {
+        RMManager manager = new RMManager();
+        assertNull(manager.getIdGenerator());
+        SequenceIdentifierGenerator generator = manager.new DefaultSequenceIdentifierGenerator();
+        manager.setIdGenerator(generator);
+        assertSame(generator, manager.getIdGenerator());
+        Identifier id1 = generator.generateSequenceIdentifier();
+        assertNotNull(id1);
+        assertNotNull(id1.getValue());
+        Identifier id2 = generator.generateSequenceIdentifier();
+        assertTrue(id1 != id2);
+        assertTrue(!id1.getValue().equals(id2.getValue()));     
+        control.replay();
+    }
      
 } 

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMOutInterceptorTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMOutInterceptorTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMOutInterceptorTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/RMOutInterceptorTest.java Fri Apr 27 11:56:29 2007
@@ -26,6 +26,7 @@
 
 import org.apache.cxf.interceptor.InterceptorChain;
 import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.FaultMode;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.Phase;
 import org.apache.cxf.phase.PhaseInterceptorChain;
@@ -63,21 +64,52 @@
         assertSame("Unexpected order.", rmi, it.next());                      
     } 
     
+    @Test 
+    public void testHandleRuntimeFault() throws NoSuchMethodException, SequenceFault {
+        Method[] mocked = new Method[] {                                                
+            RMOutInterceptor.class.getDeclaredMethod("isRuntimeFault", new Class[] {Message.class})
+        };
+        RMOutInterceptor interceptor = control.createMock(RMOutInterceptor.class, mocked);
+        Message message = control.createMock(Message.class);        
+        EasyMock.expect(interceptor.isRuntimeFault(message)).andReturn(true);
+        control.replay();
+        interceptor.handle(message);
+        control.verify();
+    }
+    
+    @Test 
+    public void testHandleNoMAPs() throws NoSuchMethodException, SequenceFault {
+        Method[] mocked = new Method[] {                                                
+            RMOutInterceptor.class.getDeclaredMethod("isRuntimeFault", new Class[] {Message.class})
+        };
+        RMOutInterceptor interceptor = control.createMock(RMOutInterceptor.class, mocked);
+        Message message = control.createMock(Message.class);        
+        EasyMock.expect(interceptor.isRuntimeFault(message)).andReturn(false);
+        EasyMock.expect(message.get(Message.REQUESTOR_ROLE)).andReturn(Boolean.FALSE).anyTimes();        
+        EasyMock.expect(message.get(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_OUTBOUND))
+            .andReturn(null);
+        control.replay();
+        interceptor.handle(message);
+        control.verify();
+    }
+    
     @Test
     public void testHandleApplicationMessage() throws NoSuchMethodException, SequenceFault {
         AddressingPropertiesImpl maps = createMAPs("greetMe", "localhost:9000/GreeterPort", 
             org.apache.cxf.ws.addressing.Names.WSA_NONE_ADDRESS);
         Method[] mocked = new Method[] {
             AbstractRMInterceptor.class.getDeclaredMethod("getManager", new Class[]{}),
+            RMOutInterceptor.class.getDeclaredMethod("isRuntimeFault", new Class[] {Message.class}),
             RMOutInterceptor.class.getDeclaredMethod("addAcknowledgements",
                 new Class[] {Destination.class, RMProperties.class, Identifier.class, 
                              AttributedURI.class})            
         };
-        RMOutInterceptor interceptor = control.createMock(RMOutInterceptor.class, mocked); 
+        RMOutInterceptor interceptor = control.createMock(RMOutInterceptor.class, mocked);         
         RMManager manager = control.createMock(RMManager.class);
         EasyMock.expect(interceptor.getManager()).andReturn(manager).times(5);
         
         Message message = control.createMock(Message.class);
+        EasyMock.expect(interceptor.isRuntimeFault(message)).andReturn(false);
         Exchange ex = control.createMock(Exchange.class);
         EasyMock.expect(message.getExchange()).andReturn(ex).times(3);
         EasyMock.expect(ex.getOutMessage()).andReturn(message).times(1);       
@@ -118,6 +150,25 @@
         assertSame(sid, rmpsOut.getSequence().getIdentifier());        
         assertEquals(BigInteger.TEN, rmpsOut.getSequence().getMessageNumber());
         assertNull(rmpsOut.getSequence().getLastMessage());
+        control.verify();
+    }
+    
+    @Test
+    public void testIsRuntimeFault() {
+        Message message = control.createMock(Message.class);
+        Exchange exchange = control.createMock(Exchange.class);
+        EasyMock.expect(message.getExchange()).andReturn(exchange).times(2);
+        EasyMock.expect(exchange.getOutFaultMessage()).andReturn(message);
+        EasyMock.expect(message.get(FaultMode.class)).andReturn(FaultMode.RUNTIME_FAULT);
+        control.replay();
+        RMOutInterceptor rmi = new RMOutInterceptor();
+        assertTrue(rmi.isRuntimeFault(message));
+        control.verify();
+        control.reset();
+        EasyMock.expect(message.getExchange()).andReturn(exchange).times(2);
+        EasyMock.expect(exchange.getOutFaultMessage()).andReturn(null);
+        control.replay();
+        assertTrue(!rmi.isRuntimeFault(message));
         control.verify();
     }
     

Modified: incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptorTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptorTest.java?view=diff&rev=533191&r1=533190&r2=533191
==============================================================================
--- incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptorTest.java (original)
+++ incubator/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptorTest.java Fri Apr 27 11:56:29 2007
@@ -34,17 +34,23 @@
 import org.w3c.dom.Element;
 import org.w3c.dom.NodeList;
 
+import org.apache.cxf.binding.soap.SoapFault;
 import org.apache.cxf.binding.soap.SoapMessage;
 import org.apache.cxf.binding.soap.interceptor.ReadHeadersInterceptor;
 import org.apache.cxf.message.Exchange;
+import org.apache.cxf.message.ExchangeImpl;
 import org.apache.cxf.message.Message;
 import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.message.MessageUtils;
 import org.apache.cxf.ws.rm.AckRequestedType;
 import org.apache.cxf.ws.rm.Identifier;
 import org.apache.cxf.ws.rm.RMConstants;
 import org.apache.cxf.ws.rm.RMContextUtils;
 import org.apache.cxf.ws.rm.RMProperties;
+import org.apache.cxf.ws.rm.RMUtils;
 import org.apache.cxf.ws.rm.SequenceAcknowledgement;
+import org.apache.cxf.ws.rm.SequenceFault;
+import org.apache.cxf.ws.rm.SequenceFaultType;
 import org.apache.cxf.ws.rm.SequenceType;
 import org.easymock.classextension.EasyMock;
 import org.easymock.classextension.IMocksControl;
@@ -53,6 +59,7 @@
 import org.junit.Test;
 
 
+
 public class RMSoapInterceptorTest extends Assert {
 
     private static final String SEQ_IDENTIFIER = "http://Business456.com/RM/ABC";
@@ -188,6 +195,51 @@
         verifyHeaders(message, new String[] {RMConstants.getAckRequestedName(), 
                                              RMConstants.getAckRequestedName()});
     }
+    
+    @Test
+    public void testEncodeFault() throws Exception {
+        RMSoapInterceptor codec = new RMSoapInterceptor();
+        setUpOutbound();
+        SoapMessage message = setupOutboundFaultMessage();
+
+        // no RM headers and no fault
+   
+        codec.encode(message);
+        verifyHeaders(message, new String[] {});
+
+        // fault is not a SoapFault
+
+        message = setupOutboundFaultMessage();
+        assertTrue(MessageUtils.isFault(message));
+        Exception ex = new RuntimeException("");
+        message.setContent(Exception.class, ex);      
+        codec.encode(message);
+        verifyHeaders(message, new String[] {});
+        
+        // fault is a SoapFault but does not have a SequenceFault cause
+
+        message = setupOutboundFaultMessage();
+        SoapFault f = new SoapFault("REASON", RMConstants.getUnknownSequenceFaultCode());
+        message.setContent(Exception.class, f);      
+        codec.encode(message);
+        verifyHeaders(message, new String[] {});
+
+        // fault is a SoapFault and has a SequenceFault cause
+        
+        message = setupOutboundFaultMessage();
+        SequenceFaultType sft = RMUtils.getWSRMFactory().createSequenceFaultType();
+        sft.setFaultCode(RMConstants.getUnknownSequenceFaultCode());
+        SequenceFault sf = new SequenceFault("REASON");
+        sf.setSequenceFault(sft);
+        Identifier sid = RMUtils.getWSRMFactory().createIdentifier();
+        sid.setValue("SID");
+        sf.setSender(true);
+        f.initCause(sf);
+        message.setContent(Exception.class, f);      
+        codec.encode(message);
+        verifyHeaders(message, new String[] {RMConstants.getSequenceFaultName()});
+
+    }
 
     @Test
     public void testDecodeSequence() throws XMLStreamException {
@@ -284,6 +336,15 @@
         RMProperties rmps = new RMProperties();
         RMContextUtils.storeRMProperties(soapMessage, rmps, true);
         
+        return soapMessage;
+    }
+    
+    private SoapMessage setupOutboundFaultMessage() throws Exception {
+        Exchange ex = new ExchangeImpl();        
+        Message message = new MessageImpl();
+        SoapMessage soapMessage = new SoapMessage(message);         
+        ex.setOutFaultMessage(soapMessage);
+        soapMessage.setExchange(ex);        
         return soapMessage;
     }