Skip to content

Commit b968d48

Browse files
committed
SWS-465: Optional WS-Addressing request headers being treated as mandatory
1 parent 2983668 commit b968d48

File tree

9 files changed

+99
-35
lines changed

9 files changed

+99
-35
lines changed

core/src/main/java/org/springframework/ws/soap/addressing/core/MessageAddressingProperties.java

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -153,23 +153,4 @@ public List getReferenceParameters() {
153153
public MessageAddressingProperties getReplyProperties(EndpointReference epr, URI action, URI messageId) {
154154
return new MessageAddressingProperties(epr, action, messageId, this.messageId);
155155
}
156-
157-
/**
158-
* Indicates whether is {@link MessageAddressingProperties} has all required properties.
159-
*
160-
* @return <code>true</code> if the to and action properties have been set, and - if a reply or fault endpoint has
161-
* been set - also checks for the message id
162-
*/
163-
public boolean hasRequiredProperties() {
164-
if (to == null) {
165-
return false;
166-
}
167-
if (action == null) {
168-
return false;
169-
}
170-
if (replyTo != null || faultTo != null) {
171-
return messageId != null;
172-
}
173-
return true;
174-
}
175156
}

core/src/main/java/org/springframework/ws/soap/addressing/server/AddressingEndpointInterceptor.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public final boolean handleRequest(MessageContext messageContext, Object endpoin
7474
Assert.isInstanceOf(SoapMessage.class, messageContext.getRequest());
7575
SoapMessage request = (SoapMessage) messageContext.getRequest();
7676
MessageAddressingProperties requestMap = version.getMessageAddressingProperties(request);
77-
if (!requestMap.hasRequiredProperties()) {
77+
if (!version.hasRequiredProperties(requestMap)) {
7878
version.addMessageAddressingHeaderRequiredFault((SoapMessage) messageContext.getResponse());
7979
return false;
8080
}
@@ -119,8 +119,9 @@ private boolean handleResponseOrFault(MessageContext messageContext, boolean isF
119119
private boolean handleNoneAddress(MessageContext messageContext, EndpointReference replyEpr) {
120120
if (replyEpr == null || version.hasNoneAddress(replyEpr)) {
121121
if (logger.isDebugEnabled()) {
122-
logger.debug("Request " + messageContext.getRequest() + "] has [" + replyEpr +
123-
"] reply address; reply [" + messageContext.getResponse() + "] discarded");
122+
logger.debug(
123+
"Request [" + messageContext.getRequest() + "] has [" + replyEpr + "] reply address; reply [" +
124+
messageContext.getResponse() + "] discarded");
124125
}
125126
messageContext.clearResponse();
126127
return true;
@@ -131,7 +132,7 @@ private boolean handleNoneAddress(MessageContext messageContext, EndpointReferen
131132
private boolean handleAnonymousAddress(MessageContext messageContext, EndpointReference replyEpr) {
132133
if (version.hasAnonymousAddress(replyEpr)) {
133134
if (logger.isDebugEnabled()) {
134-
logger.debug("Request " + messageContext.getRequest() + "] has [" + replyEpr +
135+
logger.debug("Request [" + messageContext.getRequest() + "] has [" + replyEpr +
135136
"] reply address; sending in-band reply [" + messageContext.getResponse() + "]");
136137
}
137138
return true;
@@ -141,7 +142,7 @@ private boolean handleAnonymousAddress(MessageContext messageContext, EndpointRe
141142

142143
private void sendOutOfBand(MessageContext messageContext, EndpointReference replyEpr) throws IOException {
143144
if (logger.isDebugEnabled()) {
144-
logger.debug("Request " + messageContext.getRequest() + "] has [" + replyEpr +
145+
logger.debug("Request [" + messageContext.getRequest() + "] has [" + replyEpr +
145146
"] reply address; sending out-of-band reply [" + messageContext.getResponse() + "]");
146147
}
147148

core/src/main/java/org/springframework/ws/soap/addressing/version/AbstractAddressingVersion.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,9 @@ private XPathExpression createChildrenExpression(QName name, Properties namespac
123123
public MessageAddressingProperties getMessageAddressingProperties(SoapMessage message) {
124124
Element headerElement = getSoapHeaderElement(message);
125125
URI to = getUri(headerElement, toExpression);
126+
if (to == null) {
127+
to = getDefaultTo();
128+
}
126129
EndpointReference from = getEndpointReference(fromExpression.evaluateAsNode(headerElement));
127130
EndpointReference replyTo = getEndpointReference(replyToExpression.evaluateAsNode(headerElement));
128131
if (replyTo == null) {
@@ -392,6 +395,9 @@ protected QName getAddressName() {
392395
return QNameUtils.createQName(getNamespaceUri(), "Address", getNamespacePrefix());
393396
}
394397

398+
/** Returns the default To URI. */
399+
protected abstract URI getDefaultTo();
400+
395401
/** Returns the default ReplyTo EPR. Can be based on the From EPR, or the anonymous URI. */
396402
protected abstract EndpointReference getDefaultReplyTo(EndpointReference from);
397403

core/src/main/java/org/springframework/ws/soap/addressing/version/Addressing10.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,17 @@ public void addAddressingHeaders(SoapMessage message, MessageAddressingPropertie
4343
super.addAddressingHeaders(message, map);
4444
}
4545

46+
public boolean hasRequiredProperties(MessageAddressingProperties map) {
47+
if (map.getAction() == null) {
48+
return false;
49+
}
50+
if (map.getReplyTo() != null || map.getFaultTo() != null) {
51+
return map.getMessageId() != null;
52+
}
53+
return true;
54+
55+
}
56+
4657
protected String getNamespaceUri() {
4758
return NAMESPACE_URI;
4859
}
@@ -51,6 +62,10 @@ protected QName getReferencePropertiesName() {
5162
return null;
5263
}
5364

65+
protected URI getDefaultTo() {
66+
return getAnonymous();
67+
}
68+
5469
protected EndpointReference getDefaultReplyTo(EndpointReference from) {
5570
return new EndpointReference(getAnonymous());
5671
}

core/src/main/java/org/springframework/ws/soap/addressing/version/Addressing200408.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,33 @@
3030
* Microsoft's Web Services Enhancements (WSE) 3.0, and supported by Axis 1 and 2, and XFire.
3131
*
3232
* @author Arjen Poutsma
33-
* @see <a href="http://msdn.microsoft.com/ws/2004/08/ws-addressing/">Web Services Addressing, August 2004</a>
33+
* @see <a href="http://www.w3.org/Submission/2004/SUBM-ws-addressing-20040810/">Web Services Addressing, August
34+
* 2004</a>
3435
* @since 1.5.0
3536
*/
3637
public class Addressing200408 extends AbstractAddressingVersion {
3738

3839
private static final String NAMESPACE_URI = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
3940

4041
public void addAddressingHeaders(SoapMessage message, MessageAddressingProperties map) {
41-
Assert.notNull(map.getAction(), "'Action' must not be null");
42-
Assert.notNull(map.getTo(), "'Action' must not be null");
42+
Assert.notNull(map.getAction(), "'Action' is required");
43+
Assert.notNull(map.getTo(), "'To' is required");
4344
super.addAddressingHeaders(message, map);
4445
}
4546

47+
public boolean hasRequiredProperties(MessageAddressingProperties map) {
48+
if (map.getTo() == null) {
49+
return false;
50+
}
51+
if (map.getAction() == null) {
52+
return false;
53+
}
54+
if (map.getReplyTo() != null || map.getFaultTo() != null) {
55+
return map.getMessageId() != null;
56+
}
57+
return true;
58+
}
59+
4660
protected final URI getAnonymous() {
4761
return URI.create(NAMESPACE_URI + "/role/anonymous");
4862
}
@@ -67,6 +81,10 @@ protected final String getNamespaceUri() {
6781
return NAMESPACE_URI;
6882
}
6983

84+
protected URI getDefaultTo() {
85+
return null;
86+
}
87+
7088
protected final EndpointReference getDefaultReplyTo(EndpointReference from) {
7189
return from;
7290
}
@@ -76,6 +94,6 @@ protected final URI getNone() {
7694
}
7795

7896
public String toString() {
79-
return "Ws-Addressing August 2004";
97+
return "WS-Addressing August 2004";
8098
}
8199
}

core/src/main/java/org/springframework/ws/soap/addressing/version/AddressingVersion.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,17 @@ public interface AddressingVersion {
5656
*/
5757
boolean understands(SoapHeaderElement headerElement);
5858

59-
/*
60-
* Address URIs
59+
/**
60+
* Indicates whether the given {@link MessageAddressingProperties} has all required properties.
61+
*
62+
* @return <code>true</code> if the to and action properties have been set, and - if a reply or fault endpoint has
63+
* been set - also checks for the message id
6164
*/
65+
boolean hasRequiredProperties(MessageAddressingProperties map);
66+
67+
/*
68+
* Address URIs
69+
*/
6270

6371
/**
6472
* Indicates whether the given endpoint reference has a Anonymous address. This address is used to indicate that a

core/src/test/java/org/springframework/ws/soap/addressing/server/AbstractAddressingInterceptorTestCase.java

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@
3636

3737
public abstract class AbstractAddressingInterceptorTestCase extends AbstractWsAddressingTestCase {
3838

39-
private AddressingEndpointInterceptor interceptor;
39+
protected AddressingEndpointInterceptor interceptor;
4040

41-
private MockControl strategyControl;
41+
protected MockControl strategyControl;
4242

43-
private MessageIdStrategy strategyMock;
43+
protected MessageIdStrategy strategyMock;
4444

4545
protected final void onSetUp() throws Exception {
4646
strategyControl = MockControl.createControl(MessageIdStrategy.class);
@@ -148,8 +148,9 @@ public void testOutOfBandReplyTo() throws Exception {
148148

149149
URI replyAction = new URI("urn:replyAction");
150150
URI faultAction = new URI("urn:replyAction");
151-
interceptor = new AddressingEndpointInterceptor(getVersion(), strategyMock,
152-
new WebServiceMessageSender[]{senderMock}, replyAction, faultAction);
151+
interceptor =
152+
new AddressingEndpointInterceptor(getVersion(), strategyMock, new WebServiceMessageSender[]{senderMock},
153+
replyAction, faultAction);
153154

154155
MockControl connectionControl = MockControl.createControl(WebServiceConnection.class);
155156
WebServiceConnection connectionMock = (WebServiceConnection) connectionControl.getMock();

core/src/test/java/org/springframework/ws/soap/addressing/server/AddressingInterceptor10Test.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,15 @@
1616

1717
package org.springframework.ws.soap.addressing.server;
1818

19+
import java.net.URI;
20+
21+
import org.springframework.ws.context.DefaultMessageContext;
22+
import org.springframework.ws.context.MessageContext;
23+
import org.springframework.ws.soap.SoapMessage;
1924
import org.springframework.ws.soap.addressing.version.Addressing10;
2025
import org.springframework.ws.soap.addressing.version.AddressingVersion;
26+
import org.springframework.ws.soap.saaj.SaajSoapMessage;
27+
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;
2128

2229
public class AddressingInterceptor10Test extends AbstractAddressingInterceptorTestCase {
2330

@@ -28,4 +35,20 @@ protected AddressingVersion getVersion() {
2835
protected String getTestPath() {
2936
return "10";
3037
}
38+
39+
public void testNoTo() throws Exception {
40+
SaajSoapMessage valid = loadSaajMessage(getTestPath() + "/request-no-to.xml");
41+
MessageContext context = new DefaultMessageContext(valid, new SaajSoapMessageFactory(messageFactory));
42+
URI messageId = new URI("uid:1234");
43+
strategyControl.expectAndReturn(strategyMock.newMessageId((SoapMessage) context.getResponse()), messageId);
44+
strategyControl.replay();
45+
boolean result = interceptor.handleResponse(context, null);
46+
assertTrue("Request with no To not handled", result);
47+
assertTrue("Message Context has no response", context.hasResponse());
48+
SaajSoapMessage expectedResponse = loadSaajMessage(getTestPath() + "/response-anonymous.xml");
49+
assertXMLEqual("Invalid response for message with invalid MAP", expectedResponse,
50+
(SaajSoapMessage) context.getResponse());
51+
strategyControl.verify();
52+
}
53+
3154
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope" xmlns:wsa="http://www.w3.org/2005/08/addressing">
2+
<S:Header>
3+
<wsa:Action>http://example.com/fabrikam/mail/Delete</wsa:Action>
4+
<wsa:MessageID>http://example.com/someuniquestring</wsa:MessageID>
5+
</S:Header>
6+
<S:Body>
7+
<f:Delete xmlns:f="http://example.com/fabrikam">
8+
<f:maxCount>42</f:maxCount>
9+
</f:Delete>
10+
</S:Body>
11+
</S:Envelope>

0 commit comments

Comments
 (0)