summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/pom.xml2
-rw-r--r--sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/JAXWSBindingProvider.java134
2 files changed, 132 insertions, 4 deletions
diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/pom.xml b/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/pom.xml
index 2664642436..f0adefc38f 100644
--- a/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/pom.xml
+++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/pom.xml
@@ -34,7 +34,6 @@
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-core</artifactId>
<version>2.0-SNAPSHOT</version>
- <scope>runtime</scope>
</dependency>
<dependency>
@@ -47,7 +46,6 @@
<groupId>org.apache.tuscany.sca</groupId>
<artifactId>tuscany-assembly-xml</artifactId>
<version>2.0-SNAPSHOT</version>
- <scope>runtime</scope>
</dependency>
<dependency>
diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/JAXWSBindingProvider.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/JAXWSBindingProvider.java
index a2cef5340c..5cc9277201 100644
--- a/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/JAXWSBindingProvider.java
+++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-jaxws/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/JAXWSBindingProvider.java
@@ -18,6 +18,7 @@
*/
package org.apache.tuscany.sca.binding.ws.jaxws;
+import java.util.Iterator;
import java.util.List;
import javax.annotation.Resource;
@@ -29,15 +30,21 @@ import javax.xml.soap.SOAPElement;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPFactory;
import javax.xml.soap.SOAPFault;
+import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.Provider;
+import javax.xml.ws.Service.Mode;
import javax.xml.ws.ServiceMode;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.WebServiceProvider;
-import javax.xml.ws.Service.Mode;
+import org.apache.tuscany.sca.assembly.AssemblyFactory;
+import org.apache.tuscany.sca.assembly.Endpoint;
+import org.apache.tuscany.sca.assembly.EndpointReference;
import org.apache.tuscany.sca.binding.ws.WebServiceBinding;
+import org.apache.tuscany.sca.binding.ws.WebServiceBindingFactory;
import org.apache.tuscany.sca.core.FactoryExtensionPoint;
+import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory;
import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint;
import org.apache.tuscany.sca.host.http.ServletHost;
import org.apache.tuscany.sca.interfacedef.InterfaceContract;
@@ -54,6 +61,13 @@ import org.w3c.dom.Node;
@WebServiceProvider
@ServiceMode(Mode.MESSAGE)
public class JAXWSBindingProvider implements Provider<SOAPMessage> {
+ public static final String WSA_FINAL_NAMESPACE = "http://www.w3.org/2005/08/addressing";
+ public static final QName QNAME_WSA_ADDRESS = new QName(WSA_FINAL_NAMESPACE, "Address");
+ public static final QName QNAME_WSA_FROM = new QName(WSA_FINAL_NAMESPACE, "From");
+ public static final QName QNAME_WSA_REPLYTO = new QName(WSA_FINAL_NAMESPACE, "ReplyTo");
+ public static final QName QNAME_WSA_REFERENCE_PARAMETERS = new QName(WSA_FINAL_NAMESPACE, "ReferenceParameters");
+ public static final QName QNAME_WSA_MESSAGEID = new QName(WSA_FINAL_NAMESPACE, "MessageID");
+
private MessageFactory messageFactory;
private RuntimeEndpoint endpoint;
private WebServiceBinding wsBinding;
@@ -61,7 +75,9 @@ public class JAXWSBindingProvider implements Provider<SOAPMessage> {
private SOAPFactory soapFactory;
@Resource
- private WebServiceContext context;
+ private WebServiceContext context;
+ private RuntimeAssemblyFactory assemblyFactory;
+ private WebServiceBindingFactory webServiceBindingFactory;
public JAXWSBindingProvider(){
// to keep Axis2 JAXWS implementation happy
@@ -76,6 +92,8 @@ public class JAXWSBindingProvider implements Provider<SOAPMessage> {
this.soapMessageFactory = modelFactories.getFactory(javax.xml.soap.MessageFactory.class);
this.soapFactory = modelFactories.getFactory(SOAPFactory.class);
+ this.assemblyFactory = (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class);
+ this.webServiceBindingFactory = (WebServiceBindingFactory)modelFactories.getFactory(WebServiceBindingFactory.class);
// soapMessageFactory = javax.xml.soap.MessageFactory.newInstance();
// soapFactory = SOAPFactory.newInstance();
@@ -156,6 +174,36 @@ public class JAXWSBindingProvider implements Provider<SOAPMessage> {
requestMsg.setBody(body);
requestMsg.setOperation(operation);
+ SOAPHeader header = request.getSOAPHeader();
+ String callbackAddress = null;
+ if (header != null) {
+ callbackAddress = handleCallbackAddress( header, requestMsg );
+ // Retrieve other callback-related headers
+ handleMessageIDHeader( header, requestMsg );
+ } // end if
+
+ // Create a from EPR to hold the details of the callback endpoint
+ EndpointReference from = null;
+ if (callbackAddress != null ) {
+ // Check for special (& not allowed!) WS_Addressing values
+ checkCallbackAddress( callbackAddress, request );
+ //
+ from = assemblyFactory.createEndpointReference();
+ Endpoint fromEndpoint = assemblyFactory.createEndpoint();
+ from.setTargetEndpoint(fromEndpoint);
+ from.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED);
+ requestMsg.setFrom(from);
+ Endpoint callbackEndpoint = assemblyFactory.createEndpoint();
+ //
+ WebServiceBinding cbBinding = webServiceBindingFactory.createWebServiceBinding();
+ cbBinding.setURI(callbackAddress);
+ callbackEndpoint.setBinding(cbBinding);
+ //
+ callbackEndpoint.setURI(callbackAddress);
+ callbackEndpoint.setUnresolved(true);
+ from.setCallbackEndpoint(callbackEndpoint);
+ }
+
Message responseMsg = endpoint.invoke(operation, requestMsg);
SOAPMessage response = soapMessageFactory.createMessage();
@@ -181,4 +229,86 @@ public class JAXWSBindingProvider implements Provider<SOAPMessage> {
throw new ServiceRuntimeException(e);
}
}
+ private static String WS_REF_PARMS = "WS_REFERENCE_PARAMETERS";
+ private String handleCallbackAddress( SOAPHeader header, Message msg ) {
+ String callbackAddress = null;
+
+ Iterator<SOAPElement> it = header.getChildElements(QNAME_WSA_FROM);
+ SOAPElement from = it.hasNext() ? it.next() : null;
+ if( from == null ) {
+ Iterator<SOAPElement> it2 = header.getChildElements(QNAME_WSA_REPLYTO);
+ from = it2.hasNext() ? it2.next() : null;
+ }
+
+ if (from != null) {
+ Iterator<SOAPElement> it2 = header.getChildElements(QNAME_WSA_ADDRESS);
+ SOAPElement callbackAddrElement = it2.hasNext() ? it2.next() : null;
+ if (callbackAddrElement != null) {
+ if (endpoint.getService().getInterfaceContract().getCallbackInterface() != null) {
+ callbackAddress = callbackAddrElement.getTextContent();
+ }
+// OMElement refParms = from.getFirstChildWithName(QNAME_WSA_REFERENCE_PARAMETERS);
+ Iterator<SOAPElement> it3 = header.getChildElements(QNAME_WSA_REFERENCE_PARAMETERS);
+ SOAPElement refParms = it3.hasNext() ? it3.next() : null;
+ if( refParms != null ) msg.getHeaders().put(WS_REF_PARMS, refParms);
+ }
+ } // end if
+
+ return callbackAddress;
+ } // end method handleCallbackAddress
+
+ private static String WS_MESSAGE_ID = "WS_MESSAGE_ID";
+ /**
+ * Handle a SOAP wsa:MessageID header - place the contents into the Tuscany message for use by any callback
+ * @param header - the SOAP Headers
+ * @param msg - the Tuscany Message
+ */
+ private void handleMessageIDHeader( SOAPHeader header, Message msg ) {
+ if( header == null ) return;
+ Iterator<SOAPElement> it = header.getChildElements(QNAME_WSA_MESSAGEID);
+ SOAPElement messageID = it.hasNext() ? it.next() : null;
+ if (messageID != null) {
+ String idValue = messageID.getTextContent();
+ // Store the value of the message ID element into the message under "WS_MESSAGE_ID"...
+ msg.getHeaders().put(WS_MESSAGE_ID, idValue);
+ } // end if
+ } // end method handleMessageID
+ // Special WS_Addressing values
+ private static String WS_ADDR_ANONYMOUS = "http://www.w3.org/2005/08/addressing/anonymous";
+ private static String WS_ADDR_NONE = "http://www.w3.org/2005/08/addressing/none";
+
+ /**
+ * Check if the received callback address has either of the special WS-Addressing forms which are outlawed by the
+ * Web Service Binding specification [BWS50004]
+ * @param callbackAddress - the received callback address
+ * @param inMC - the Axis message context for the received forward call
+ * @throws AxisFault - throws a "OnlyNonAnonymousAddressSupportedFault" if the callback address has either of the special forms
+ */
+ private void checkCallbackAddress( String callbackAddress, SOAPMessage request) {
+ // If the address is anonymous or none, throw a SOAP fault...
+ if( WS_ADDR_ANONYMOUS.equals(callbackAddress) || WS_ADDR_NONE.equals(callbackAddress) ) {
+ triggerOnlyNonAnonymousAddressSupportedFault(request, "wsa:From");
+ }
+ } // end method checkCallbackAddress
+ // wsa:OnlyAnonymousAddressSupported
+
+ // wsa:OnlyNonAnonymousAddressSupported
+ public void triggerOnlyNonAnonymousAddressSupportedFault(SOAPMessage request, String incorrectHeaderName){
+// TODO
+// String namespace = (String)messageContext.getProperty(AddressingConstants.WS_ADDRESSING_VERSION);
+// if (Submission.WSA_NAMESPACE.equals(namespace)) {
+// triggerAddressingFault(messageContext, Final.FAULT_HEADER_PROB_HEADER_QNAME,
+// AddressingConstants.WSA_DEFAULT_PREFIX + ":" +
+// incorrectHeaderName, Submission.FAULT_INVALID_HEADER,
+// null, AddressingMessages.getMessage(
+// "spec.submission.FAULT_INVALID_HEADER_REASON"));
+// } else {
+// triggerAddressingFault(messageContext, Final.FAULT_HEADER_PROB_HEADER_QNAME,
+// AddressingConstants.WSA_DEFAULT_PREFIX + ":" +
+// incorrectHeaderName, Final.FAULT_INVALID_HEADER,
+// Final.FAULT_ONLY_NON_ANONYMOUS_ADDRESS_SUPPORTED,
+// AddressingMessages.getMessage(
+// "spec.final.FAULT_INVALID_HEADER_REASON"));
+// }
+ }
}