Skip to content
Permalink
Browse files
CXF-4866, CXF-352: Restructure WS-RM to capture message in PRE_STREAM
phase, begin retransmission from same point so that WS-Security and
other add-ons will function correctly.

git-svn-id: https://svn.apache.org/repos/asf/cxf/trunk@1566560 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
Dennis M. Sosnoski committed Feb 10, 2014
1 parent 5d6e1bc commit 9879f3e1255d6a19dca7e9a167f647f8fa30f935
Show file tree
Hide file tree
Showing 23 changed files with 485 additions and 223 deletions.
@@ -19,7 +19,6 @@

package org.apache.cxf.ws.rm;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
@@ -167,7 +166,9 @@ public void acknowledge(Message message) throws SequenceFault {
RMMessage msg = null;
if (!MessageUtils.isTrue(message.getContextualProperty(Message.ROBUST_ONEWAY))) {
msg = new RMMessage();
msg.setContent((InputStream)message.get(RMMessageConstants.SAVED_CONTENT));
RewindableInputStream in = (RewindableInputStream)message.get(RMMessageConstants.SAVED_CONTENT);
in.rewind();
msg.setContent(in);
msg.setMessageNumber(st.getMessageNumber());
}
store.persistIncoming(this, msg);
@@ -180,7 +181,6 @@ public void acknowledge(Message message) throws SequenceFault {

long inactivityTimeout = cfg.getInactivityTimeoutTime();
scheduleSequenceTermination(inactivityTimeout);

}

void mergeRanges() {
@@ -24,12 +24,13 @@
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.apache.cxf.helpers.DOMUtils;
import org.apache.cxf.ws.rm.v200702.AckRequestedType;
import org.apache.cxf.ws.rm.v200702.CloseSequenceType;
import org.apache.cxf.ws.rm.v200702.CreateSequenceResponseType;
@@ -53,13 +54,6 @@ public abstract class EncoderDecoder {
*/
protected abstract JAXBContext getContext() throws JAXBException;

/**
* Add WS-RM namespace declaration to element.
*
* @param element
*/
protected abstract void addNamespaceDecl(Element element);

/**
* Get the WS-ReliableMessaging namespace used by this encoder/decoder.
*
@@ -110,71 +104,67 @@ public abstract class EncoderDecoder {
public abstract Class<?> getTerminateSequenceResponseType();

/**
* Insert WS-RM headers into a SOAP message. This adds the appropriate WS-RM namespace declaration to the
* SOAP:Header element (which must be present), and then adds any WS-RM headers set in the supplied properties as
* child elements.
* Builds an element containing WS-RM headers. This adds the appropriate WS-RM namespace declaration to the element,
* and then adds any WS-RM headers set in the supplied properties as child elements.
*
* @param rmps
* @param doc
* @return <code>true</code> if headers added, <code>false</code> if not
* @param qname constructed element name
* @return element (<code>null</code> if none)
*/
public boolean insertHeaders(RMProperties rmps, Document doc) throws JAXBException {
public Element buildHeaders(RMProperties rmps, QName qname) throws JAXBException {

// check if there's anything to insert
SequenceType seq = rmps.getSequence();
Collection<SequenceAcknowledgement> acks = rmps.getAcks();
Collection<AckRequestedType> reqs = rmps.getAcksRequested();
if (seq == null && acks == null && reqs == null) {
return false;
return null;
}

// add WSRM namespace declaration to header, instead of repeating in each individual child node
Element header = getSoapHeader(doc);
// create element with namespace declaration included
Document doc = DOMUtils.createDocument();
Element header = doc.createElementNS(qname.getNamespaceURI(), qname.getLocalPart());
addNamespaceDecl(header);

// build individual headers
Marshaller marshaller = getContext().createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
buildHeaders(seq, acks, reqs, rmps.isLastMessage(), header, marshaller);
return true;
return header;
}

/**
* Get the SOAP Header element from a message document.
* Add WS-RM namespace declaration to element.
*
* @param doc
* @return header
* @throws JAXBException if not found
* @param element
*/
protected Element getSoapHeader(Document doc) throws JAXBException {
NodeList nodes = doc.getDocumentElement().getChildNodes();
Element header = null;
for (int i = 0; i < nodes.getLength(); i++) {
Node node = nodes.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE && "Header".equals(node.getLocalName())) {
header = (Element)node;
break;
}
}
if (header == null) {
throw new JAXBException("No SOAP:Header element in message");
}
return header;
protected void addNamespaceDecl(Element element) {
Attr attr = element.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + RMConstants.NAMESPACE_PREFIX);
attr.setValue(getWSRMNamespace());
element.setAttributeNodeNS(attr);
}

/**
* Inserts a Header element containing a WS-RM Fault into a SOAP message.
* Builds an element containing a WS-RM Fault. This adds the appropriate WS-RM namespace declaration to
* the element, and then adds the Fault as a child element.
*
* @param sf
* @param qname constructed element name
* @param doc
* @return element
*/
public void insertHeaderFault(SequenceFault sf, Document doc) throws JAXBException {
Element header = getSoapHeader(doc);
public Element buildHeaderFault(SequenceFault sf, QName qname) throws JAXBException {

// create element with namespace declaration included
Document doc = DOMUtils.createDocument();
Element header = doc.createElementNS(qname.getNamespaceURI(), qname.getLocalPart());
addNamespaceDecl(header);

// insert the actual fault
Marshaller marshaller = getContext().createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
buildHeaderFault(sf, header, marshaller);
return header;
}

/**
@@ -30,7 +30,6 @@
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

@@ -105,13 +104,6 @@ protected JAXBContext getContext() throws JAXBException {
}
return jaxbContext;
}

protected void addNamespaceDecl(Element element) {
Attr attr = element.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + RMConstants.NAMESPACE_PREFIX);
attr.setValue(RM10Constants.NAMESPACE_URI);
element.setAttributeNodeNS(attr);
}

protected void buildHeaders(SequenceType seq, Collection<SequenceAcknowledgement> acks,
Collection<AckRequestedType> reqs, boolean last, Element header, Marshaller marshaller) throws JAXBException {
@@ -30,7 +30,6 @@
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

@@ -105,13 +104,6 @@ protected JAXBContext getContext() throws JAXBException {
}
return jaxbContext;
}

protected void addNamespaceDecl(Element element) {
Attr attr = element.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + RMConstants.NAMESPACE_PREFIX);
attr.setValue(RM10Constants.NAMESPACE_URI);
element.setAttributeNodeNS(attr);
}

protected void buildHeaders(SequenceType seq, Collection<SequenceAcknowledgement> acks,
Collection<AckRequestedType> reqs, boolean last, Element header, Marshaller marshaller) throws JAXBException {
@@ -30,7 +30,6 @@
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

@@ -129,13 +128,6 @@ protected void buildHeaders(SequenceType seq, Collection<SequenceAcknowledgement
}
}

protected void addNamespaceDecl(Element element) {
Attr attr = element.getOwnerDocument().createAttributeNS("http://www.w3.org/2000/xmlns/",
"xmlns:" + RMConstants.NAMESPACE_PREFIX);
attr.setValue(RM10Constants.NAMESPACE_URI);
element.setAttributeNodeNS(attr);
}

public void buildHeaderFault(SequenceFault sf, Element header, Marshaller marshaller) throws JAXBException {
SequenceFaultType flt = new SequenceFaultType();
flt.setFaultCode(sf.getFaultCode());
@@ -56,9 +56,10 @@ protected void handle(Message message) throws SequenceFault, RMException {
is.close();
saved.lockOutputStream();

message.setContent(InputStream.class, saved.getInputStream());
LOG.fine("Capturing the original RM message");
message.put(RMMessageConstants.SAVED_CONTENT, saved.getInputStream());
RewindableInputStream ris = RewindableInputStream.makeRewindable(saved.getInputStream());
message.setContent(InputStream.class, ris);
message.put(RMMessageConstants.SAVED_CONTENT, ris);
} catch (Exception e) {
throw new Fault(e);
}

0 comments on commit 9879f3e

Please sign in to comment.