Author: richard.opalka(a)jboss.com
Date: 2010-05-17 10:11:27 -0400 (Mon, 17 May 2010)
New Revision: 12246
Added:
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/DetailedAddressingException.java
Modified:
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/handler/HandlerChainExecutor.java
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/jaxws/WSAddressingServerHandler.java
stack/native/trunk/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/handlerlifecycle/HandlerLifecycleTestCase.java
Log:
[JBWS-3027] throwing runtime exceptions in Addressing handler plus ensuring proper handler
flow, see JIRA
Modified:
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java
===================================================================
---
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java 2010-05-17
14:07:12 UTC (rev 12245)
+++
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/SOAPFaultHelperJAXWS.java 2010-05-17
14:11:27 UTC (rev 12246)
@@ -38,6 +38,7 @@
import javax.xml.transform.Source;
import javax.xml.transform.dom.DOMSource;
import javax.xml.ws.WebServiceException;
+import javax.xml.ws.addressing.AddressingException;
import javax.xml.ws.addressing.MapRequiredException;
import javax.xml.ws.soap.SOAPBinding;
import javax.xml.ws.soap.SOAPFaultException;
@@ -57,12 +58,14 @@
import org.jboss.ws.core.soap.MessageFactoryImpl;
import org.jboss.ws.core.soap.NameImpl;
import org.jboss.ws.core.soap.SOAPFactoryImpl;
+import org.jboss.ws.core.soap.SOAPFaultImpl;
import org.jboss.ws.core.soap.SOAPMessageImpl;
import org.jboss.ws.core.soap.XMLFragment;
import org.jboss.ws.metadata.umdm.EndpointMetaData;
import org.jboss.ws.metadata.umdm.FaultMetaData;
import org.jboss.ws.metadata.umdm.OperationMetaData;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
import com.ibm.wsdl.extensions.soap12.SOAP12Constants;
@@ -270,6 +273,28 @@
MapRequiredException addrException = (MapRequiredException)ex;
soapFault = soapBody.addFault(addrException.getSubcode(),
addrException.getMessage());
}
+ else if (ex instanceof AddressingException)
+ {
+ try
+ {
+ AddressingException addrException = (AddressingException) ex;
+ SOAPFault fault = new SOAPFaultImpl();
+ fault.setFaultCode(addrException.getCode());
+ fault.setFaultString(addrException.getReason());
+ Detail detail = fault.addDetail();
+ Object detailElement = addrException.getDetail();
+ if (detailElement instanceof Node)
+ {
+ detail.appendChild((Node)detailElement);
+ }
+
+ return toSOAPMessage(new SOAPFaultException(fault));
+ }
+ catch (SOAPException e)
+ {
+ log.warn(e);
+ }
+ }
else
{
soapFault = soapBody.addFault(getFallbackFaultCode(),
getFallbackFaultString(ex));
Modified:
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/handler/HandlerChainExecutor.java
===================================================================
---
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/handler/HandlerChainExecutor.java 2010-05-17
14:07:12 UTC (rev 12245)
+++
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/core/jaxws/handler/HandlerChainExecutor.java 2010-05-17
14:11:27 UTC (rev 12246)
@@ -27,6 +27,7 @@
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.soap.SOAPPart;
+import javax.xml.ws.ProtocolException;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.handler.Handler;
import javax.xml.ws.handler.LogicalHandler;
@@ -154,9 +155,24 @@
index = getNextIndex(index);
}
}
+ catch (ProtocolException pe)
+ {
+ // JAX-WS 2.2 specification
+ // 9.3.2.1 handleMessage chapter
+ // Throw ProtocolException or a subclass paragraph
+ doNext = false;
+ processHandlerFailure(pe);
+ }
catch (RuntimeException ex)
{
+ // JAX-WS 2.2 specification
+ // 9.3.2.1 handleMessage chapter
+ // Throw any other runtime exception paragraph
doNext = false;
+ if (serverSide && !isOutbound)
+ {
+ index = index -1;
+ }
processHandlerFailure(ex);
}
finally
@@ -164,7 +180,7 @@
// we start at this index in the response chain
if (doNext == false)
falseIndex = index;
-
+
if (debugEnabled)
log.debug("Exit: handle" + (isOutbound ? "Out" :
"In ") + "BoundMessage with status: " + doNext);
}
Added:
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/DetailedAddressingException.java
===================================================================
---
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/DetailedAddressingException.java
(rev 0)
+++
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/DetailedAddressingException.java 2010-05-17
14:11:27 UTC (rev 12246)
@@ -0,0 +1,79 @@
+/*
+ * JBoss, Home of Professional Open Source.
+ * Copyright 2006, Red Hat Middleware LLC, and individual contributors
+ * as indicated by the @author tags. See the copyright.txt file in the
+ * distribution for a full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site:
http://www.fsf.org.
+ */
+package org.jboss.ws.extensions.addressing;
+
+import javax.xml.namespace.QName;
+import javax.xml.ws.addressing.AddressingException;
+
+/**
+ * Addressing exception that allows better addressing details setup.
+ *
+ * @author <a href="mailto:ropalka@redhat.com">Richard Opalka</a>
+ */
+public final class DetailedAddressingException extends AddressingException
+{
+
+ private static final long serialVersionUID = 1L;
+
+ public DetailedAddressingException(final QName code, final String reason, final Object
detail)
+ {
+ super();
+
+ this.setInternals(code, reason, detail);
+ }
+
+ public DetailedAddressingException(final String message, final Throwable cause, final
QName code, final String reason, final Object detail)
+ {
+ super(message, cause);
+
+ this.setInternals(code, reason, detail);
+ }
+
+ public DetailedAddressingException(final String message, final QName code, final
String reason, final Object detail)
+ {
+ super(message);
+
+ this.setInternals(code, reason, detail);
+ }
+
+ public DetailedAddressingException(final Throwable cause, final QName code, final
String reason, final Object detail)
+ {
+ super(cause);
+
+ this.setInternals(code, reason, detail);
+ }
+
+ private void setInternals(final QName code, final String reason, final Object detail)
+ {
+ if (code == null)
+ throw new IllegalArgumentException("code must be specified");
+ if (reason == null)
+ throw new IllegalArgumentException("reason must be specified");
+ if (detail == null)
+ throw new IllegalArgumentException("detail must be specified");
+
+ this.code = code;
+ this.reason = reason;
+ this.detail = detail;
+ }
+
+}
Modified:
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/jaxws/WSAddressingServerHandler.java
===================================================================
---
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/jaxws/WSAddressingServerHandler.java 2010-05-17
14:07:12 UTC (rev 12245)
+++
stack/native/trunk/modules/core/src/main/java/org/jboss/ws/extensions/addressing/jaxws/WSAddressingServerHandler.java 2010-05-17
14:11:27 UTC (rev 12246)
@@ -21,7 +21,6 @@
*/
package org.jboss.ws.extensions.addressing.jaxws;
-import java.lang.annotation.Annotation;
import java.net.URISyntaxException;
import java.util.Collections;
import java.util.HashSet;
@@ -30,10 +29,7 @@
import java.util.Set;
import javax.xml.namespace.QName;
-import javax.xml.soap.Detail;
-import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
-import javax.xml.soap.SOAPFault;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.WebServiceException;
import javax.xml.ws.addressing.AddressingBuilder;
@@ -45,14 +41,13 @@
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.handler.MessageContext.Scope;
import javax.xml.ws.handler.soap.SOAPMessageContext;
-import javax.xml.ws.soap.Addressing;
import javax.xml.ws.soap.AddressingFeature;
-import javax.xml.ws.soap.SOAPFaultException;
import org.jboss.logging.Logger;
+import org.jboss.util.xml.DOMUtils;
import org.jboss.ws.core.CommonMessageContext;
-import org.jboss.ws.core.soap.SOAPFaultImpl;
import org.jboss.ws.extensions.addressing.AddressingConstantsImpl;
+import org.jboss.ws.extensions.addressing.DetailedAddressingException;
import org.jboss.ws.extensions.addressing.metadata.AddressingOpMetaExt;
import org.jboss.ws.metadata.umdm.FaultMetaData;
import org.jboss.ws.metadata.umdm.OperationMetaData;
@@ -60,6 +55,7 @@
import org.jboss.wsf.common.addressing.AddressingConstants;
import org.jboss.wsf.common.handler.GenericSOAPHandler;
import org.w3c.dom.Element;
+import org.w3c.dom.Node;
/**
* A server side handler that reads/writes the addressing properties
@@ -117,6 +113,7 @@
}
addrProps.readHeaders(soapMessage);
+
if (addrProps.getAction() != null)
{
msgContext.put(JAXWSAConstants.SERVER_ADDRESSING_PROPERTIES_INBOUND,
addrProps);
@@ -136,24 +133,20 @@
// R1109 The value of the SOAPAction HTTP header field in a HTTP request
MESSAGE MUST be a quoted string.
if (!soapAction.equals(wsaAction) &&
!soapAction.equals("\"" + wsaAction + "\""))
{
- try
- {
- SOAPFault fault = new SOAPFaultImpl();
- fault.setFaultCode(new QName(ADDR_CONSTANTS.getNamespaceURI(),
"ActionMismatch"));
- fault.setFaultString("Mismatch between soap action:" +
soapAction + " and wsa action:\""
- + addrProps.getAction().getURI() + "\"");
- Detail detail = fault.addDetail();
- detail.addDetailEntry(new QName(ADDR_CONSTANTS.getNamespaceURI(),
"ProblemAction"));
- throw new SOAPFaultException(fault);
- }
- catch (SOAPException e)
- {
- throw new WebServiceException(e);
- }
+ final QName code = new QName(ADDR_CONSTANTS.getNamespaceURI(),
"ActionMismatch");
+ final String reason = "Mismatch between soap action:" +
soapAction + " and wsa action:\""
+ + addrProps.getAction().getURI() + "\"";
+ final Node detail = DOMUtils.createElement(new
QName(ADDR_CONSTANTS.getNamespaceURI(),
+ "ProblemAction"));
+
+ throw new DetailedAddressingException(code, reason, detail);
}
}
}
}
+
+ this.ensureAnonymousPolicy(addrProps, msgContext);
+
return true;
}
@@ -236,8 +229,6 @@
}
outProps.writeHeaders(soapMessage);
-
- this.ensureAnonymousPolicy(inProps, msgContext);
}
private AttributedURI newURI(final String uri) // TODO: client addressing handler have
the same method - refactor it to some helper class
@@ -262,34 +253,41 @@
private AddressingOpMetaExt getAddressingMetaData(final MessageContext msgContext)
{
OperationMetaData operationMD = this.getOperationMetaData(msgContext);
+ AddressingOpMetaExt addressingMD = null;
- AddressingOpMetaExt addressingMD = (AddressingOpMetaExt)
operationMD.getExtension(ADDR_CONSTANTS
- .getNamespaceURI());
+ if (operationMD != null)
+ {
+ addressingMD = (AddressingOpMetaExt)
operationMD.getExtension(ADDR_CONSTANTS.getNamespaceURI());
- if (addressingMD == null)
- throw new IllegalStateException("Addressing meta data not
available");
+ if (addressingMD == null)
+ throw new IllegalStateException("Addressing meta data not
available");
+ }
return addressingMD;
}
-
+
private void ensureAnonymousPolicy(final SOAPAddressingProperties inProps, final
MessageContext msgContext)
{
- final AddressingFeature addressing =
this.getOperationMetaData(msgContext).getEndpointMetaData().getFeature(AddressingFeature.class);
- final boolean isOnlyAnonymousEnabled = addressing != null &&
addressing.getResponses() == AddressingFeature.Responses.ANONYMOUS;
- final boolean isOnlyNonAnonymousEnabled = addressing != null &&
addressing.getResponses() == AddressingFeature.Responses.NON_ANONYMOUS;
+ final CommonMessageContext commonCtx = (CommonMessageContext) msgContext;
+ final AddressingFeature addressing =
commonCtx.getEndpointMetaData().getFeature(AddressingFeature.class);
+ final boolean isOnlyAnonymousEnabled = addressing != null
+ && addressing.getResponses() ==
AddressingFeature.Responses.ANONYMOUS;
+ final boolean isOnlyNonAnonymousEnabled = addressing != null
+ && addressing.getResponses() ==
AddressingFeature.Responses.NON_ANONYMOUS;
final boolean isReplyToAnonymous = this.isAnonymous(inProps.getReplyTo());
final boolean isFaultToAnonymous = this.isAnonymous(inProps.getFaultTo());
-
+
if ((isOnlyAnonymousEnabled) && (!isReplyToAnonymous ||
!isFaultToAnonymous))
{
try
{
- this.addRelatesTo(inProps, msgContext);
- SOAPFault fault = new SOAPFaultImpl();
- fault.setFaultCode(new QName(ADDR_CONSTANTS.getNamespaceURI(),
"OnlyAnonymousAddressSupported"));
- fault.setFaultString("A header representing a Message Addressing
Property is not valid and the message cannot be processed");
- this.addFaultDetail(fault, !isReplyToAnonymous ?
AddressingConstants.Core.Elements.REPLYTO_QNAME :
AddressingConstants.Core.Elements.FAULTTO_QNAME);
- throw new SOAPFaultException(fault);
+ final QName faultCode = new QName(ADDR_CONSTANTS.getNamespaceURI(),
"OnlyAnonymousAddressSupported");
+ final String reason = "A header representing a Message Addressing
Property is not valid and the message cannot be processed";
+ final Object detail = this.getProblemHeaderDetail(!isReplyToAnonymous
+ ? AddressingConstants.Core.Elements.REPLYTO_QNAME
+ : AddressingConstants.Core.Elements.FAULTTO_QNAME);
+
+ throw new DetailedAddressingException(faultCode, reason, detail);
}
catch (SOAPException e)
{
@@ -300,12 +298,13 @@
{
try
{
- this.addRelatesTo(inProps, msgContext);
- SOAPFault fault = new SOAPFaultImpl();
- fault.setFaultCode(new QName(ADDR_CONSTANTS.getNamespaceURI(),
"OnlyNonAnonymousAddressSupported"));
- fault.setFaultString("A header representing a Message Addressing
Property is not valid and the message cannot be processed");
- this.addFaultDetail(fault, isReplyToAnonymous ?
AddressingConstants.Core.Elements.REPLYTO_QNAME :
AddressingConstants.Core.Elements.FAULTTO_QNAME);
- throw new SOAPFaultException(fault);
+ final QName faultCode = new QName(ADDR_CONSTANTS.getNamespaceURI(),
"OnlyNonAnonymousAddressSupported");
+ final String reason = "A header representing a Message Addressing
Property is not valid and the message cannot be processed";
+ final Object detail = this.getProblemHeaderDetail(isReplyToAnonymous
+ ? AddressingConstants.Core.Elements.REPLYTO_QNAME
+ : AddressingConstants.Core.Elements.FAULTTO_QNAME);
+
+ throw new DetailedAddressingException(faultCode, reason, detail);
}
catch (SOAPException e)
{
@@ -313,37 +312,30 @@
}
}
}
-
- private void addFaultDetail(final SOAPFault faultElement, final QName
problemHeaderQName) throws SOAPException
+
+ private Node getProblemHeaderDetail(final QName problemHeaderQName) throws
SOAPException
{
- final Detail detailElement = faultElement.addDetail();
- final SOAPElement problemHeaderQNameElement =
detailElement.addChildElement(AddressingConstants.Core.Elements.PROBLEMHEADERQNAME_QNAME);
+ final Element problemHeaderQNameElement = DOMUtils
+ .createElement(AddressingConstants.Core.Elements.PROBLEMHEADERQNAME_QNAME);
problemHeaderQNameElement.setTextContent(problemHeaderQName.toString());
+
+ return problemHeaderQNameElement;
}
-
- private void addRelatesTo(final SOAPAddressingProperties inProps, final MessageContext
msgContext) throws SOAPException
- {
- final String reqMessageID = inProps.getMessageID().getURI().toString();
- final SOAPMessage soapMessage = ((SOAPMessageContext) msgContext).getMessage();
- final SOAPElement relatesToElement =
soapMessage.getSOAPHeader().addChildElement(AddressingConstants.Core.Elements.RELATESTO_QNAME);
-
- relatesToElement.setTextContent(reqMessageID);
- }
private boolean isAnonymous(final EndpointReference epr)
{
if ((epr != null) && (epr.getAddress() != null))
return
ADDR_CONSTANTS.getAnonymousURI().equals(epr.getAddress().getURI().toString());
-
+
return true;
}
private String getFaultAction(final MessageContext msgContext)
{
- final OperationMetaData operationMD = this.getOperationMetaData(msgContext);
final AddressingOpMetaExt addressingMD = this.getAddressingMetaData(msgContext);
final Throwable exception = ((CommonMessageContext)
msgContext).getCurrentException();
- final FaultMetaData faultMD = operationMD.getFaultMetaData(exception.getClass());
+ final OperationMetaData operationMD = this.getOperationMetaData(msgContext);
+ final FaultMetaData faultMD = operationMD != null ?
operationMD.getFaultMetaData(exception.getClass()) : null;
if (faultMD != null)
{
Modified:
stack/native/trunk/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/handlerlifecycle/HandlerLifecycleTestCase.java
===================================================================
---
stack/native/trunk/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/handlerlifecycle/HandlerLifecycleTestCase.java 2010-05-17
14:07:12 UTC (rev 12245)
+++
stack/native/trunk/modules/testsuite/native-tests/src/test/java/org/jboss/test/ws/jaxws/handlerlifecycle/HandlerLifecycleTestCase.java 2010-05-17
14:11:27 UTC (rev 12246)
@@ -332,6 +332,7 @@
expMessages.add("PostServerHandler1:Message:InBound");
expMessages.add("ServerHandler3:Message:InBound");
expMessages.add("ServerHandler2:Message:InBound:ErrorInServerHandler2");
+ expMessages.add("ServerHandler2:Fault:OutBound");
expMessages.add("ServerHandler3:Fault:OutBound");
expMessages.add("PostServerHandler1:Fault:OutBound");
expMessages.add("PostServerHandler2:Fault:OutBound");
@@ -601,7 +602,7 @@
expMessages.add("ClientHandler1:Close");
expMessages.add("PreClientHandler2:Close");
expMessages.add("PreClientHandler1:Close");
-
+
assertEquals(expMessages.toString(), trackerMessages);
trackerMessages = trackerPort.getListMessages();