You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by ds...@apache.org on 2014/02/10 11:08:35 UTC
svn commit: r1566555 [2/2] - in /cxf/trunk:
core/src/main/java/org/apache/cxf/interceptor/
core/src/main/java/org/apache/cxf/io/
rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/
rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/feature/
rt/ws/rm/src/main/java/or...
Copied: cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInInterceptor.java (from r1566482, cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java)
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInInterceptor.java?p2=cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInInterceptor.java&p1=cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java&r1=1566482&r2=1566555&rev=1566555&view=diff
==============================================================================
--- cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInterceptor.java (original)
+++ cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapInInterceptor.java Mon Feb 10 10:08:34 2014
@@ -19,7 +19,6 @@
package org.apache.cxf.ws.rm.soap;
-import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
@@ -34,14 +33,11 @@ import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.namespace.QName;
-import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.apache.cxf.binding.Binding;
-import org.apache.cxf.binding.soap.Soap11;
import org.apache.cxf.binding.soap.SoapFault;
-import org.apache.cxf.binding.soap.SoapHeader;
import org.apache.cxf.binding.soap.SoapMessage;
import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor;
import org.apache.cxf.common.logging.LogUtils;
@@ -52,7 +48,6 @@ import org.apache.cxf.interceptor.Interc
import org.apache.cxf.interceptor.InterceptorChain;
import org.apache.cxf.message.Exchange;
import org.apache.cxf.message.Message;
-import org.apache.cxf.message.MessageUtils;
import org.apache.cxf.phase.Phase;
import org.apache.cxf.phase.PhaseInterceptor;
import org.apache.cxf.service.Service;
@@ -76,7 +71,6 @@ import org.apache.cxf.ws.rm.RMException;
import org.apache.cxf.ws.rm.RMManager;
import org.apache.cxf.ws.rm.RMMessageConstants;
import org.apache.cxf.ws.rm.RMProperties;
-import org.apache.cxf.ws.rm.SequenceFault;
import org.apache.cxf.ws.rm.v200702.AckRequestedType;
import org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement;
import org.apache.cxf.wsdl.interceptors.BareInInterceptor;
@@ -85,7 +79,7 @@ import org.apache.cxf.wsdl.interceptors.
* Protocol Handler responsible for {en|de}coding the RM
* Properties for {outgo|incom}ing messages.
*/
-public class RMSoapInterceptor extends AbstractSoapInterceptor {
+public class RMSoapInInterceptor extends AbstractSoapInterceptor {
protected static JAXBContext jaxbContext;
@@ -97,12 +91,12 @@ public class RMSoapInterceptor extends A
HEADERS = set;
}
- private static final Logger LOG = LogUtils.getL7dLogger(RMSoapInterceptor.class);
+ private static final Logger LOG = LogUtils.getL7dLogger(RMSoapInInterceptor.class);
/**
* Constructor.
*/
- public RMSoapInterceptor() {
+ public RMSoapInInterceptor() {
super(Phase.PRE_PROTOCOL);
addAfter(MAPCodec.class.getName());
@@ -123,113 +117,8 @@ public class RMSoapInterceptor extends A
* @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message)
*/
public void handleMessage(SoapMessage message) throws Fault {
- mediate(message);
- }
-
- /**
- * Mediate message flow, peforming RMProperties {en|de}coding.
- *
- * @param message the messsage
- */
- void mediate(SoapMessage message) {
- if (MessageUtils.isOutbound(message)) {
- encode(message);
- } else {
- decode(message);
- updateServiceModelInfo(message);
- }
- }
-
- /**
- * Encode the current RM properties in protocol-specific headers.
- *
- * @param message the SOAP message
- */
- void encode(SoapMessage message) {
- RMProperties rmps = RMContextUtils.retrieveRMProperties(message, true);
- 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 the current RM properties in protocol-specific headers.
- *
- * @param message the SOAP message.
- * @param rmps the current RM properties.
- */
- public static void encode(SoapMessage message, RMProperties rmps) {
- if (null == rmps) {
- return;
- }
- LOG.log(Level.FINE, "encoding RMPs in SOAP headers");
-
- try {
-
- List<Header> headers = message.getHeaders();
- discardRMHeaders(headers);
-
- AddressingProperties maps = RMContextUtils.retrieveMAPs(message, false, true);
- ProtocolVariation protocol = ProtocolVariation.findVariant(rmps.getNamespaceURI(),
- maps.getNamespaceURI());
- Element header = protocol.getCodec().buildHeaders(rmps, Soap11.getInstance().getHeader());
- Node node = header.getFirstChild();
- if (node != null && MessageUtils.isPartialResponse(message)) {
- // make sure the response is returned as HTTP 200 and not 202
- message.put(Message.RESPONSE_CODE, HttpURLConnection.HTTP_OK);
- }
- while (node != null) {
- Header holder = null;
- if (node.getLocalName().equals("Sequence")) {
- holder = new SoapHeader(new QName(node.getNamespaceURI(), node.getLocalName()), node);
- ((SoapHeader)holder).setMustUnderstand(true);
- } else {
- holder = new Header(new QName(node.getNamespaceURI(), node.getLocalName()), node);
- }
- headers.add(holder);
- node = node.getNextSibling();
- }
-
- } catch (JAXBException je) {
- LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je);
- }
- }
-
- /**
- * Encode the SequenceFault in protocol-specific header.
- *
- * @param message the SOAP message.
- * @param sf the SequenceFault.
- */
- public static void encodeFault(SoapMessage message, SequenceFault sf) {
- LOG.log(Level.FINE, "Encoding SequenceFault in SOAP header");
- try {
- List<Header> headers = message.getHeaders();
- discardRMHeaders(headers);
- Message inmsg = message.getExchange().getInMessage();
- RMProperties rmps = RMContextUtils.retrieveRMProperties(inmsg, false);
- AddressingProperties maps = RMContextUtils.retrieveMAPs(inmsg, false, false);
- ProtocolVariation protocol = ProtocolVariation.findVariant(rmps.getNamespaceURI(),
- maps.getNamespaceURI());
- Element header = protocol.getCodec().buildHeaderFault(sf, Soap11.getInstance().getHeader());
- Node node = header.getFirstChild();
- if (node instanceof Element) {
- Attr attr = header.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/",
- "xmlns:" + RMConstants.NAMESPACE_PREFIX);
- attr.setValue(rmps.getNamespaceURI());
- ((Element)node).setAttributeNodeNS(attr);
- }
-
- headers.add(new Header(new QName(node.getNamespaceURI(), node.getLocalName()), node));
- } catch (JAXBException je) {
- LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je);
- }
+ decode(message);
+ updateServiceModelInfo(message);
}
/**
@@ -321,24 +210,6 @@ public class RMSoapInterceptor extends A
LOG.log(Level.WARNING, "SOAP_HEADER_DECODE_FAILURE_MSG", ex);
}
}
-
- /**
- * Discard any pre-existing RM headers - this may occur if the runtime
- * re-uses a SOAP message.
- *
- * @param header the SOAP header element
- */
- private static void discardRMHeaders(List<Header> header) {
- Iterator<Header> iter = header.iterator();
- while (iter.hasNext()) {
- Header hdr = iter.next();
- String uri = hdr.getName().getNamespaceURI();
- if (RM10Constants.NAMESPACE_URI.equals(uri)
- || RM11Constants.NAMESPACE_URI.equals(uri)) {
- iter.remove();
- }
- }
- }
/**
* When invoked inbound, check if the action indicates that this is one of the
@@ -434,7 +305,7 @@ public class RMSoapInterceptor extends A
// In the logical RM interceptor set it back to what it was so that the logical
// addressing interceptor does not try to send a partial response to
// server originated oneway RM protocol messages.
- // The actions that can appear in the response to the requestor should be excluded.
+ //
if (!consts.getCreateSequenceResponseAction().equals(action)
&& !consts.getSequenceAckAction().equals(action)
Added: cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptor.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptor.java?rev=1566555&view=auto
==============================================================================
--- cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptor.java (added)
+++ cxf/trunk/rt/ws/rm/src/main/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptor.java Mon Feb 10 10:08:34 2014
@@ -0,0 +1,195 @@
+/**
+ * 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.net.HttpURLConnection;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.xml.bind.JAXBContext;
+import javax.xml.bind.JAXBException;
+import javax.xml.namespace.QName;
+import javax.xml.soap.SOAPException;
+import javax.xml.soap.SOAPMessage;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+import org.apache.cxf.binding.soap.Soap11;
+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;
+import org.apache.cxf.headers.Header;
+import org.apache.cxf.interceptor.Fault;
+import org.apache.cxf.message.Message;
+import org.apache.cxf.message.MessageUtils;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.rm.ProtocolVariation;
+import org.apache.cxf.ws.rm.RM10Constants;
+import org.apache.cxf.ws.rm.RM11Constants;
+import org.apache.cxf.ws.rm.RMConstants;
+import org.apache.cxf.ws.rm.RMContextUtils;
+import org.apache.cxf.ws.rm.RMOutInterceptor;
+import org.apache.cxf.ws.rm.RMProperties;
+import org.apache.cxf.ws.rm.SequenceFault;
+
+/**
+ * Protocol Handler responsible for {en|de}coding the RM
+ * Properties for {outgo|incom}ing messages.
+ */
+public class RMSoapOutInterceptor extends AbstractSoapInterceptor {
+
+ protected static JAXBContext jaxbContext;
+
+ private static final Set<QName> HEADERS;
+ static {
+ Set<QName> set = new HashSet<QName>();
+ set.addAll(RM10Constants.HEADERS);
+ set.addAll(RM11Constants.HEADERS);
+ HEADERS = set;
+ }
+
+ private static final Logger LOG = LogUtils.getL7dLogger(RMSoapOutInterceptor.class);
+
+ /**
+ * Constructor.
+ */
+ public RMSoapOutInterceptor() {
+ super(Phase.POST_PROTOCOL);
+
+ addAfter(RMOutInterceptor.class.getName());
+ }
+
+ // AbstractSoapInterceptor interface
+
+ /**
+ * @return the set of SOAP headers understood by this handler
+ */
+ public Set<QName> getUnderstoodHeaders() {
+ return HEADERS;
+ }
+
+ // Interceptor interface
+
+ /* (non-Javadoc)
+ * @see org.apache.cxf.interceptor.Interceptor#handleMessage(org.apache.cxf.message.Message)
+ */
+ public void handleMessage(SoapMessage message) throws Fault {
+ encode(message);
+ }
+
+ /**
+ * Encode the current RM properties in protocol-specific headers.
+ *
+ * @param message the SOAP message
+ */
+ void encode(SoapMessage message) {
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(message, true);
+ 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 the current RM properties in protocol-specific headers.
+ *
+ * @param message the SOAP message.
+ * @param rmps the current RM properties.
+ */
+ public static void encode(SoapMessage message, RMProperties rmps) {
+ if (null == rmps) {
+ return;
+ }
+ LOG.log(Level.FINE, "encoding RMPs in SOAP headers");
+ try {
+
+ AddressingProperties maps = RMContextUtils.retrieveMAPs(message, false, true);
+ ProtocolVariation protocol = ProtocolVariation.findVariant(rmps.getNamespaceURI(),
+ maps.getNamespaceURI());
+ SOAPMessage content = message.getContent(SOAPMessage.class);
+ boolean added = protocol.getCodec().insertHeaders(rmps, content.getSOAPPart());
+ if (added && MessageUtils.isPartialResponse(message)) {
+ // make sure the response is returned as HTTP 200 and not 202
+ message.put(Message.RESPONSE_CODE, HttpURLConnection.HTTP_OK);
+ }
+ if (added) {
+ try {
+ content.saveChanges();
+// ByteArrayOutputStream bos = new ByteArrayOutputStream();
+// content.writeTo(bos);
+// bos.close();
+// LOG.info("Message after headers added: " + bos.toString("UTF-8"));
+ } catch (SOAPException e) {
+ // TODO Auto-generated catch block
+ e.printStackTrace();
+// } catch (IOException e) {
+// // TODO Auto-generated catch block
+// e.printStackTrace();
+ }
+
+ }
+
+ } catch (JAXBException je) {
+ LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je);
+ }
+ }
+
+ /**
+ * Encode the SequenceFault in protocol-specific header.
+ *
+ * @param message the SOAP message.
+ * @param sf the SequenceFault.
+ */
+ public static void encodeFault(SoapMessage message, SequenceFault sf) {
+ LOG.log(Level.FINE, "Encoding SequenceFault in SOAP header");
+ try {
+ List<Header> headers = message.getHeaders();
+ Message inmsg = message.getExchange().getInMessage();
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(inmsg, false);
+ AddressingProperties maps = RMContextUtils.retrieveMAPs(inmsg, false, false);
+ ProtocolVariation protocol = ProtocolVariation.findVariant(rmps.getNamespaceURI(),
+ maps.getNamespaceURI());
+ Element header = protocol.getCodec().buildHeaderFault(sf, Soap11.getInstance().getHeader());
+ Node node = header.getFirstChild();
+ if (node instanceof Element) {
+ Attr attr = header.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/",
+ "xmlns:" + RMConstants.NAMESPACE_PREFIX);
+ attr.setValue(rmps.getNamespaceURI());
+ ((Element)node).setAttributeNodeNS(attr);
+ }
+
+ headers.add(new Header(new QName(node.getNamespaceURI(), node.getLocalName()), node));
+ } catch (JAXBException je) {
+ LOG.log(Level.WARNING, "SOAP_HEADER_ENCODE_FAILURE_MSG", je);
+ }
+ }
+}
\ No newline at end of file
Added: cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptorTest.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptorTest.java?rev=1566555&view=auto
==============================================================================
--- cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptorTest.java (added)
+++ cxf/trunk/rt/ws/rm/src/test/java/org/apache/cxf/ws/rm/soap/RMSoapOutInterceptorTest.java Mon Feb 10 10:08:34 2014
@@ -0,0 +1,475 @@
+/**
+ * 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.io.InputStream;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.w3c.dom.Element;
+
+import org.apache.cxf.BusFactory;
+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.binding.soap.interceptor.StartBodyInterceptor;
+import org.apache.cxf.headers.Header;
+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.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.Names;
+import org.apache.cxf.ws.rm.RM10Constants;
+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.SequenceFault;
+import org.apache.cxf.ws.rm.v200702.AckRequestedType;
+import org.apache.cxf.ws.rm.v200702.Identifier;
+import org.apache.cxf.ws.rm.v200702.ObjectFactory;
+import org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement;
+import org.apache.cxf.ws.rm.v200702.SequenceAcknowledgement.AcknowledgementRange;
+import org.apache.cxf.ws.rm.v200702.SequenceType;
+import org.easymock.EasyMock;
+import org.easymock.IMocksControl;
+
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+public class RMSoapOutInterceptorTest extends Assert {
+
+ private static final String SEQ_IDENTIFIER = "http://Business456.com/RM/ABC";
+ private static final Long ONE = new Long(1);
+ private static final Long TEN = new Long(10);
+ private static final Long MSG1_MESSAGE_NUMBER = ONE;
+ private static final Long MSG2_MESSAGE_NUMBER = new Long(2);
+
+ private IMocksControl control;
+
+ private SequenceType s1;
+ private SequenceType s2;
+ private SequenceAcknowledgement ack1;
+ private SequenceAcknowledgement ack2;
+ private AckRequestedType ar1;
+ private AckRequestedType ar2;
+
+ @Before
+ public void setUp() {
+ control = EasyMock.createNiceControl();
+ }
+
+ @Test
+ public void testGetUnderstoodHeaders() throws Exception {
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ Set<QName> headers = codec.getUnderstoodHeaders();
+ assertTrue("expected Sequence header", headers.contains(RM10Constants.SEQUENCE_QNAME));
+ assertTrue("expected SequenceAcknowledgment header",
+ headers.contains(RM10Constants.SEQUENCE_ACK_QNAME));
+ assertTrue("expected AckRequested header",
+ headers.contains(RM10Constants.ACK_REQUESTED_QNAME));
+ }
+
+ @Test
+ public void testHandleMessage() throws NoSuchMethodException {
+ Method m = RMSoapOutInterceptor.class.getDeclaredMethod("mediate",
+ new Class[] {SoapMessage.class});
+ RMSoapOutInterceptor codec =
+ EasyMock.createMockBuilder(RMSoapOutInterceptor.class)
+ .addMockedMethod(m).createMock(control);
+ SoapMessage msg = control.createMock(SoapMessage.class);
+ codec.mediate(msg);
+ EasyMock.expectLastCall();
+
+ control.replay();
+ codec.handleMessage(msg);
+ control.verify();
+ }
+
+ @Test
+ public void testMediate() throws NoSuchMethodException, XMLStreamException {
+ Method m1 = RMSoapOutInterceptor.class.getDeclaredMethod("encode",
+ new Class[] {SoapMessage.class});
+ Method m2 = RMSoapOutInterceptor.class.getDeclaredMethod("decode",
+ new Class[] {SoapMessage.class});
+ RMSoapOutInterceptor codec =
+ EasyMock.createMockBuilder(RMSoapOutInterceptor.class)
+ .addMockedMethods(m1, m2).createMock(control);
+
+ SoapMessage msg = control.createMock(SoapMessage.class);
+ Exchange exchange = control.createMock(Exchange.class);
+ EasyMock.expect(msg.getExchange()).andReturn(exchange);
+ EasyMock.expect(exchange.getOutMessage()).andReturn(msg);
+ codec.encode(msg);
+ EasyMock.expectLastCall();
+
+ control.replay();
+ codec.mediate(msg);
+ control.verify();
+
+ control.reset();
+ EasyMock.expect(msg.getExchange()).andReturn(null);
+ codec.decode(msg);
+ EasyMock.expectLastCall();
+
+ control.replay();
+ codec.mediate(msg);
+ control.verify();
+
+ }
+
+ @Test
+ public void testEncode() throws Exception {
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ setUpOutbound();
+ SoapMessage message = setupOutboundMessage();
+
+ // no RM headers
+
+ codec.handleMessage(message);
+ verifyHeaders(message, new String[] {});
+
+ // one sequence header
+
+ message = setupOutboundMessage();
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(message, true);
+ rmps.setSequence(s1);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {RMConstants.SEQUENCE_NAME});
+
+ // one acknowledgment header
+
+ message = setupOutboundMessage();
+ rmps = RMContextUtils.retrieveRMProperties(message, true);
+ Collection<SequenceAcknowledgement> acks = new ArrayList<SequenceAcknowledgement>();
+ acks.add(ack1);
+ rmps.setAcks(acks);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {RMConstants.SEQUENCE_ACK_NAME});
+
+ // two acknowledgment headers
+
+ message = setupOutboundMessage();
+ rmps = RMContextUtils.retrieveRMProperties(message, true);
+ acks.add(ack2);
+ rmps.setAcks(acks);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {RMConstants.SEQUENCE_ACK_NAME,
+ RMConstants.SEQUENCE_ACK_NAME});
+
+ // one ack requested header
+
+ message = setupOutboundMessage();
+ rmps = RMContextUtils.retrieveRMProperties(message, true);
+ Collection<AckRequestedType> requested = new ArrayList<AckRequestedType>();
+ requested.add(ar1);
+ rmps.setAcksRequested(requested);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {RMConstants.ACK_REQUESTED_NAME});
+
+ // two ack requested headers
+
+ message = setupOutboundMessage();
+ rmps = RMContextUtils.retrieveRMProperties(message, true);
+ requested.add(ar2);
+ rmps.setAcksRequested(requested);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {RMConstants.ACK_REQUESTED_NAME,
+ RMConstants.ACK_REQUESTED_NAME});
+ }
+
+ @Test
+ public void testEncodeFault() throws Exception {
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ 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", RM10Constants.UNKNOWN_SEQUENCE_FAULT_QNAME);
+ message.setContent(Exception.class, f);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {});
+
+ // fault is a SoapFault and has a SequenceFault cause
+
+ message = setupOutboundFaultMessage();
+ SequenceFault sf = new SequenceFault("REASON");
+ sf.setFaultCode(RM10Constants.UNKNOWN_SEQUENCE_FAULT_QNAME);
+ Identifier sid = new Identifier();
+ sid.setValue("SID");
+ sf.setSender(true);
+ f.initCause(sf);
+ message.setContent(Exception.class, f);
+ codec.encode(message);
+ verifyHeaders(message, new String[] {RMConstants.SEQUENCE_FAULT_NAME});
+
+ }
+
+ @Test
+ public void testDecodeSequence() throws XMLStreamException {
+ SoapMessage message = setUpInboundMessage("resources/Message1.xml");
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ codec.handleMessage(message);
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(message, false);
+ SequenceType st = rmps.getSequence();
+ assertNotNull(st);
+ assertEquals(st.getIdentifier().getValue(), SEQ_IDENTIFIER);
+ assertEquals(st.getMessageNumber(), MSG1_MESSAGE_NUMBER);
+
+ assertNull(rmps.getAcks());
+ assertNull(rmps.getAcksRequested());
+
+ }
+
+ @Test
+ public void testDecodeAcknowledgements() throws XMLStreamException {
+ SoapMessage message = setUpInboundMessage("resources/Acknowledgment.xml");
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ codec.handleMessage(message);
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(message, false);
+ Collection<SequenceAcknowledgement> acks = rmps.getAcks();
+ assertNotNull(acks);
+ assertEquals(1, acks.size());
+ SequenceAcknowledgement ack = acks.iterator().next();
+ assertNotNull(ack);
+ assertEquals(ack.getIdentifier().getValue(), SEQ_IDENTIFIER);
+ assertEquals(2, ack.getAcknowledgementRange().size());
+ AcknowledgementRange r1 = ack.getAcknowledgementRange().get(0);
+ AcknowledgementRange r2 = ack.getAcknowledgementRange().get(1);
+ verifyRange(r1, 1, 1);
+ verifyRange(r2, 3, 3);
+ assertNull(rmps.getSequence());
+ assertNull(rmps.getAcksRequested());
+ }
+
+ @Test
+ public void testDecodeAcknowledgements2() throws XMLStreamException {
+ SoapMessage message = setUpInboundMessage("resources/Acknowledgment2.xml");
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ codec.handleMessage(message);
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(message, false);
+ Collection<SequenceAcknowledgement> acks = rmps.getAcks();
+ assertNotNull(acks);
+ assertEquals(1, acks.size());
+ SequenceAcknowledgement ack = acks.iterator().next();
+ assertNotNull(ack);
+ assertEquals(1, ack.getAcknowledgementRange().size());
+ AcknowledgementRange r1 = ack.getAcknowledgementRange().get(0);
+ verifyRange(r1, 1, 3);
+ assertNull(rmps.getSequence());
+ assertNull(rmps.getAcksRequested());
+ }
+
+ private void verifyRange(AcknowledgementRange r, int i, int j) {
+ assertNotNull(r);
+ if (i > 0) {
+ assertNotNull(r.getLower());
+ assertEquals(i, r.getLower().longValue());
+ }
+ if (j > 0) {
+ assertNotNull(r.getUpper());
+ assertEquals(j, r.getUpper().longValue());
+ }
+ }
+
+ @Test
+ public void testDecodeAcksRequested() throws XMLStreamException {
+ SoapMessage message = setUpInboundMessage("resources/Retransmission.xml");
+ RMSoapOutInterceptor codec = new RMSoapOutInterceptor();
+ codec.handleMessage(message);
+ RMProperties rmps = RMContextUtils.retrieveRMProperties(message, false);
+ Collection<AckRequestedType> requested = rmps.getAcksRequested();
+ assertNotNull(requested);
+ assertEquals(1, requested.size());
+ AckRequestedType ar = requested.iterator().next();
+ assertNotNull(ar);
+ assertEquals(ar.getIdentifier().getValue(), SEQ_IDENTIFIER);
+
+ SequenceType s = rmps.getSequence();
+ assertNotNull(s);
+ assertEquals(s.getIdentifier().getValue(), SEQ_IDENTIFIER);
+ assertEquals(s.getMessageNumber(), MSG2_MESSAGE_NUMBER);
+
+ assertNull(rmps.getAcks());
+ }
+
+ private void setUpOutbound() {
+ ObjectFactory factory = new ObjectFactory();
+ s1 = factory.createSequenceType();
+ Identifier sid = factory.createIdentifier();
+ sid.setValue("sequence1");
+ s1.setIdentifier(sid);
+ s1.setMessageNumber(ONE);
+ s2 = factory.createSequenceType();
+ sid = factory.createIdentifier();
+ sid.setValue("sequence2");
+ s2.setIdentifier(sid);
+ s2.setMessageNumber(TEN);
+
+ ack1 = factory.createSequenceAcknowledgement();
+ SequenceAcknowledgement.AcknowledgementRange r =
+ factory.createSequenceAcknowledgementAcknowledgementRange();
+ r.setLower(ONE);
+ r.setUpper(ONE);
+ ack1.getAcknowledgementRange().add(r);
+ ack1.setIdentifier(s1.getIdentifier());
+
+ ack2 = factory.createSequenceAcknowledgement();
+ r = factory.createSequenceAcknowledgementAcknowledgementRange();
+ r.setLower(ONE);
+ r.setUpper(TEN);
+ ack2.getAcknowledgementRange().add(r);
+ ack2.setIdentifier(s2.getIdentifier());
+
+ ar1 = factory.createAckRequestedType();
+ ar1.setIdentifier(s1.getIdentifier());
+
+ ar2 = factory.createAckRequestedType();
+ ar2.setIdentifier(s2.getIdentifier());
+ }
+
+ private SoapMessage setupOutboundMessage() throws Exception {
+ Exchange ex = new ExchangeImpl();
+ Message message = new MessageImpl();
+ SoapMessage soapMessage = new SoapMessage(message);
+ RMProperties rmps = new RMProperties();
+ rmps.exposeAs(RM10Constants.NAMESPACE_URI);
+ RMContextUtils.storeRMProperties(soapMessage, rmps, true);
+ AddressingProperties maps = new AddressingProperties();
+ RMContextUtils.storeMAPs(maps, soapMessage, true, false);
+ ex.setOutMessage(soapMessage);
+ soapMessage.setExchange(ex);
+ return soapMessage;
+ }
+
+ private SoapMessage setupOutboundFaultMessage() throws Exception {
+ Exchange ex = new ExchangeImpl();
+ Message message = new MessageImpl();
+ RMProperties rmps = new RMProperties();
+ rmps.exposeAs(RM10Constants.NAMESPACE_URI);
+ RMContextUtils.storeRMProperties(message, rmps, false);
+ AddressingProperties maps = new AddressingProperties();
+ RMContextUtils.storeMAPs(maps, message, false, false);
+ ex.setInMessage(message);
+ message = new MessageImpl();
+ SoapMessage soapMessage = new SoapMessage(message);
+ ex.setOutFaultMessage(soapMessage);
+ soapMessage.setExchange(ex);
+ return soapMessage;
+ }
+
+ private void verifyHeaders(SoapMessage message, String... names) {
+ List<Header> header = message.getHeaders();
+
+ // check all expected headers are present
+
+ for (String name : names) {
+ boolean found = false;
+ Iterator<Header> iter = header.iterator();
+ while (iter.hasNext()) {
+ Object obj = iter.next().getObject();
+ if (obj instanceof Element) {
+ Element elem = (Element) obj;
+ String namespace = elem.getNamespaceURI();
+ String localName = elem.getLocalName();
+ if (RM10Constants.NAMESPACE_URI.equals(namespace)
+ && localName.equals(name)) {
+ found = true;
+ break;
+ } else if (Names.WSA_NAMESPACE_NAME.equals(namespace)
+ && localName.equals(name)) {
+ found = true;
+ break;
+ }
+ }
+ }
+ assertTrue("Could not find header element " + name, found);
+ }
+
+ // no other headers should be present
+
+ Iterator<Header> iter1 = header.iterator();
+ while (iter1.hasNext()) {
+ Object obj = iter1.next().getObject();
+ if (obj instanceof Element) {
+ Element elem = (Element) obj;
+ String namespace = elem.getNamespaceURI();
+ String localName = elem.getLocalName();
+ assertTrue(RM10Constants.NAMESPACE_URI.equals(namespace)
+ || Names.WSA_NAMESPACE_NAME.equals(namespace));
+ boolean found = false;
+ for (String name : names) {
+ if (localName.equals(name)) {
+ found = true;
+ break;
+ }
+ }
+ assertTrue("Unexpected header element " + localName, found);
+ }
+ }
+ }
+
+ private SoapMessage setUpInboundMessage(String resource) throws XMLStreamException {
+ Message message = new MessageImpl();
+ SoapMessage soapMessage = new SoapMessage(message);
+ RMProperties rmps = new RMProperties();
+ rmps.exposeAs(RM10Constants.NAMESPACE_URI);
+ RMContextUtils.storeRMProperties(soapMessage, rmps, false);
+ AddressingProperties maps = new AddressingProperties();
+ RMContextUtils.storeMAPs(maps, soapMessage, false, false);
+ message.put(MessaRMSoapOutInterceptorTestENABLED, false);
+ InputStream is = RMSoapInterceptorTest.class.getResourceAsStream(resource);
+ assertNotNull(is);
+ XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(is);
+ soapMessage.setContent(XMLStreamReader.class, reader);
+ ReadHeadersInterceptor rji = new ReadHeadersInterceptor(BusFactory.getDefaultBus());
+ rji.handleMessage(soapMessage);
+ StartBodyInterceptor sbi = new StartBodyInterceptor();
+ sbi.handleMessage(soapMessage);
+ return soapMessage;
+ }
+}