From b9952cb12559ce6369890b47fea7299179bd4e43 Mon Sep 17 00:00:00 2001 From: slaws Date: Mon, 8 Feb 2010 12:37:05 +0000 Subject: Move toward having the Axis specific code in the Axis2EngineIntegration class while having the service and reference provides do more of the orchestration. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@907634 13f79535-47bb-0310-9956-ffa450edef68 --- .../binding-ws-runtime-axis2/META-INF/MANIFEST.MF | 1 + .../sca/binding/ws/axis2/Axis2BindingInvoker.java | 8 +- .../ws/axis2/Axis2BindingProviderFactory.java | 15 +- .../binding/ws/axis2/Axis2EngineIntegration.java | 443 ++++++--------------- .../ws/axis2/Axis2OneWayBindingInvoker.java | 4 +- .../ws/axis2/Axis2ReferenceBindingProvider.java | 268 ++++++++++++- .../ws/axis2/Axis2ServiceBindingProvider.java | 249 +++++++++++- .../sca/binding/ws/axis2/Axis2ServiceProvider.java | 8 +- 8 files changed, 636 insertions(+), 360 deletions(-) (limited to 'sca-java-2.x/trunk/modules/binding-ws-runtime-axis2') diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF index 22840f3cd6..6ddb93b622 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF @@ -111,6 +111,7 @@ Import-Package: com.ctc.wstx.stax, org.apache.commons.logging;resolution:=optional, org.apache.neethi, org.apache.tuscany.sca.assembly;version="2.0.0", + org.apache.tuscany.sca.assembly.xml;version="2.0.0", org.apache.tuscany.sca.binding.ws;version="2.0.0", org.apache.tuscany.sca.common.xml;version="2.0.0", org.apache.tuscany.sca.contribution.processor;version="2.0.0", diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java index 2d03b10db5..fd18997adc 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java @@ -65,7 +65,7 @@ public class Axis2BindingInvoker implements Invoker, DataExchangeSemantics { public static final QName CONVERSATION_ID_REFPARM_QN = new QName(SCA11_TUSCANY_NS, "ConversationID", TUSCANY_PREFIX); - private Axis2ServiceClient serviceClient; + private Axis2ReferenceBindingProvider bindingProvider; private QName wsdlOperationName; private Options options; private SOAPFactory soapFactory; @@ -75,12 +75,12 @@ public class Axis2BindingInvoker implements Invoker, DataExchangeSemantics { // private Axis2TokenAuthenticationPolicy axis2TokenAuthenticationPolicy = null; // private List axis2HeaderPolicies = new ArrayList(); - public Axis2BindingInvoker(Axis2ServiceClient serviceClient, + public Axis2BindingInvoker(Axis2ReferenceBindingProvider bindingProvider, QName wsdlOperationName, Options options, SOAPFactory soapFactory, WebServiceBinding wsBinding) { - this.serviceClient = serviceClient; + this.bindingProvider = bindingProvider; this.wsdlOperationName = wsdlOperationName; this.options = options; this.soapFactory = soapFactory; @@ -213,7 +213,7 @@ public class Axis2BindingInvoker implements Invoker, DataExchangeSemantics { requestMC.setEnvelope(env); // Axis2 operationClients can not be shared so create a new one for each request - final OperationClient operationClient = serviceClient.getServiceClient().createClient(wsdlOperationName); + final OperationClient operationClient = bindingProvider.getServiceClient().createClient(wsdlOperationName); operationClient.setOptions(options); Endpoint callbackEndpoint = msg.getFrom().getCallbackEndpoint(); diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java index 42e4cf83ac..b9cc93691d 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingProviderFactory.java @@ -18,6 +18,9 @@ */ package org.apache.tuscany.sca.binding.ws.axis2; +import javax.xml.namespace.QName; + +import org.apache.tuscany.sca.assembly.xml.Constants; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; @@ -38,22 +41,22 @@ import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; public class Axis2BindingProviderFactory implements BindingProviderFactory { - private FactoryExtensionPoint modelFactories; + public static final QName MTOM_INTENT = new QName(Constants.SCA11_TUSCANY_NS, "MTOM"); + + private ExtensionPointRegistry extensionPoints; private ServletHost servletHost; - private DataBindingExtensionPoint dataBindings; public Axis2BindingProviderFactory(ExtensionPointRegistry extensionPoints) { + this.extensionPoints = extensionPoints; this.servletHost = ServletHostHelper.getServletHost(extensionPoints); - modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); - dataBindings = extensionPoints.getExtensionPoint(DataBindingExtensionPoint.class); } public ReferenceBindingProvider createReferenceBindingProvider(RuntimeEndpointReference endpointReference) { - return new Axis2ReferenceBindingProvider(endpointReference, modelFactories, dataBindings); + return new Axis2ReferenceBindingProvider(extensionPoints, endpointReference); } public ServiceBindingProvider createServiceBindingProvider(RuntimeEndpoint endpoint) { - return new Axis2ServiceBindingProvider(endpoint, servletHost, modelFactories, dataBindings); + return new Axis2ServiceBindingProvider(extensionPoints, endpoint, servletHost); } public Class getModelType() { diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2EngineIntegration.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2EngineIntegration.java index 5ee93022bb..2c44fbdd84 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2EngineIntegration.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2EngineIntegration.java @@ -19,21 +19,17 @@ package org.apache.tuscany.sca.binding.ws.axis2; +import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URL; import java.security.AccessController; import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Arrays; -import java.util.HashMap; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.Vector; -import java.util.logging.Level; -import java.util.logging.Logger; import javax.wsdl.Definition; import javax.wsdl.Import; @@ -44,12 +40,11 @@ import javax.wsdl.extensions.soap.SOAPAddress; import javax.wsdl.extensions.soap12.SOAP12Address; import javax.xml.namespace.QName; -import org.apache.axiom.om.OMAbstractFactory; -import org.apache.axiom.om.OMElement; -import org.apache.axiom.om.OMFactory; import org.apache.axis2.AxisFault; import org.apache.axis2.Constants; import org.apache.axis2.addressing.AddressingConstants; +import org.apache.axis2.addressing.EndpointReference; +import org.apache.axis2.client.Options; import org.apache.axis2.context.ConfigurationContext; import org.apache.axis2.context.ConfigurationContextFactory; import org.apache.axis2.deployment.URLBasedAxisConfigurator; @@ -58,38 +53,26 @@ import org.apache.axis2.description.AxisEndpoint; import org.apache.axis2.description.AxisOperation; import org.apache.axis2.description.AxisService; import org.apache.axis2.description.Parameter; -import org.apache.axis2.description.TransportInDescription; -import org.apache.axis2.description.TransportOutDescription; import org.apache.axis2.description.WSDL11ToAxisServiceBuilder; import org.apache.axis2.description.WSDL2Constants; import org.apache.axis2.description.WSDLToAxisServiceBuilder; -import org.apache.axis2.engine.ListenerManager; import org.apache.axis2.engine.MessageReceiver; -import org.apache.axis2.transport.jms.JMSListener; -import org.apache.axis2.transport.jms.JMSSender; import org.apache.axis2.transport.local.LocalResponder; import org.apache.tuscany.sca.assembly.AbstractContract; -import org.apache.tuscany.sca.assembly.AssemblyFactory; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; -import org.apache.tuscany.sca.binding.ws.axis2.Axis2ServiceClient.URIResolverImpl; -import org.apache.tuscany.sca.binding.ws.axis2.policy.mtom.Axis2MTOMPolicyProvider; -import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory; +import org.apache.tuscany.sca.common.xml.XMLDocumentHelper; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.extensibility.ClassLoaderContext; -import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.Interface; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.interfacedef.java.JavaInterface; import org.apache.tuscany.sca.interfacedef.wsdl.WSDLDefinition; -import org.apache.tuscany.sca.invocation.MessageFactory; -import org.apache.tuscany.sca.policy.util.PolicyHelper; -import org.apache.tuscany.sca.provider.PolicyProvider; -import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeEndpoint; import org.apache.tuscany.sca.xsd.XSDefinition; import org.apache.ws.commons.schema.XmlSchema; import org.apache.ws.commons.schema.XmlSchemaExternal; +import org.apache.ws.commons.schema.resolver.URIResolver; import org.apache.xerces.jaxp.DocumentBuilderFactoryImpl; import org.oasisopen.sca.ServiceRuntimeException; import org.w3c.dom.Element; @@ -101,45 +84,7 @@ import com.ctc.wstx.stax.WstxInputFactory; public class Axis2EngineIntegration { - private static final Logger logger = Logger.getLogger(Axis2EngineIntegration.class.getName()); - - private RuntimeEndpoint endpoint; - private RuntimeComponent component; - private AbstractContract contract; - private WebServiceBinding wsBinding; - private ServletHost servletHost; - private MessageFactory messageFactory; - private FactoryExtensionPoint modelFactories; - private RuntimeAssemblyFactory assemblyFactory; - - private ConfigurationContext configContext; - - // a map of all endpoint URIs to WSDL ports for which service will be started - // - private Map urlMap = new HashMap(); - - // default provided intents - public static final String SCA_11_NS = org.apache.tuscany.sca.assembly.xml.Constants.SCA11_NS; - public static final String SCA_11_TUSCANY_NS = org.apache.tuscany.sca.assembly.xml.Constants.SCA11_TUSCANY_NS; - - // TODO - move these constants to assembly - public static final QName AUTHENTICATION_INTENT = new QName(SCA_11_NS, "authentication"); - public static final QName CONFIDENTIALITY_INTENT = new QName(SCA_11_NS, "confidentiality"); - public static final QName INTEGRITY_INTENT = new QName(SCA_11_NS, "integrity"); - public static final QName MTOM_INTENT = new QName(SCA_11_TUSCANY_NS, "MTOM"); - public static final QName SOAP_INTENT = new QName(SCA_11_NS, "SOAP"); - public static final QName SOAP11_INTENT = new QName(SCA_11_NS, "SOAP.1_1"); - public static final QName SOAP12_INTENT = new QName(SCA_11_NS, "SOAP.1_2"); - - private boolean isSOAP12Required = false; - private boolean isRampartRequired = false; - private boolean isMTOMRequired = false; - private boolean isJMSRequired = false; - - // JMS transport support - private JMSSender jmsSender; - private JMSListener jmsListener; - + //========================================================= // most of the following is related to rewriting WSDL imports // I'd like to move this but don't know where to yet. @@ -147,7 +92,6 @@ public class Axis2EngineIntegration { public static final String IMPORT_TAG = "import"; public static final String INCLUDE_TAG = "include"; - public static final QName QNAME_WSA_ADDRESS = new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.EPR_ADDRESS); public static final QName QNAME_WSA_FROM = @@ -155,8 +99,6 @@ public class Axis2EngineIntegration { public static final QName QNAME_WSA_REFERENCE_PARAMETERS = new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.EPR_REFERENCE_PARAMETERS); - private static final String DEFAULT_QUEUE_CONNECTION_FACTORY = "TuscanyQueueConnectionFactory"; - //Schema element names public static final String ELEM_SCHEMA = "schema"; @@ -172,41 +114,13 @@ public class Axis2EngineIntegration { public static final List XSD_QNAME_LIST = Arrays.asList(new QName[] {Q_ELEM_XSD_1999, Q_ELEM_XSD_2000, Q_ELEM_XSD_2001}); - //========================================================= - - /** - * Construct the service provider. This creates the base configuration for - * Axis2 but with no services deployed yet. Services will be deployed when - * this service binding provider is started - * - * @param endpoint - * @param component - * @param contract - * @param wsBinding - * @param servletHost - * @param messageFactory - * @param modelFactories + //========================================================= + + /* + * Create the whole configuration context for the Axis engine */ - public Axis2EngineIntegration(RuntimeEndpoint endpoint, - RuntimeComponent component, - AbstractContract contract, - WebServiceBinding wsBinding, - ServletHost servletHost, - MessageFactory messageFactory, - final FactoryExtensionPoint modelFactories) { - this.endpoint = endpoint; - this.component = component; - this.contract = contract; - this.wsBinding = wsBinding; - this.servletHost = servletHost; - this.messageFactory = messageFactory; - this.modelFactories = modelFactories; - this.assemblyFactory = (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class); - - // TODO - taken the Tuscany configurator out for a while - // but may need to re-introduce a simplified version if we feel - // that it's important to not deploy rampart when it's not required - + public static ConfigurationContext getAxisConfigurationContext(){ + ConfigurationContext configContext = null; // get the axis configuration context from the Tuscany axis2.xml file // Allow privileged access to read properties. Requires PropertyPermission read in // security policy. @@ -240,207 +154,27 @@ public class Axis2EngineIntegration { }); } catch (PrivilegedActionException e) { throw new ServiceRuntimeException(e.getException()); - } + } - // set the root context for this instance of Axis - configContext.setContextRoot(servletHost.getContextPath()); - - // Determine the configuration from the mayProvides intents - - isSOAP12Required = PolicyHelper.isIntentRequired(wsBinding, SOAP12_INTENT); - - // this is not correct as there may be other, custom, policies that - // require rampart. For example this is not going to pick up the case - // of external policy attachment - isRampartRequired = PolicyHelper.isIntentRequired(wsBinding, AUTHENTICATION_INTENT) || - PolicyHelper.isIntentRequired(wsBinding, CONFIDENTIALITY_INTENT) || - PolicyHelper.isIntentRequired(wsBinding, INTEGRITY_INTENT); - - // Update port addresses with runtime information, and create a - // map from endpoint URIs to WSDL ports that eliminates duplicate - // ports for the same endpoint. - // TODO - when do we think we are dealing with more than one port on the service side? - // is this an OSOA thing? - for (Object port : wsBinding.getService().getPorts().values()) { - String endpointURI = getPortAddress((Port)port); - if (!endpointURI.startsWith("jms:")) { - endpointURI = servletHost.getURLMapping(endpointURI).toString(); - } else { - isJMSRequired = true; - } - setPortAddress((Port)port, endpointURI); - urlMap.put(endpointURI, (Port)port); - } - - isMTOMRequired = PolicyHelper.isIntentRequired(wsBinding, MTOM_INTENT); - - - // Apply the configuration from any other policies - - for (PolicyProvider pp : endpoint.getPolicyProviders()) { - // we probably want to pass the whole provider in here - // so that the policy providers can get at the rampart configuration - //pp.configureBinding(configContext); - } - - // Apply the configuration from the mayProvides intents - - if (isRampartRequired){ - // TODO - do we need to go back to configurator? - } - - if (isJMSRequired){ - // TODO - do we need to o go back to configurator? - } - - if (isMTOMRequired) { - new Axis2MTOMPolicyProvider(endpoint).configureBinding(configContext); - } - - } - - /** - * Add the Tuscany services, that this binding instance represents, to the - * Axis runtime. - */ - public void start() { - try { - for (Map.Entry entry : urlMap.entrySet()) { - AxisService axisService = createAxisService(entry.getKey(), entry.getValue()); - configContext.getAxisConfiguration().addService(axisService); - } - - Axis2ServiceServlet servlet = null; - for (String endpointURL : urlMap.keySet()) { - if (endpointURL.startsWith("http://") || - endpointURL.startsWith("https://") || - endpointURL.startsWith("/")) { - if (servlet == null) { - servlet = new Axis2ServiceServlet(); - servlet.init(configContext); - } - servletHost.addServletMapping(endpointURL, servlet); - } else if (endpointURL.startsWith("jms")) { - logger.log(Level.INFO, "Axis2 JMS URL=" + endpointURL); - - jmsListener = new JMSListener(); - jmsSender = new JMSSender(); - ListenerManager listenerManager = configContext.getListenerManager(); - TransportInDescription trsIn = - configContext.getAxisConfiguration().getTransportIn(Constants.TRANSPORT_JMS); - - // get JMS transport parameters from the computed URL -// not in Axis2 1.5.1 -// Map jmsProps = JMSUtils.getProperties(endpointURL); - - // collect the parameters used to configure the JMS transport - OMFactory fac = OMAbstractFactory.getOMFactory(); - OMElement parms = fac.createOMElement(DEFAULT_QUEUE_CONNECTION_FACTORY, null); -/* - for (String key : jmsProps.keySet()) { - OMElement param = fac.createOMElement("parameter", null); - param.addAttribute("name", key, null); - param.addChild(fac.createOMText(param, jmsProps.get(key))); - parms.addChild(param); - } -*/ - Parameter queueConnectionFactory = new Parameter(DEFAULT_QUEUE_CONNECTION_FACTORY, parms); - trsIn.addParameter(queueConnectionFactory); - - trsIn.setReceiver(jmsListener); - - configContext.getAxisConfiguration().addTransportIn(trsIn); - TransportOutDescription trsOut = - configContext.getAxisConfiguration().getTransportOut(Constants.TRANSPORT_JMS); - //configContext.getAxisConfiguration().addTransportOut( trsOut ); - trsOut.setSender(jmsSender); - - if (listenerManager == null) { - listenerManager = new ListenerManager(); - listenerManager.init(configContext); - } - listenerManager.addListener(trsIn, true); - jmsSender.init(configContext, trsOut); - jmsListener.init(configContext, trsIn); - jmsListener.start(); - } - } - } catch (AxisFault e) { - throw new RuntimeException(e); - } -/* - catch (ClassNotFoundException e) { - throw new RuntimeException(e); - } catch (InstantiationException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } -*/ + return configContext; } - - - public void stop() { - if (jmsListener != null) { -// jmsListener.stop(); - jmsListener.destroy(); - } else { - for (String endpointURL : urlMap.keySet()) { - servletHost.removeServletMapping(endpointURL); - } - } - - servletHost = null; - - if (jmsSender != null) - jmsSender.stop(); - - try { - for (String endpointURL : urlMap.keySet()) { - // get the path to the service - URI uriPath = new URI(endpointURL); - String stringURIPath = uriPath.getPath(); - - /* [nash] Need a leading slash for WSDL imports to work with ?wsdl - // remove any "/" from the start of the path - if (stringURIPath.startsWith("/")) { - stringURIPath = stringURIPath.substring(1, stringURIPath.length()); - } - */ - - configContext.getAxisConfiguration().removeService(stringURIPath); - } - } catch (URISyntaxException e) { - throw new RuntimeException(e); - } catch (AxisFault e) { - throw new RuntimeException(e); - } - } - - private AxisService createAxisService(String endpointURL, Port port) throws AxisFault { - AxisService axisService; - if (wsBinding.getWSDLDocument() != null) { - axisService = createWSDLAxisService(endpointURL, port); - } else { - axisService = createJavaAxisService(endpointURL); - } - initAxisOperations(axisService); - return axisService; - } - + + //========================================================= + /** * Create an AxisService from the Java interface class of the SCA service interface */ - protected AxisService createJavaAxisService(String endpointURL) throws AxisFault { - + public static AxisService createJavaAxisService(String endpointURL, + ConfigurationContext configContext, + AbstractContract contract) throws AxisFault { AxisService axisService = new AxisService(); String path = URI.create(endpointURL).getPath(); axisService.setName(path); axisService.setServiceDescription("Tuscany configured AxisService for service: " + endpointURL); axisService.setClientSide(false); Parameter classParam = - new Parameter(Constants.SERVICE_CLASS, ((JavaInterface)contract.getInterfaceContract().getInterface()) - .getJavaClass().getName()); + new Parameter(Constants.SERVICE_CLASS, + ((JavaInterface)contract.getInterfaceContract().getInterface()).getJavaClass().getName()); axisService.addParameter(classParam); try { Utils.fillAxisService(axisService, configContext.getAxisConfiguration(), null, null); @@ -451,10 +185,14 @@ public class Axis2EngineIntegration { return axisService; } + //========================================================= + /** * Create an AxisService from the WSDL doc used by ws binding */ - protected AxisService createWSDLAxisService(String endpointURL, Port port) throws AxisFault { + public static AxisService createWSDLAxisService(String endpointURL, + Port port, + WebServiceBinding wsBinding) throws AxisFault { Definition definition = wsBinding.getWSDLDocument(); QName serviceQName = wsBinding.getService().getQName(); @@ -527,11 +265,9 @@ public class Axis2EngineIntegration { return axisService; } + /** * Workaround for https://issues.apache.org/jira/browse/AXIS2-3205 - * @param definition - * @param serviceName - * @return */ private static Definition getDefinition(Definition definition, QName serviceName) { @@ -556,9 +292,9 @@ public class Axis2EngineIntegration { } } return null; - } - - private void addSchemas(WSDLDefinition wsdlDef, AxisService axisService) { + } + + private static void addSchemas(WSDLDefinition wsdlDef, AxisService axisService) { for (XSDefinition xsDef : wsdlDef.getXmlSchemas()) { if (xsDef.getSchema() != null) { axisService.addSchema(xsDef.getSchema()); @@ -570,7 +306,7 @@ public class Axis2EngineIntegration { } } - private void updateSchemaRefs(XmlSchema parentSchema, String name) { + private static void updateSchemaRefs(XmlSchema parentSchema, String name) { for (Iterator iter = parentSchema.getIncludes().getIterator(); iter.hasNext();) { Object obj = iter.next(); if (obj instanceof XmlSchemaExternal) { @@ -584,9 +320,9 @@ public class Axis2EngineIntegration { } } } - } - - private void modifySchemaImportsAndIncludes(Definition definition, String name) { + } + + private static void modifySchemaImportsAndIncludes(Definition definition, String name) { // adjust the schema locations in types section Types types = definition.getTypes(); if (types != null) { @@ -607,7 +343,7 @@ public class Axis2EngineIntegration { } } - private void changeLocations(Element element, String name) { + private static void changeLocations(Element element, String name) { NodeList nodeList = element.getChildNodes(); for (int i = 0; i < nodeList.getLength(); i++) { String tagName = nodeList.item(i).getLocalName(); @@ -617,7 +353,7 @@ public class Axis2EngineIntegration { } } - private void processImport(Node importNode, String name) { + private static void processImport(Node importNode, String name) { NamedNodeMap nodeMap = importNode.getAttributes(); for (int i = 0; i < nodeMap.getLength(); i++) { Node attribute = nodeMap.item(i); @@ -628,12 +364,21 @@ public class Axis2EngineIntegration { } } } - } - - protected void initAxisOperations(AxisService axisService) { + } + + //========================================================= + + /* + * Create the service message receivers and the service provider that will push + * messages out onto the binding wire + */ + public static void createAxisServiceProviders(AxisService axisService, + RuntimeEndpoint endpoint, + WebServiceBinding wsBinding, + ExtensionPointRegistry extensionPoints) { for (Iterator i = axisService.getOperations(); i.hasNext();) { AxisOperation axisOp = (AxisOperation)i.next(); - Operation op = getOperation(axisOp); + Operation op = getOperation(axisOp, wsBinding); if (op != null) { if (op.isNonBlocking()) { @@ -643,7 +388,7 @@ public class Axis2EngineIntegration { } MessageReceiver msgrec = null; - Axis2ServiceProvider serviceProvider = new Axis2ServiceProvider(endpoint, wsBinding, messageFactory, modelFactories); + Axis2ServiceProvider serviceProvider = new Axis2ServiceProvider(endpoint, wsBinding, extensionPoints); if (op.isNonBlocking()) { msgrec = new Axis2ServiceInMessageReceiver(serviceProvider, op); } else { @@ -652,9 +397,9 @@ public class Axis2EngineIntegration { axisOp.setMessageReceiver(msgrec); } } - } - - protected Operation getOperation(AxisOperation axisOp) { + } + + private static Operation getOperation(AxisOperation axisOp,WebServiceBinding wsBinding) { String operationName = axisOp.getName().getLocalPart(); Interface iface = wsBinding.getBindingInterfaceContract().getInterface(); for (Operation op : iface.getOperations()) { @@ -663,12 +408,11 @@ public class Axis2EngineIntegration { } } return null; - } - + } - // Utility operations. Should these be available to the client also? + //========================================================= - static String getPortAddress(Port port) { + public static String getPortAddress(Port port) { Object ext = port.getExtensibilityElements().get(0); if (ext instanceof SOAPAddress) { return ((SOAPAddress)ext).getLocationURI(); @@ -679,7 +423,7 @@ public class Axis2EngineIntegration { return null; } - static void setPortAddress(Port port, String locationURI) { + public static void setPortAddress(Port port, String locationURI) { Object ext = port.getExtensibilityElements().get(0); if (ext instanceof SOAPAddress) { ((SOAPAddress)ext).setLocationURI(locationURI); @@ -687,5 +431,74 @@ public class Axis2EngineIntegration { if (ext instanceof SOAP12Address) { ((SOAP12Address)ext).setLocationURI(locationURI); } + } + + /** + * This method is copied from AxisService.createClientSideAxisService to + * work around http://issues.apache.org/jira/browse/WSCOMMONS-228 + * + * @param wsdlDefinition + * @param wsdlServiceName + * @param portName + * @param options + * @return + * @throws AxisFault + */ + @Deprecated + public static AxisService createClientSideAxisService(Definition definition, + QName serviceName, + String portName, + Options options) throws AxisFault { + Definition def = getDefinition(definition, serviceName); + final WSDL11ToAxisServiceBuilder serviceBuilder = new WSDL11ToAxisServiceBuilder(def, serviceName, portName); + serviceBuilder.setServerSide(false); + // [rfeng] Add a custom resolver to work around WSCOMMONS-228 + serviceBuilder.setCustomResolver(new URIResolverImpl(def)); + serviceBuilder.setBaseUri(def.getDocumentBaseURI()); + // [rfeng] + // Allow access to read properties. Requires PropertiesPermission in security policy. + AxisService axisService; + try { + axisService = AccessController.doPrivileged(new PrivilegedExceptionAction() { + public AxisService run() throws AxisFault { + return serviceBuilder.populateService(); + } + }); + } catch ( PrivilegedActionException e ) { + throw (AxisFault) e.getException(); + } + + AxisEndpoint axisEndpoint = (AxisEndpoint)axisService.getEndpoints().get(axisService.getEndpointName()); + options.setTo(new EndpointReference(axisEndpoint.getEndpointURL())); + if (axisEndpoint != null) { + options.setSoapVersionURI((String)axisEndpoint.getBinding().getProperty(WSDL2Constants.ATTR_WSOAP_VERSION)); + } + return axisService; + } + + /** + * URI resolver implementation for XML schema + */ + public static class URIResolverImpl implements URIResolver { + private Definition definition; + + public URIResolverImpl(Definition definition) { + this.definition = definition; + } + + public org.xml.sax.InputSource resolveEntity(java.lang.String targetNamespace, + java.lang.String schemaLocation, + java.lang.String baseUri) { + try { + if (baseUri == null) { + baseUri = definition.getDocumentBaseURI(); + } + URL url = new URL(new URL(baseUri), schemaLocation); + return XMLDocumentHelper.getInputSource(url); + } catch (IOException e) { + return null; + } + } } + } diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java index abf5f4008d..4a22b39ed9 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java @@ -36,13 +36,13 @@ import org.apache.tuscany.sca.invocation.Message; */ public class Axis2OneWayBindingInvoker extends Axis2BindingInvoker { - public Axis2OneWayBindingInvoker(Axis2ServiceClient serviceClient, + public Axis2OneWayBindingInvoker(Axis2ReferenceBindingProvider bindingProvider, QName wsdlOperationName, Options options, SOAPFactory soapFactory, WebServiceBinding wsBinding) { - super(serviceClient, wsdlOperationName, options, soapFactory, wsBinding); + super(bindingProvider, wsdlOperationName, options, soapFactory, wsBinding); } @Override diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java index 2aabce9937..15e4ea3435 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java @@ -18,15 +18,52 @@ */ package org.apache.tuscany.sca.binding.ws.axis2; +import java.io.IOException; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.util.Collection; +import java.util.List; + +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; +import javax.wsdl.Definition; +import javax.wsdl.Port; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.wsdl.extensions.soap12.SOAP12Address; +import javax.xml.namespace.QName; +import javax.xml.stream.FactoryConfigurationError; +import javax.xml.stream.XMLInputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.transform.dom.DOMSource; + +import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.impl.builder.StAXOMBuilder; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.EndpointReferenceHelper; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.description.AxisService; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.axis2.util.threadpool.ThreadPool; +import org.apache.commons.httpclient.HttpClient; +import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; +import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import org.apache.tuscany.sca.assembly.EndpointReference; +import org.apache.tuscany.sca.assembly.xml.Constants; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.policy.util.PolicyHelper; import org.apache.tuscany.sca.provider.ReferenceBindingProvider; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; @@ -34,17 +71,38 @@ import org.oasisopen.sca.ServiceRuntimeException; public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { + // Tuscany extensions + private ExtensionPointRegistry extensionPoints; + private FactoryExtensionPoint modelFactories; + private MessageFactory messageFactory; + + // the endpoint reference configuration that's driving this binding provider + // and some convenience data retrieved from the endpoint reference + private EndpointReference endpointReference; private RuntimeComponent component; private RuntimeComponentReference reference; private WebServiceBinding wsBinding; - private Axis2ServiceClient axisClient; + // derived policy configuration + private boolean isSOAP12Required = false; + private boolean isRampartRequired = false; + private boolean isMTOMRequired = false; + private boolean isJMSRequired = false; + + // The Axis2 configuration that the binding creates + private ConfigurationContext configContext; + private ServiceClient serviceClient; + private AxisService axisClientSideService; + - public Axis2ReferenceBindingProvider(EndpointReference endpointReference, - FactoryExtensionPoint modelFactories, - DataBindingExtensionPoint dataBindings) { + public Axis2ReferenceBindingProvider(ExtensionPointRegistry extensionPoints, + EndpointReference endpointReference) { - MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); + this.extensionPoints = extensionPoints; + this.endpointReference = endpointReference; + + this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.messageFactory = modelFactories.getFactory(MessageFactory.class); this.wsBinding = (WebServiceBinding)endpointReference.getBinding(); this.component = (RuntimeComponent)endpointReference.getComponent(); this.reference = (RuntimeComponentReference)endpointReference.getReference(); @@ -59,16 +117,87 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { if (contract.getInterface() != null) { contract.getInterface().resetDataBinding(OMElement.class.getName()); } + + isSOAP12Required = PolicyHelper.isIntentRequired(wsBinding, Constants.SOAP12_INTENT); + + isMTOMRequired = PolicyHelper.isIntentRequired(wsBinding, Axis2BindingProviderFactory.MTOM_INTENT); + + // this is not correct as there may be other, custom, policies that + // require rampart. For example this is not going to pick up the case + // of external policy attachment + isRampartRequired = PolicyHelper.isIntentRequired(wsBinding, Constants.AUTHENTICATION_INTENT) || + PolicyHelper.isIntentRequired(wsBinding, Constants.CONFIDENTIALITY_INTENT) || + PolicyHelper.isIntentRequired(wsBinding, Constants.INTEGRITY_INTENT); - axisClient = new Axis2ServiceClient(component, reference, wsBinding, messageFactory); } - + public void start() { - axisClient.start(); + configContext = Axis2EngineIntegration.getAxisConfigurationContext(); + + try { + Definition definition = wsBinding.getWSDLDocument(); + QName serviceQName = wsBinding.getService().getQName(); + Port port = wsBinding.getPort(); + if (port == null) { + // service has multiple ports, select one port to use + // TODO - it feels like there is much more to this than is + // here at the moment as need to match with the service side + // assuming that it's available + Collection ports = wsBinding.getService().getPorts().values(); + for (Port p : ports) { + // look for a SOAP 1.1 port first + if (p.getExtensibilityElements().get(0) instanceof SOAPAddress) { + port = p; + break; + } + } + if (port == null) { + // no SOAP 1.1 port available, so look for a SOAP 1.2 port + for (Port p : ports) { + if (p.getExtensibilityElements().get(0) instanceof SOAP12Address) { + port = p; + break; + } + } + } + } + + axisClientSideService = Axis2EngineIntegration.createClientSideAxisService(definition, serviceQName, port.getName(), new Options()); + + HttpClient httpClient = (HttpClient)configContext.getProperty(HTTPConstants.CACHED_HTTP_CLIENT); + if (httpClient == null) { + MultiThreadedHttpConnectionManager connectionManager = new MultiThreadedHttpConnectionManager(); + HttpConnectionManagerParams connectionManagerParams = new HttpConnectionManagerParams(); + connectionManagerParams.setDefaultMaxConnectionsPerHost(2); + connectionManagerParams.setTcpNoDelay(true); + connectionManagerParams.setStaleCheckingEnabled(true); + connectionManagerParams.setLinger(0); + connectionManager.setParams(connectionManagerParams); + httpClient = new HttpClient(connectionManager); + configContext.setThreadPool(new ThreadPool(1, 5)); + configContext.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); + configContext.setProperty(HTTPConstants.CACHED_HTTP_CLIENT, httpClient); + } + + serviceClient = new ServiceClient(configContext, axisClientSideService); + + } catch (AxisFault e) { + throw new RuntimeException(e); // TODO: better exception + } } public void stop() { - axisClient.stop(); + if (serviceClient != null) { + // close all connections that we have initiated, so that the jetty server + // can be restarted without seeing ConnectExceptions + HttpClient httpClient = + (HttpClient)serviceClient.getServiceContext().getConfigurationContext() + .getProperty(HTTPConstants.CACHED_HTTP_CLIENT); + if (httpClient != null) + ((MultiThreadedHttpConnectionManager)httpClient.getHttpConnectionManager()).shutdown(); + + serviceClient = null; + } } public InterfaceContract getBindingInterfaceContract() { @@ -80,7 +209,126 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { } public Invoker createInvoker(Operation operation) { - return axisClient.createInvoker(operation); + Options options = new Options(); + org.apache.axis2.addressing.EndpointReference epTo = getWSATOEPR(wsBinding); + if (epTo != null) { + options.setTo(epTo); + } + options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE); + + String operationName = operation.getName(); + + String soapAction = getSOAPAction(operationName); + if (soapAction != null && soapAction.length() > 1) { + options.setAction(soapAction); + } + + options.setTimeOutInMilliSeconds(30 * 1000); // 30 seconds + + // Allow privileged access to read properties. Requires PropertiesPermission read in + // security policy. + SOAPFactory soapFactory = AccessController.doPrivileged(new PrivilegedAction() { + public SOAPFactory run() { + if (isSOAP12Required) + return OMAbstractFactory.getSOAP12Factory(); + else + return OMAbstractFactory.getSOAP11Factory(); + + } + }); + QName wsdlOperationQName = new QName(operationName); + if (isMTOMRequired) + { + options.setProperty(org.apache.axis2.Constants.Configuration.ENABLE_MTOM, org.apache.axis2.Constants.VALUE_TRUE); + } + Axis2BindingInvoker invoker; + if (operation.isNonBlocking()) { + invoker = new Axis2OneWayBindingInvoker(this, wsdlOperationQName, options, soapFactory, wsBinding); + } else { + invoker = new Axis2BindingInvoker(this, wsdlOperationQName, options, soapFactory, wsBinding); + } + + return invoker; + } + + // Reference specific utility operations + + protected org.apache.axis2.addressing.EndpointReference getWSATOEPR(WebServiceBinding binding) { + org.apache.axis2.addressing.EndpointReference epr = getEPR(binding); + if (epr == null) { + epr = getPortLocationEPR(binding); + } else if (epr.getAddress() == null || epr.getAddress().length() < 1) { + org.apache.axis2.addressing.EndpointReference bindingEPR = getPortLocationEPR(binding); + if (bindingEPR != null) { + epr.setAddress(bindingEPR.getAddress()); + } + } + return epr; + } + + protected org.apache.axis2.addressing.EndpointReference getPortLocationEPR(WebServiceBinding binding) { + String ep = null; + if (binding.getPort() != null) { + List wsdlPortExtensions = binding.getPort().getExtensibilityElements(); + for (final Object extension : wsdlPortExtensions) { + if (extension instanceof SOAPAddress) { + ep = ((SOAPAddress)extension).getLocationURI(); + break; + } + if (extension instanceof SOAP12Address) { + SOAP12Address address = (SOAP12Address)extension; + ep = address.getLocationURI(); + break; + } + } + } + if(ep == null || ep.equals("")) { + ep = binding.getURI(); + } + return ep == null || "".equals(ep) ? null : new org.apache.axis2.addressing.EndpointReference(ep); } + protected org.apache.axis2.addressing.EndpointReference getEPR(WebServiceBinding wsBinding) { + if (wsBinding.getEndPointReference() == null) { + return null; + } + try { + + XMLStreamReader parser = + XMLInputFactory.newInstance().createXMLStreamReader(new DOMSource(wsBinding.getEndPointReference())); + StAXOMBuilder builder = new StAXOMBuilder(parser); + OMElement omElement = builder.getDocumentElement(); + org.apache.axis2.addressing.EndpointReference epr = EndpointReferenceHelper.fromOM(omElement); + return epr; + + } catch (IOException e) { + throw new RuntimeException(e); + } catch (XMLStreamException e) { + throw new RuntimeException(e); + } catch (FactoryConfigurationError e) { + throw new RuntimeException(e); + } + } + + protected String getSOAPAction(String operationName) { + Binding binding = wsBinding.getBinding(); + if (binding != null) { + for (Object o : binding.getBindingOperations()) { + BindingOperation bop = (BindingOperation)o; + if (bop.getName().equalsIgnoreCase(operationName)) { + for (Object o2 : bop.getExtensibilityElements()) { + if (o2 instanceof SOAPOperation) { + return ((SOAPOperation)o2).getSoapActionURI(); + } + } + } + } + } + return null; + } + + public ServiceClient getServiceClient() { + return serviceClient; + } + } diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java index da05b07d3a..63f506f179 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceBindingProvider.java @@ -18,13 +18,40 @@ */ package org.apache.tuscany.sca.binding.ws.axis2; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.wsdl.Port; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.extensions.soap12.SOAP12Address; +import javax.xml.namespace.QName; + +import org.apache.axiom.om.OMAbstractFactory; import org.apache.axiom.om.OMElement; +import org.apache.axiom.om.OMFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.description.AxisService; +import org.apache.axis2.description.Parameter; +import org.apache.axis2.description.TransportInDescription; +import org.apache.axis2.description.TransportOutDescription; +import org.apache.axis2.engine.ListenerManager; +import org.apache.axis2.transport.jms.JMSListener; +import org.apache.axis2.transport.jms.JMSSender; +import org.apache.tuscany.sca.assembly.AssemblyFactory; +import org.apache.tuscany.sca.assembly.xml.Constants; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.axis2.policy.mtom.Axis2MTOMPolicyProvider; +import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; +import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory; import org.apache.tuscany.sca.host.http.ServletHost; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.policy.util.PolicyHelper; +import org.apache.tuscany.sca.provider.PolicyProvider; import org.apache.tuscany.sca.provider.ServiceBindingProvider; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentService; @@ -32,45 +59,215 @@ import org.apache.tuscany.sca.runtime.RuntimeEndpoint; import org.oasisopen.sca.ServiceRuntimeException; public class Axis2ServiceBindingProvider implements ServiceBindingProvider { + private static final Logger logger = Logger.getLogger(Axis2ServiceBindingProvider.class.getName()); + // Tuscany extensions + private ExtensionPointRegistry extensionPoints; + private ServletHost servletHost; private RuntimeComponent component; private RuntimeComponentService service; + private MessageFactory messageFactory; + private FactoryExtensionPoint modelFactories; + private RuntimeAssemblyFactory assemblyFactory; + + // the endpoint configuration that's driving this binding provider + // and some convenience data retrieved from the endpoint + private RuntimeEndpoint endpoint; private WebServiceBinding wsBinding; + private Port wsdlPort; + private String endpointURI; + private InterfaceContract contract; - private Axis2EngineIntegration axisProvider; - - public Axis2ServiceBindingProvider(RuntimeEndpoint endpoint, - ServletHost servletHost, - FactoryExtensionPoint modelFactories, - DataBindingExtensionPoint dataBindings) { - - if (servletHost == null) { - throw new ServiceRuntimeException("No Servlet host is avaible for HTTP web services"); - } - - MessageFactory messageFactory = modelFactories.getFactory(MessageFactory.class); + // derived policy configuration + private boolean isSOAP12Required = false; + private boolean isRampartRequired = false; + private boolean isMTOMRequired = false; + private boolean isJMSRequired = false; + + // The Axis2 configuration that the binding creates + private ConfigurationContext configContext; + private JMSSender jmsSender; + private JMSListener jmsListener; + + public Axis2ServiceBindingProvider(ExtensionPointRegistry extensionPoints, + RuntimeEndpoint endpoint, + ServletHost servletHost ) { + this.extensionPoints = extensionPoints; + this.endpoint = endpoint; + this.servletHost = servletHost; + + this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.messageFactory = modelFactories.getFactory(MessageFactory.class); + this.assemblyFactory = (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class); this.wsBinding = (WebServiceBinding)endpoint.getBinding(); this.component = (RuntimeComponent)endpoint.getComponent(); this.service = (RuntimeComponentService)endpoint.getService(); - + // A WSDL document should always be present in the binding if (wsBinding.getWSDLDocument() == null) { throw new ServiceRuntimeException("No WSDL document for " + component.getName() + "/" + service.getName()); } // Set to use the Axiom data binding - InterfaceContract contract = wsBinding.getBindingInterfaceContract(); + contract = wsBinding.getBindingInterfaceContract(); contract.getInterface().resetDataBinding(OMElement.class.getName()); - axisProvider = new Axis2EngineIntegration(endpoint, component, service, wsBinding, servletHost, messageFactory, modelFactories); + configContext = Axis2EngineIntegration.getAxisConfigurationContext(); + + // set the root context for this instance of Axis + configContext.setContextRoot(servletHost.getContextPath()); + + // Determine the configuration from the bindings "mayProvides" intents + + isSOAP12Required = PolicyHelper.isIntentRequired(wsBinding, Constants.SOAP12_INTENT); + + isMTOMRequired = PolicyHelper.isIntentRequired(wsBinding, Axis2BindingProviderFactory.MTOM_INTENT); + + // this is not correct as there may be other, custom, policies that + // require rampart. For example this is not going to pick up the case + // of external policy attachment + isRampartRequired = PolicyHelper.isIntentRequired(wsBinding, Constants.AUTHENTICATION_INTENT) || + PolicyHelper.isIntentRequired(wsBinding, Constants.CONFIDENTIALITY_INTENT) || + PolicyHelper.isIntentRequired(wsBinding, Constants.INTEGRITY_INTENT); + + // Update port addresses with runtime information + // We can safely assume there is only one port here because you configure + // a binding in the following ways: + // 1/ default - one port generated = host domain : host port / structural path + // 2/ uri="absolute addr" - one port generated = host domain : uri port / uri path + // 3/ uri="relative addr" - one port generated = host domain : host port / structural path / relative path + // 4/ wsdl.binding - one port generated = host domain : host port / structural path + // 5/ wsdl.port - one port generated = host domain : port port / port path + // 6/ wsa:Address - one port generated = host domain : address port / address path + // 7/ 4 + 6 - as 6 + wsdlPort = (Port)wsBinding.getService().getPorts().values().iterator().next(); + + if (wsdlPort == null){ + throw new ServiceRuntimeException("No WSDL port for ws binding of " + component.getName() + "/" + service.getName()); + } + + endpointURI = Axis2EngineIntegration.getPortAddress(wsdlPort); + + if (!endpointURI.startsWith("jms:")) { + if (servletHost == null) { + throw new ServiceRuntimeException("No Servlet host is avaible for HTTP web services"); + } + endpointURI = servletHost.getURLMapping(endpointURI).toString(); + } else { + isJMSRequired = true; + } + Axis2EngineIntegration.setPortAddress(wsdlPort, endpointURI); + + + // Apply the configuration from any other policies + + for (PolicyProvider pp : endpoint.getPolicyProviders()) { + // we probably want to pass the whole provider in here + // so that the policy providers can get at the rampart configuration + pp.configureBinding(configContext); + } + + // Apply the configuration from the mayProvides intents + + if (isRampartRequired){ + // TODO - do we need to go back to configurator? + } + + if (isJMSRequired){ + // TODO - do we need to go back to configurator? + } + + if (isMTOMRequired) { + new Axis2MTOMPolicyProvider(endpoint).configureBinding(configContext); + } } + + private static final String DEFAULT_QUEUE_CONNECTION_FACTORY = "TuscanyQueueConnectionFactory"; public void start() { - axisProvider.start(); + try { + createAxisService(endpointURI, wsdlPort); + + if (endpointURI.startsWith("http://") || + endpointURI.startsWith("https://") || + endpointURI.startsWith("/")) { + Axis2ServiceServlet servlet = new Axis2ServiceServlet(); + servlet.init(configContext); + servletHost.addServletMapping(endpointURI, servlet); + } else if (endpointURI.startsWith("jms")) { + logger.log(Level.INFO, "Axis2 JMS URL=" + endpointURI); + + jmsListener = new JMSListener(); + jmsSender = new JMSSender(); + ListenerManager listenerManager = configContext.getListenerManager(); + TransportInDescription trsIn = + configContext.getAxisConfiguration().getTransportIn(org.apache.axis2.Constants.TRANSPORT_JMS); + + // get JMS transport parameters from the computed URL +//not in Axis2 1.5.1 +// Map jmsProps = JMSUtils.getProperties(endpointURL); + + // collect the parameters used to configure the JMS transport + OMFactory fac = OMAbstractFactory.getOMFactory(); + OMElement parms = fac.createOMElement(DEFAULT_QUEUE_CONNECTION_FACTORY, null); +/* + for (String key : jmsProps.keySet()) { + OMElement param = fac.createOMElement("parameter", null); + param.addAttribute("name", key, null); + param.addChild(fac.createOMText(param, jmsProps.get(key))); + parms.addChild(param); + } +*/ + Parameter queueConnectionFactory = new Parameter(DEFAULT_QUEUE_CONNECTION_FACTORY, parms); + trsIn.addParameter(queueConnectionFactory); + + trsIn.setReceiver(jmsListener); + + configContext.getAxisConfiguration().addTransportIn(trsIn); + TransportOutDescription trsOut = + configContext.getAxisConfiguration().getTransportOut(org.apache.axis2.Constants.TRANSPORT_JMS); + //configContext.getAxisConfiguration().addTransportOut( trsOut ); + trsOut.setSender(jmsSender); + + if (listenerManager == null) { + listenerManager = new ListenerManager(); + listenerManager.init(configContext); + } + listenerManager.addListener(trsIn, true); + jmsSender.init(configContext, trsOut); + jmsListener.init(configContext, trsIn); + jmsListener.start(); + } + } catch (AxisFault e) { + throw new RuntimeException(e); + } } public void stop() { - axisProvider.stop(); + try { + if (jmsListener != null) { + jmsListener.stop(); + jmsListener.destroy(); + } else { + servletHost.removeServletMapping(endpointURI); + } + + if (jmsSender != null) { + jmsSender.stop(); + } + + servletHost = null; + + // get the path to the service + // [nash] Need a leading slash for WSDL imports to work with ?wsdl + URI uriPath = new URI(endpointURI); + String stringURIPath = uriPath.getPath(); + configContext.getAxisConfiguration().removeService(stringURIPath); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } catch (AxisFault e) { + throw new RuntimeException(e); + } } public InterfaceContract getBindingInterfaceContract() { @@ -80,5 +277,19 @@ public class Axis2ServiceBindingProvider implements ServiceBindingProvider { public boolean supportsOneWayInvocation() { return true; } - + + // Service specific utility operations + + private void createAxisService(String endpointURL, Port port) throws AxisFault { + AxisService axisService; + if (wsBinding.getWSDLDocument() != null) { + axisService = Axis2EngineIntegration.createWSDLAxisService(endpointURL, port, wsBinding); + } else { + axisService = Axis2EngineIntegration.createJavaAxisService(endpointURL, configContext, service); + } + + Axis2EngineIntegration.createAxisServiceProviders(axisService, endpoint, wsBinding, extensionPoints); + + configContext.getAxisConfiguration().addService(axisService); + } } diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java index 45374ae150..e1ac10ad2c 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ServiceProvider.java @@ -35,6 +35,7 @@ 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.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; import org.apache.tuscany.sca.core.assembly.RuntimeAssemblyFactory; import org.apache.tuscany.sca.interfacedef.Operation; @@ -64,12 +65,11 @@ public class Axis2ServiceProvider implements Provider { public Axis2ServiceProvider(RuntimeEndpoint endpoint, WebServiceBinding wsBinding, - MessageFactory messageFactory, - FactoryExtensionPoint modelFactories) { + ExtensionPointRegistry extensionPoints) { this.endpoint = endpoint; this.wsBinding = wsBinding; - this.messageFactory = messageFactory; - this.modelFactories = modelFactories; + this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); + this.messageFactory = modelFactories.getFactory(MessageFactory.class); this.assemblyFactory = (RuntimeAssemblyFactory)modelFactories.getFactory(AssemblyFactory.class); } -- cgit v1.2.3