From 0fb0a8321f7af39c8ecdcf52b1d4572b05e4c19d Mon Sep 17 00:00:00 2001 From: slaws Date: Fri, 25 Jun 2010 14:29:31 +0000 Subject: connecting the JAXWS provider to the Tuscany chain. Pointed out an interesting thing that should have been obvious but which I didn't notice before. The MessageContext coming from a JAXWSProvider is a JAXWS MessageContext and we are expecting an Axis MessageContext in our existing code. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@957987 13f79535-47bb-0310-9956-ffa450edef68 --- .../ws/jaxws/axis2/JAXWSBindingProvider.java | 114 ------------ .../sca/binding/ws/jaxws/axis2/JAXWSProvider.java | 53 ++++++ .../jaxws/axis2/JAXWSServiceBindingProvider.java | 33 ++-- .../sca/binding/ws/jaxws/axis2/WSProvider.java | 198 +++++++++++++++++++++ 4 files changed, 272 insertions(+), 126 deletions(-) delete mode 100644 sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSBindingProvider.java create mode 100644 sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSProvider.java create mode 100644 sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/WSProvider.java (limited to 'sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main') diff --git a/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSBindingProvider.java b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSBindingProvider.java deleted file mode 100644 index 6e3b821af7..0000000000 --- a/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSBindingProvider.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * 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.tuscany.sca.binding.ws.jaxws.axis2; - -import java.util.List; - -import javax.annotation.Resource; -import javax.wsdl.extensions.soap.SOAPAddress; -import javax.xml.namespace.QName; -import javax.xml.soap.Detail; -import javax.xml.soap.DetailEntry; -import javax.xml.soap.SOAPElement; -import javax.xml.soap.SOAPException; -import javax.xml.soap.SOAPFactory; -import javax.xml.soap.SOAPFault; -import javax.xml.soap.SOAPMessage; -import javax.xml.ws.Provider; -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.binding.ws.WebServiceBinding; -import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; -import org.apache.tuscany.sca.host.http.ServletHost; -import org.apache.tuscany.sca.interfacedef.InterfaceContract; -import org.apache.tuscany.sca.interfacedef.Operation; -import org.apache.tuscany.sca.interfacedef.util.FaultException; -import org.apache.tuscany.sca.invocation.InvocationChain; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.invocation.MessageFactory; -import org.apache.tuscany.sca.runtime.RuntimeEndpoint; -import org.oasisopen.sca.ServiceRuntimeException; -import org.w3c.dom.Element; -import org.w3c.dom.Node; - - -@WebServiceProvider -@ServiceMode(Mode.MESSAGE) -public class JAXWSBindingProvider implements Provider { - private MessageFactory messageFactory; - private RuntimeEndpoint endpoint; - private WebServiceBinding wsBinding; - private javax.xml.soap.MessageFactory soapMessageFactory; - private SOAPFactory soapFactory; - - @Resource - private WebServiceContext context; - - - public SOAPMessage invoke(SOAPMessage request) { - try { - // Assuming document-literal-wrapper style - Node root = request.getSOAPBody().getFirstChild(); - String operationName = root.getLocalName(); - Operation operation = null; - for (InvocationChain invocationChain : endpoint.getInvocationChains()) { - if (operationName.equals(invocationChain.getSourceOperation().getName())) { - operation = invocationChain.getSourceOperation(); - break; - } - } - if (operation == null) { - throw new SOAPException("Operation not found: " + operationName); - } - - Message requestMsg = messageFactory.createMessage(); - Object[] body = new Object[]{root}; - requestMsg.setBody(body); - requestMsg.setOperation(operation); - - Message responseMsg = endpoint.invoke(operation, requestMsg); - - SOAPMessage response = soapMessageFactory.createMessage(); - if (responseMsg.isFault()) { -// ServiceRuntimeException e = responseMsg.getBody(); -// throw e; - - FaultException fe = responseMsg.getBody(); - SOAPFault fault = response.getSOAPBody().addFault(new QName(response.getSOAPBody().getNamespaceURI(), "Server"), fe.getMessage()); - Detail d = fault.addDetail(); - DetailEntry de = d.addDetailEntry(fe.getFaultName()); - SOAPElement dece = de.addChildElement("message"); - if (fe.getMessage() != null) { - dece.addTextNode(fe.getMessage()); - } - - } else { - Element element = responseMsg.getBody(); - response.getSOAPBody().addChildElement(soapFactory.createElement(element)); - } - return response; - } catch (SOAPException e) { - throw new ServiceRuntimeException(e); - } - } -} diff --git a/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSProvider.java b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSProvider.java new file mode 100644 index 0000000000..9a4650af14 --- /dev/null +++ b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSProvider.java @@ -0,0 +1,53 @@ +/* + * 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.tuscany.sca.binding.ws.jaxws.axis2; + + + +import javax.annotation.Resource; + +import javax.xml.namespace.QName; +import javax.xml.ws.Provider; +import javax.xml.ws.ServiceMode; +import javax.xml.ws.WebServiceContext; +import javax.xml.ws.WebServiceException; +import javax.xml.ws.WebServiceProvider; +import javax.xml.ws.Service.Mode; + +import org.apache.axiom.om.OMElement; + + +@WebServiceProvider +@ServiceMode(Mode.MESSAGE) +//public class JAXWSProvider implements Provider { +public class JAXWSProvider implements Provider { + + @Resource + private WebServiceContext wsContext; + + public OMElement invoke(OMElement request) { + try { + QName operationName = (QName)wsContext.getMessageContext().get("javax.xml.ws.wsdl.operation"); + WSProvider wsProvider = JAXWSServiceBindingProvider.getProviderCache().get(operationName.getLocalPart()); + return wsProvider.invoke(request, wsContext.getMessageContext()); + } catch (Throwable e) { + throw new WebServiceException(e); + } + } +} diff --git a/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSServiceBindingProvider.java b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSServiceBindingProvider.java index 94cd1d621d..fe05a45ecf 100644 --- a/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSServiceBindingProvider.java +++ b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/JAXWSServiceBindingProvider.java @@ -22,6 +22,7 @@ import java.net.URI; import java.util.HashMap; import java.util.Iterator; import java.util.List; +import java.util.Map; import javax.wsdl.Port; import javax.xml.ws.Binding; @@ -49,6 +50,7 @@ import org.apache.tuscany.sca.core.UtilityExtensionPoint; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.host.http.SecurityContext; import org.apache.tuscany.sca.host.http.ServletHost; +import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.invocation.MessageFactory; @@ -61,6 +63,8 @@ import org.oasisopen.sca.ServiceRuntimeException; public class JAXWSServiceBindingProvider implements ServiceBindingProvider { + private static Map providerCache = new HashMap(); + // Tuscany extensions private ExtensionPointRegistry extensionPoints; private ServletHost servletHost; @@ -77,7 +81,6 @@ public class JAXWSServiceBindingProvider implements ServiceBindingProvider { protected SecurityContext httpSecurityContext; // JAXWS fields - private JAXWSBindingProvider jaxwsBindingProvider; private Endpoint wsEndpoint; // Axis2 fields @@ -146,27 +149,23 @@ public class JAXWSServiceBindingProvider implements ServiceBindingProvider { if (pp != null) { defaultPort = ps.getProperties().getProperty(this.getClass().getName() + ".defaultPort"); } - // ======== -/* - jaxwsBindingProvider = new JAXWSBindingProvider(endpoint, - servletHost, - modelFactories, - dataBindings, - defaultPort); -*/ - jaxwsBindingProvider = new JAXWSBindingProvider(); - + // ======== + // get the Axis configuration context configContext = Axis2EngineIntegration.getAxisConfigurationContext(extensionPoints.getServiceDiscovery()); //configContext.setContextRoot(servletHost.getContextPath()); configContext.setContextRoot("http://localhost:8085"); } + public static Map getProviderCache(){ + return providerCache; + } + public void start() { // experiment in how to install a JAXWS provider into Axis2 programatically try { // create the service description - JavaClassToDBCConverter converter = new JavaClassToDBCConverter(jaxwsBindingProvider.getClass()); + JavaClassToDBCConverter converter = new JavaClassToDBCConverter(JAXWSProvider.class); HashMap dbcMap = converter.produceDBC(); // Set the details of the service we are going to expose through this provider @@ -212,6 +211,15 @@ public class JAXWSServiceBindingProvider implements ServiceBindingProvider { configContext.getAxisConfiguration().addService(axisService); + Interface iface = wsBinding.getBindingInterfaceContract().getInterface(); + for (Operation operation : iface.getOperations()) { + WSProvider wsProvider = new WSProvider(extensionPoints, + endpoint, + wsBinding, + operation); + providerCache.put(operation.getName(), wsProvider); + } + // fire up the Axis servlet Axis2ServiceServlet servlet = new Axis2ServiceServlet(); servlet.init(configContext); @@ -221,6 +229,7 @@ public class JAXWSServiceBindingProvider implements ServiceBindingProvider { ex.printStackTrace(); } } + /* public void start() { // experiment in how to install a JAXWS provider into Axis programatically starting diff --git a/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/WSProvider.java b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/WSProvider.java new file mode 100644 index 0000000000..8955e842a4 --- /dev/null +++ b/sca-java-2.x/contrib/modules/binding-ws-runtime-jaxws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/jaxws/axis2/WSProvider.java @@ -0,0 +1,198 @@ +/* + * 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.tuscany.sca.binding.ws.jaxws.axis2; + +import java.lang.reflect.InvocationTargetException; +import java.util.Collection; +import java.util.Set; +import java.util.Map.Entry; +import java.util.logging.Logger; + +import javax.xml.namespace.QName; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPHeader; +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.AddressingConstants; +import org.apache.axis2.addressing.AddressingFaultsHelper; +import org.apache.axis2.context.MessageContext; +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.ExtensionPointRegistry; +import org.apache.tuscany.sca.core.FactoryExtensionPoint; +import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory; +import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.runtime.RuntimeEndpoint; + +public class WSProvider { + private static final Logger logger = Logger.getLogger(WSProvider.class.getName()); + + public static final QName QNAME_WSA_ADDRESS = + new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.EPR_ADDRESS); + public static final QName QNAME_WSA_FROM = + new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.WSA_FROM); + public static final QName QNAME_WSA_REPLYTO = + new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.WSA_REPLY_TO); + public static final QName QNAME_WSA_REFERENCE_PARAMETERS = + new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.EPR_REFERENCE_PARAMETERS); + public static final QName QNAME_WSA_MESSAGEID = + new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.WSA_MESSAGE_ID); + + private RuntimeEndpoint endpoint; + private WebServiceBinding wsBinding; + private MessageFactory messageFactory; + private FactoryExtensionPoint modelFactories; + private RuntimeAssemblyFactory assemblyFactory; + private WebServiceBindingFactory webServiceBindingFactory; + private Operation operation; + + public WSProvider(ExtensionPointRegistry extensionPoints, + RuntimeEndpoint endpoint, + WebServiceBinding wsBinding, + Operation operation) { + this.endpoint = endpoint; + this.wsBinding = wsBinding; + this.operation = operation; + this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.messageFactory = modelFactories.getFactory(MessageFactory.class); + this.assemblyFactory = (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class); + this.webServiceBindingFactory = (WebServiceBindingFactory)modelFactories.getFactory(WebServiceBindingFactory.class); + } + + // 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, MessageContext inMC ) throws AxisFault { + // If the address is anonymous or none, throw a SOAP fault... + if( WS_ADDR_ANONYMOUS.equals(callbackAddress) || WS_ADDR_NONE.equals(callbackAddress) ) { + AddressingFaultsHelper.triggerOnlyNonAnonymousAddressSupportedFault(inMC, "wsa:From"); + } + } // end method checkCallbackAddress + +/* + public OMElement invoke(OMElement requestOM, javax.xml.ws.handler.MessageContext jaxwsMC) throws InvocationTargetException, AxisFault { + Set> entries = jaxwsMC.entrySet(); + Collection values = jaxwsMC.values(); + jaxwsMC.get("FRED"); + MessageContext inMC = null; + return invoke(requestOM, inMC); + } +*/ + + public OMElement invoke(OMElement requestOM, javax.xml.ws.handler.MessageContext inMC) throws InvocationTargetException, AxisFault { + String callbackAddress = null; + String callbackID = null; + + // create a message object and set the args as its body + Message msg = messageFactory.createMessage(); + Object[] args = new Object[] {requestOM}; + msg.setBody(args); + msg.setOperation(operation); + //msg.setBindingContext(inMC); + + //FIXME: can we use the Axis2 addressing support for this? +/* + SOAPHeader header = inMC.getEnvelope().getHeader(); + if (header != null) { + callbackAddress = handleCallbackAddress( header, msg ); + // Retrieve other callback-related headers + handleMessageIDHeader( header, msg ); + } // 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, inMC ); + // + from = assemblyFactory.createEndpointReference(); + Endpoint fromEndpoint = assemblyFactory.createEndpoint(); + from.setTargetEndpoint(fromEndpoint); + from.setStatus(EndpointReference.Status.WIRED_TARGET_FOUND_AND_MATCHED); + msg.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 response = endpoint.invoke(msg); + + if(response.isFault()) { + throw new InvocationTargetException((Throwable) response.getBody()); + } + return response.getBody(); + } // end method + + private static String WS_REF_PARMS = "WS_REFERENCE_PARAMETERS"; + private String handleCallbackAddress( SOAPHeader header, Message msg ) { + String callbackAddress = null; + + OMElement from = header.getFirstChildWithName(QNAME_WSA_FROM); + if( from == null ) from = header.getFirstChildWithName(QNAME_WSA_REPLYTO); + + if (from != null) { + OMElement callbackAddrElement = from.getFirstChildWithName(QNAME_WSA_ADDRESS); + if (callbackAddrElement != null) { + if (endpoint.getService().getInterfaceContract().getCallbackInterface() != null) { + callbackAddress = callbackAddrElement.getText(); + } + OMElement refParms = from.getFirstChildWithName(QNAME_WSA_REFERENCE_PARAMETERS); + 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; + OMElement messageID = header.getFirstChildWithName(QNAME_WSA_MESSAGEID); + if (messageID != null) { + String idValue = messageID.getText(); + // 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 +} -- cgit v1.2.3