diff options
author | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
---|---|---|
committer | dims <dims@13f79535-47bb-0310-9956-ffa450edef68> | 2008-06-17 00:23:01 +0000 |
commit | bdd0a41aed7edf21ec2a65cfa17a86af2ef8c48a (patch) | |
tree | 38a92061c0793434c4be189f1d70c3458b6bc41d /branches/sca-java-integration/sca/extensions/axis2/binding/src/main |
Move Tuscany from Incubator to top level.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@668359 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'branches/sca-java-integration/sca/extensions/axis2/binding/src/main')
27 files changed, 4115 insertions, 0 deletions
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml new file mode 100644 index 0000000000..7c835caa5c --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/assembly/axis2.xml @@ -0,0 +1,38 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<assembly> + <id>bin</id> + <includeBaseDirectory>false</includeBaseDirectory> + <formats> + <format>zip</format> + <format>tar.gz</format> + </formats> + + <dependencySets> + <dependencySet> + <outputDirectory>extension</outputDirectory> + <includes> + <include>org.apache.tuscany.bindings:axis2</include> + </includes> + <fileMode>644</fileMode> + </dependencySet> + </dependencySets> +</assembly> + diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java new file mode 100644 index 0000000000..90f37ba5fa --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2AsyncTargetInvoker.java @@ -0,0 +1,94 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.concurrent.CountDownLatch; + +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; + +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.OperationClient; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; + +public class Axis2AsyncTargetInvoker extends Axis2TargetInvoker { + + private Axis2ReferenceCallbackTargetInvoker callbackInvoker; + + public Axis2AsyncTargetInvoker(ServiceClient serviceClient, + QName wsdlOperationName, + Options options, + SOAPFactory soapFactory, WorkContext workContext) { + super(serviceClient, wsdlOperationName, options, soapFactory, workContext); + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + throw new InvocationTargetException(new InvocationRuntimeException("Operation not supported")); + } + + private Object invokeTarget(final Object payload, LinkedList<Object> callbackRoutingChain) + throws InvocationTargetException { + try { + Object[] args = (Object[]) payload; + OperationClient operationClient = createOperationClient(args); + callbackInvoker.setCallbackRoutingChain(callbackRoutingChain); + Axis2ReferenceCallback callback = new Axis2ReferenceCallback(callbackInvoker); + operationClient.setCallback(callback); + + // FIXME Synchronize with callback thread to get return value + CountDownLatch doneSignal = new CountDownLatch(1); + callbackInvoker.setSignal(doneSignal); + + operationClient.execute(false); + + try { + doneSignal.await(); + } catch(InterruptedException e) { + e.printStackTrace(); + } + + // FIXME returning value from callback thread + Object response = callbackInvoker.getReturnPayload(); + return response; + } catch (AxisFault e) { + throw new InvocationTargetException(e); + } + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody(), msg.getCallbackRoutingChain()); + msg.setBody(resp); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public void setCallbackTargetInvoker(Axis2ReferenceCallbackTargetInvoker callbackInvoker) { + this.callbackInvoker = callbackInvoker; + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java new file mode 100755 index 0000000000..56725fdf3e --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilder.java @@ -0,0 +1,331 @@ +/* + * 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.binding.axis2; + +import java.net.URI; + +import javax.wsdl.Port; +import javax.wsdl.PortType; + +import org.apache.axiom.om.OMElement; +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.tuscany.binding.axis2.util.TuscanyAxisConfigurator; +import org.apache.tuscany.idl.wsdl.InterfaceWSDLIntrospector; +import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistry; +import org.apache.tuscany.idl.wsdl.WSDLServiceContract; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.ReferenceBinding; +import org.apache.tuscany.spi.component.ServiceBinding; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.BindingBuilderExtension; +import org.apache.tuscany.spi.host.ServletHost; +import org.apache.tuscany.spi.idl.InvalidServiceContractException; +import org.apache.tuscany.spi.model.AbstractReferenceDefinition; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.model.ServiceDefinition; +import org.apache.tuscany.spi.wire.IncompatibleServiceContractException; + +/** + * Builds a {@link org.osoa.sca.annotations.Service} or {@link org.apache.tuscany.spi.component.ReferenceBinding} configured + * with the Axis2 binding + * + * @version $Rev$ $Date$ + */ +@SuppressWarnings("deprecation") +public class Axis2BindingBuilder extends BindingBuilderExtension<WebServiceBindingDefinition> { + private static final String OM_DATA_BINDING = OMElement.class.getName(); + + // TODO: what to do about the base URI? + private static final String BASE_URI = "http://localhost:8080/"; + + private ServletHost servletHost; + + private ConfigurationContext configContext; + + private InterfaceWSDLIntrospector introspector; + + private WorkContext workContext; + + private WSDLDefinitionRegistry wsdlReg; + + public Axis2BindingBuilder() throws BuilderConfigException { + initAxis(); + } + + @Autowire(required = false) + public void setServletHost(ServletHost servletHost) { + this.servletHost = servletHost; + } + + /** + * @param introspector the introspector to set + */ + @Autowire + public void setIntrospector(InterfaceWSDLIntrospector introspector) { + this.introspector = introspector; + } + + @Autowire + public void setWorkContext(WorkContext workContext) { + this.workContext = workContext; + } + + @Autowire + public void setWSDLDefinitionRegistry(WSDLDefinitionRegistry wsdlReg) { + this.wsdlReg = wsdlReg; + } + + @SuppressWarnings("unchecked") + public ServiceBinding build( + CompositeComponent parent, + ServiceDefinition serviceDefinition, + WebServiceBindingDefinition wsBinding, DeploymentContext deploymentContext) { + + try { + // Set the default databinding + ServiceContract outboundContract = serviceDefinition.getServiceContract(); + if (outboundContract instanceof WSDLServiceContract) { + outboundContract.setDataBinding(OM_DATA_BINDING); + } + + // TODO: TUSCANY-1148, <binding.ws> with no wsdl only works with <interface.wsdl> + if (wsBinding.getWSDLDefinition() == null) { + if (outboundContract instanceof WSDLServiceContract) { + String ns = ((WSDLServiceContract)outboundContract).getPortType().getQName().getNamespaceURI(); + wsBinding.setWSDLDefinition(wsdlReg.getDefinition(ns)); + } else { + throw new IllegalStateException("<binding.ws> with no WSDL requires using <interface.wsdl>"); + } + } + + // FIXME: We need to define how the WSDL PortType is honored in the case that + // both the service.ws and interface.wsdl are in place. + // The WSDL portType from the WSDL Port decides the incoming SOAP message format + // There are also cases that interface.java is used. + + ServiceContract<?> inboundContract; + Port port = wsBinding.getWSDLPort(); + if (port == null) { + // FIXME: [rfeng] No WSDL is referenced by service.ws, we need to create one from + // the outbound service contract if it's JavaServiceContract + inboundContract = outboundContract; + } + + PortType portType = wsBinding.getWSDLPort().getBinding().getPortType(); + inboundContract = introspector.introspect(portType); + + // FIXME: + inboundContract.setInterfaceClass(serviceDefinition.getServiceContract().getInterfaceClass()); + inboundContract.setDataBinding(OM_DATA_BINDING); + inboundContract.setCallbackName(serviceDefinition.getServiceContract().getCallbackName()); + inboundContract.setInteractionScope(serviceDefinition.getServiceContract().getInteractionScope()); + try { + wireService.checkCompatibility(inboundContract, outboundContract, true); + } catch (IncompatibleServiceContractException e) { + throw new Axis2BindingBuilderRuntimeException(e); + } + + String axisServiceName; + if (wsBinding.isSpec10Compliant()) { + wsBinding.setActualURI(computeActualURI(wsBinding, BASE_URI, serviceDefinition.getTarget(), serviceDefinition.getName(), parent)); + axisServiceName = wsBinding.getActualURI().getPath(); + if (axisServiceName != null && axisServiceName.length() > 1 && axisServiceName.startsWith("/")) { + axisServiceName = axisServiceName.substring(1); + } + } else { + axisServiceName = serviceDefinition.getName(); + } + + ServiceBinding serviceBinding = + new Axis2ServiceBinding(axisServiceName, outboundContract, inboundContract, parent, wsBinding, + servletHost, configContext, workContext); + return serviceBinding; + + } catch (InvalidServiceContractException e) { + throw new Axis2BindingBuilderRuntimeException(e); + } + } + + @SuppressWarnings("unchecked") + public ReferenceBinding build( + CompositeComponent parent, + AbstractReferenceDefinition boundReferenceDefinition, + WebServiceBindingDefinition wsBinding, + DeploymentContext deploymentContext) { + + // Set the default binding + ServiceContract inboundContract = boundReferenceDefinition.getServiceContract(); + if (inboundContract instanceof WSDLServiceContract) { + inboundContract.setDataBinding(OM_DATA_BINDING); + } + + // TODO: TUSCANY-1148, <binding.ws> with no wsdl only works with <interface.wsdl> + if (wsBinding.getWSDLDefinition() == null) { + if (inboundContract instanceof WSDLServiceContract) { + String ns = ((WSDLServiceContract)inboundContract).getPortType().getQName().getNamespaceURI(); + wsBinding.setWSDLDefinition(wsdlReg.getDefinition(ns)); + } else { + throw new IllegalStateException("<binding.ws> with no WSDL requires using <interface.wsdl>"); + } + } + + // FIXME: We need to define how the WSDL PortType is honored in the case that + // both the binding.ws and interface.wsdl are in place + // The WSDL portType from the WSDL Port decides the incoming SOAP message format + + ServiceContract<?> outboundContract = inboundContract; + Port port = wsBinding.getWSDLPort(); + if (port == null) { + // FIXME: [rfeng] No WSDL is referenced by binding.ws, we need to create one from + // the inbound service contract if it's JavaServiceContract + outboundContract = inboundContract; + } + PortType portType = port.getBinding().getPortType(); + try { + outboundContract = introspector.introspect(portType); + } catch (InvalidServiceContractException e) { + new Axis2BindingBuilderRuntimeException(e); + } + + // Set the default databinding + outboundContract.setDataBinding(OM_DATA_BINDING); + //FIXME ... need to figure out how to specify scope on wsdl. + outboundContract.setInteractionScope(inboundContract.getInteractionScope()); + + try { + wireService.checkCompatibility(inboundContract, outboundContract, true); + } catch (IncompatibleServiceContractException e) { + throw new Axis2BindingBuilderRuntimeException(e); + } + + if (wsBinding.isSpec10Compliant()) { + wsBinding.setActualURI(computeActualURI(wsBinding, BASE_URI, null, boundReferenceDefinition.getName(), null)); + } + + return new Axis2ReferenceBinding(boundReferenceDefinition.getName(), parent, wsBinding, + inboundContract, outboundContract, workContext); + + } + + protected Class<WebServiceBindingDefinition> getBindingType() { + return WebServiceBindingDefinition.class; + } + + protected void initAxis() throws BuilderConfigException { + // TODO: consider having a system component wrapping the Axis2 ConfigContext + try { + this.configContext = new TuscanyAxisConfigurator().getConfigurationContext(); + } catch (AxisFault e) { + throw new BuilderConfigException(e); + } + } + + /** + * Compute the endpoint URI based on section 2.1.1 of the WS binding spec + * 1. The URIs in the endpoint(s) of the referenced WSDL, which may be relative + * 2. The URI specified by the wsa:Address element of the wsa:EndpointReference, which may be relative + * 3. The explicitly stated URI in the "uri" attribute of the binding.ws element, which may be relative, + * 4. The implicit URI as defined by in section 1.7 in the SCA Assembly spec + * If the <binding.ws> has no wsdlElement but does have a uri attribute then the uri takes precidence + * over any implicitly used WSDL. + * @param parent + */ + protected URI computeActualURI(WebServiceBindingDefinition wsBinding, String baseURI, URI componentURI, String bindingName, CompositeComponent parent) { + URI wsdlURI = null; + if (wsBinding.getServiceName() != null && wsBinding.getBindingName() == null) { + // <binding.ws> explicitly points at a wsdl port, may be a relative URI + wsdlURI = wsBinding.getPortURI(); + } + if (wsdlURI != null && wsdlURI.isAbsolute()) { + if (wsBinding.getURI() != null && (wsBinding.getServiceName() != null && wsBinding.getBindingName() == null)) { + throw new IllegalArgumentException("binding URI cannot be used with absolute WSDL endpoint URI"); + } + return URI.create(wsdlURI.toString()); + } + + // there is no wsdl port endpoint URI or that URI is relative + + URI bindingURI = null; + if (wsBinding.getURI() != null) { + bindingURI = URI.create(wsBinding.getURI()); + } + + if (bindingURI != null && bindingURI.isAbsolute()) { + if (wsdlURI != null) { + return URI.create(bindingURI + "/" + wsdlURI).normalize(); + } else { + return bindingURI; + } + } + + if (componentURI == null) { // null for references + wsdlURI = wsBinding.getPortURI(); + if (bindingURI != null) { + return URI.create(wsdlURI + "/" + bindingURI).normalize(); + } else { + return wsdlURI; + } + } + + + // TODO: TUSCANY-xxx, how to tell if component has multiple services using <binding.ws>? + // boolean singleService = (parent != null) && (((Component)parent.getChild(componentURI.toString())).getInboundWires().size() == 1); + // if (bindingURI == null && !singleService) { + + if (bindingURI == null) { + bindingURI = URI.create(bindingName); + } + + if (componentURI.isAbsolute()) { + if (bindingURI == null && wsdlURI == null) { + return componentURI; + } else if (wsdlURI == null) { + return URI.create(componentURI + "/" + bindingURI).normalize(); + } else if (bindingURI == null) { + return URI.create(componentURI + "/" + wsdlURI).normalize(); + } else { + return URI.create(componentURI + "/" + bindingURI + "/" + wsdlURI).normalize(); + } + } + + String actualURI = ""; + + if (bindingURI == null) { + actualURI = baseURI + "/" + componentURI + "/"; + } else { + actualURI = baseURI + "/" + componentURI + "/" + bindingURI + "/"; + } + + if (wsdlURI != null) { + actualURI = actualURI + wsdlURI.toString(); + } + + if (actualURI.endsWith("/")) { + actualURI = actualURI.substring(0, actualURI.length() -1); + } + + // normalize to handle any . or .. occurances + return URI.create(actualURI).normalize(); + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java new file mode 100644 index 0000000000..a5743668a4 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingBuilderRuntimeException.java @@ -0,0 +1,65 @@ +/* + * 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.binding.axis2; + + +/** + * Base class for Exceptions raised during the loading process. Loader implementations should throw a subclass of this + * to indicate the actual problem. + * + * @version $Rev$ $Date$ + */ +public class Axis2BindingBuilderRuntimeException extends Axis2BindingRunTimeException { + private static final long serialVersionUID = -7459051598906813461L; + private String resourceURI; + + public Axis2BindingBuilderRuntimeException() { + } + + public Axis2BindingBuilderRuntimeException(String message) { + super(message); + } + + public Axis2BindingBuilderRuntimeException(String message, Throwable cause) { + super(message, cause); + } + + public Axis2BindingBuilderRuntimeException(Throwable cause) { + super(cause); + } + + /** + * Returns the location of the resource that was being loaded. + * + * @return the location of the resource that was being loaded + */ + public String getResourceURI() { + return resourceURI; + } + + /** + * Sets the location of the resource that was being loaded. + * + * @param resourceURI the location of the resource that was being loaded + */ + public void setResourceURI(String resourceURI) { + this.resourceURI = resourceURI; + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java new file mode 100644 index 0000000000..cd957c2ec6 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2BindingRunTimeException.java @@ -0,0 +1,48 @@ +/* + * 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.binding.axis2; + +import org.apache.tuscany.api.TuscanyRuntimeException; + +/** + * Denotes an error creating a new object instance + * + * @version $Rev$ $Date$ + */ +public class Axis2BindingRunTimeException extends TuscanyRuntimeException { + private static final long serialVersionUID = -6423113430265944499L; + + public Axis2BindingRunTimeException() { + super(); + } + + public Axis2BindingRunTimeException(String message) { + super(message); + } + + public Axis2BindingRunTimeException(String message, Throwable cause) { + super(message, cause); + } + + public Axis2BindingRunTimeException(Throwable cause) { + super(cause); + } + +} + diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java new file mode 100644 index 0000000000..e9aefa7320 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2CallbackInvocationHandler.java @@ -0,0 +1,50 @@ +/* + * 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.binding.axis2; + +import java.util.LinkedList; +import java.util.Map; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.AbstractOutboundInvocationHandler; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.OutboundInvocationChain; +import org.apache.tuscany.spi.wire.TargetInvoker; + +public class Axis2CallbackInvocationHandler extends AbstractOutboundInvocationHandler { + + private InboundWire inboundWire; + + public Axis2CallbackInvocationHandler(InboundWire inboundWire) { + this.inboundWire = inboundWire; + } + + public Object invoke(Operation operation, Object[] args, LinkedList<Object> callbackRoutingChain) throws Throwable { + Object targetAddress = callbackRoutingChain.removeFirst(); + if (targetAddress == null) { + throw new AssertionError("Popped a null from address from stack"); + } + //TODO optimize as this is slow in local invocations + Map<Operation<?>, OutboundInvocationChain> sourceCallbackInvocationChains = + inboundWire.getSourceCallbackInvocationChains(targetAddress); + OutboundInvocationChain chain = sourceCallbackInvocationChains.get(operation); + TargetInvoker invoker = chain.getTargetInvoker(); + return invoke(chain, invoker, args, null, callbackRoutingChain); + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java new file mode 100644 index 0000000000..23d0fa56de --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2OneWayTargetInvoker.java @@ -0,0 +1,72 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.OperationClient; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; + +public class Axis2OneWayTargetInvoker extends Axis2TargetInvoker { + + protected static final OMElement RESPONSE = null; + + public Axis2OneWayTargetInvoker(ServiceClient serviceClient, + QName wsdlOperationName, + Options options, + SOAPFactory soapFactory, WorkContext workContext) { + + super(serviceClient, wsdlOperationName, options, soapFactory, workContext); + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + try { + Object[] args = (Object[]) payload; + OperationClient operationClient = createOperationClient(args); + + operationClient.execute(false); + + // REVIEW it seems ok to return null + return RESPONSE; + } catch (AxisFault e) { + throw new InvocationTargetException(e); + } catch (Throwable t) { + throw new Axis2BindingRunTimeException(t); + } + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody(), NONE); + msg.setBody(resp); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java new file mode 100755 index 0000000000..b0ee16ba3a --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceBinding.java @@ -0,0 +1,194 @@ +/* + * 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.binding.axis2; + +import java.util.Collection; +import javax.wsdl.Definition; +import javax.xml.namespace.QName; + +import static org.osoa.sca.Constants.SCA_NS; + +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.ReferenceBindingExtension; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import org.apache.axiom.om.OMAbstractFactory; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.EndpointReference; +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.tuscany.binding.axis2.util.TuscanyAxisConfigurator; +import org.apache.tuscany.binding.axis2.util.WebServiceOperationMetaData; +import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData; + +/** + * Axis2Reference uses Axis2 to invoke a remote web service + */ +public class Axis2ReferenceBinding<T> extends ReferenceBindingExtension { + private static final QName BINDING_WS = new QName(SCA_NS, "binding.ws"); + + private WebServicePortMetaData wsPortMetaData; + private ServiceClient serviceClient; + private WorkContext workContext; + + @SuppressWarnings("unchecked") + public Axis2ReferenceBinding(String theName, + CompositeComponent parent, + WebServiceBindingDefinition wsBinding, + ServiceContract contract, + ServiceContract<?> bindingServiceContract, + WorkContext workContext) { + super(theName, parent); + this.bindingServiceContract = bindingServiceContract; + this.workContext = workContext; + try { + Definition wsdlDefinition = wsBinding.getWSDLDefinition(); + if (wsBinding.isSpec10Compliant()) { + wsPortMetaData = + new WebServicePortMetaData(wsdlDefinition, wsBinding.getWSDLPort(), wsBinding.getActualURI().toString(), false); + } else { + wsPortMetaData = + new WebServicePortMetaData(wsdlDefinition, wsBinding.getWSDLPort(), wsBinding.getURI(), false); + } + serviceClient = createServiceClient(wsdlDefinition, wsPortMetaData); + } catch (AxisFault e) { + throw new Axis2BindingRunTimeException(e); + } + } + + public QName getBindingType() { + return BINDING_WS; + } + + public TargetInvoker createTargetInvoker(ServiceContract contract, Operation operation) { + Axis2TargetInvoker invoker; + try { + boolean operationHasCallback = contract.getCallbackName() != null; + if (operationHasCallback) { + // FIXME: SDODataBinding needs to pass in TypeHelper and classLoader + // as parameters. + Axis2AsyncTargetInvoker asyncInvoker = + (Axis2AsyncTargetInvoker) createOperationInvoker(serviceClient, + operation, + wsPortMetaData, + true, + false); + // FIXME: This makes the (BIG) assumption that there is only one + // callback method + // Relaxing this assumption, however, does not seem to be trivial, + // it may depend on knowledge + // of what actual callback method was invoked by the service at the + // other end + Operation callbackOperation = findCallbackOperation(); + Axis2CallbackInvocationHandler invocationHandler = + new Axis2CallbackInvocationHandler(inboundWire); + Axis2ReferenceCallbackTargetInvoker callbackInvoker = + new Axis2ReferenceCallbackTargetInvoker(callbackOperation, inboundWire, invocationHandler); + asyncInvoker.setCallbackTargetInvoker(callbackInvoker); + + invoker = asyncInvoker; + } else { + boolean isOneWay = operation.isNonBlocking(); + invoker = createOperationInvoker(serviceClient, operation, wsPortMetaData, false, isOneWay); + } + } catch (AxisFault e) { + throw new Axis2BindingRunTimeException(e); + } + return invoker; + } + + private Operation findCallbackOperation() { + ServiceContract contract = inboundWire.getServiceContract(); + Operation callbackOperation = null; + Collection callbackOperations = contract.getCallbackOperations().values(); + if (callbackOperations.size() != 1) { + throw new Axis2BindingRunTimeException("Can only handle one callback operation"); + } else { + callbackOperation = (Operation) callbackOperations.iterator().next(); + } + return callbackOperation; + } + + /** + * Create an Axis2 ServiceClient + */ + private ServiceClient createServiceClient(Definition wsdlDefinition, WebServicePortMetaData wsPortMetaData) + throws AxisFault { + + TuscanyAxisConfigurator tuscanyAxisConfigurator = new TuscanyAxisConfigurator(); + ConfigurationContext configurationContext = tuscanyAxisConfigurator.getConfigurationContext(); + QName serviceQName = wsPortMetaData.getServiceName(); + String portName = wsPortMetaData.getPortName().getLocalPart(); + AxisService axisService = + AxisService.createClientSideAxisService(wsdlDefinition, serviceQName, portName, new Options()); + return new ServiceClient(configurationContext, axisService); + } + + /** + * Create and configure an Axis2TargetInvoker for each operations + */ + private Axis2TargetInvoker createOperationInvoker(ServiceClient serviceClient, + Operation m, + WebServicePortMetaData wsPortMetaData, + boolean hasCallback, + boolean isOneWay) throws AxisFault { + SOAPFactory soapFactory = OMAbstractFactory.getSOAP11Factory(); + String portTypeNS = wsPortMetaData.getPortTypeName().getNamespaceURI(); + + String methodName = m.getName(); + + WebServiceOperationMetaData operationMetaData = wsPortMetaData.getOperationMetaData(methodName); + + Options options = new Options(); + options.setTo(new EndpointReference(wsPortMetaData.getEndpoint())); + options.setProperty(HTTPConstants.CHUNKED, Boolean.FALSE); + + String wsdlOperationName = operationMetaData.getBindingOperation().getOperation().getName(); + + String soapAction = wsPortMetaData.getOperationMetaData(wsdlOperationName).getSOAPAction(); + if (soapAction != null && soapAction.length() > 1) { + options.setAction(soapAction); + } + + options.setTimeOutInMilliSeconds(5 * 60 * 1000); + + QName wsdlOperationQName = new QName(portTypeNS, wsdlOperationName); + + Axis2TargetInvoker invoker; + if (hasCallback) { + invoker = + new Axis2AsyncTargetInvoker(serviceClient, wsdlOperationQName, options, soapFactory, workContext); + } else if (isOneWay) { + invoker = + new Axis2OneWayTargetInvoker(serviceClient, wsdlOperationQName, options, soapFactory, workContext); + } else { + invoker = new Axis2TargetInvoker(serviceClient, wsdlOperationQName, options, soapFactory, workContext); + } + + return invoker; + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java new file mode 100644 index 0000000000..ca129ca1cc --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallback.java @@ -0,0 +1,56 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.axiom.om.OMElement; +import org.apache.axis2.client.async.AsyncResult; +import org.apache.axis2.client.async.Callback; +import org.apache.axis2.context.MessageContext; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.TargetInvoker; + +public class Axis2ReferenceCallback extends Callback { + + private Axis2ReferenceCallbackTargetInvoker targetInvoker; + + public Axis2ReferenceCallback(Axis2ReferenceCallbackTargetInvoker targetInvoker) { + this.targetInvoker = targetInvoker; + } + + public void onComplete(AsyncResult result) { + MessageContext responseMC = result.getResponseMessageContext(); + OMElement responseOM = responseMC.getEnvelope().getBody().getFirstElement(); + try { + targetInvoker.invokeTarget(new Object[] {responseOM}, TargetInvoker.NONE); + } catch (InvocationTargetException e) { + // FIXME what is the appropriate exception here? + throw new InvocationRuntimeException(e); + } + } + + public void setComplete(boolean complete) { + super.setComplete(complete); + } + + public void onError(Exception e) { + throw new InvocationRuntimeException(e); + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java new file mode 100644 index 0000000000..cdc975b54e --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ReferenceCallbackTargetInvoker.java @@ -0,0 +1,114 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; +import java.util.LinkedList; +import java.util.concurrent.CountDownLatch; + +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InboundWire; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +public class Axis2ReferenceCallbackTargetInvoker implements TargetInvoker { + + private Operation operation; + private InboundWire inboundWire; + private LinkedList<Object> callbackRoutingChain; + private boolean cacheable; + Axis2CallbackInvocationHandler invocationHandler; + private CountDownLatch signal; + private Object returnPayload; + + public Axis2ReferenceCallbackTargetInvoker(Operation operation, + InboundWire inboundWire, + Axis2CallbackInvocationHandler invocationHandler) { + + this.operation = operation; + this.inboundWire = inboundWire; + this.invocationHandler = invocationHandler; + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + Object[] args; + if (payload != null && !payload.getClass().isArray()) { + args = new Object[]{payload}; + returnPayload = payload; + } else { + args = (Object[]) payload; + returnPayload = args[0]; + } + // FIXME synchronize with forward thread to return value + signal.countDown(); + try { + return invocationHandler.invoke(operation, args, callbackRoutingChain); + } catch (Throwable t) { + t.printStackTrace(); + throw new InvocationTargetException(t); + } + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody(), NONE); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setBodyWithFault(e.getCause()); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public boolean isCacheable() { + return cacheable; + } + + public void setCacheable(boolean cacheable) { + this.cacheable = cacheable; + } + + public boolean isOptimizable() { + return isCacheable(); // we only need to check if the scopes are correct + } + + public Axis2ReferenceCallbackTargetInvoker clone() throws CloneNotSupportedException { + Axis2ReferenceCallbackTargetInvoker invoker = (Axis2ReferenceCallbackTargetInvoker) super.clone(); + invoker.operation = this.operation; + invoker.inboundWire = this.inboundWire; + invoker.callbackRoutingChain = this.callbackRoutingChain; + invoker.cacheable = this.cacheable; + invoker.invocationHandler = this.invocationHandler; + return invoker; + } + + public void setCallbackRoutingChain(LinkedList<Object> callbackRoutingChain) { + this.callbackRoutingChain = callbackRoutingChain; + } + + public void setSignal(CountDownLatch signal) { + this.signal = signal; + } + + public Object getReturnPayload() { + return returnPayload; + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java new file mode 100755 index 0000000000..d7e04ca917 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceBinding.java @@ -0,0 +1,390 @@ +/* + * 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.binding.axis2; + +import static org.osoa.sca.Constants.SCA_NS; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.CountDownLatch; + +import javax.wsdl.Definition; +import javax.wsdl.Operation; +import javax.wsdl.PortType; +import javax.xml.namespace.QName; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.description.AxisOperation; +import org.apache.axis2.description.AxisService; +import org.apache.axis2.description.Parameter; +import org.apache.axis2.description.WSDL11ToAxisServiceBuilder; +import org.apache.axis2.description.WSDLToAxisServiceBuilder; +import org.apache.axis2.engine.MessageReceiver; +import org.apache.axis2.wsdl.WSDLConstants; +import org.apache.axis2.wsdl.WSDLConstants.WSDL20_2004Constants; +import org.apache.tuscany.binding.axis2.util.WebServicePortMetaData; +import org.apache.tuscany.spi.builder.BuilderConfigException; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.component.TargetInvokerCreationException; +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.extension.ServiceBindingExtension; +import org.apache.tuscany.spi.host.ServletHost; +import org.apache.tuscany.spi.model.InteractionScope; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.model.ServiceContract; +import org.apache.tuscany.spi.wire.Interceptor; +import org.apache.tuscany.spi.wire.InvocationChain; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.MessageImpl; +import org.apache.tuscany.spi.wire.TargetInvoker; +import org.osoa.sca.annotations.Destroy; + +// org.apache.tuscany.spi.model +/** + * An implementation of a {@link ServiceBindingExtension} configured with the Axis2 binding + * + * @version $Rev$ $Date$ + */ +public class Axis2ServiceBinding extends ServiceBindingExtension { + private static final QName BINDING_WS = new QName(SCA_NS, "binding.ws"); + + private ServiceContract<?> serviceContract; + + private ServletHost servletHost; + + private ConfigurationContext configContext; + + private WebServiceBindingDefinition binding; + + private Map<Object, InvocationContext> invCtxMap = new HashMap<Object, InvocationContext>(); + + private String serviceName; + + private WorkContext workContext; + + private Boolean conversational = null; + + private Set<String> seenConversations = Collections.synchronizedSet(new HashSet<String>()); + + public Axis2ServiceBinding(String theName, + ServiceContract<?> serviceContract, + ServiceContract<?> serviceBindingContract, + CompositeComponent parent, + WebServiceBindingDefinition binding, + ServletHost servletHost, + ConfigurationContext configContext, + WorkContext workContext) { + + super(theName, parent); + + this.serviceContract = serviceContract; + this.bindingServiceContract = serviceBindingContract; + this.binding = binding; + this.servletHost = servletHost; + this.configContext = configContext; + this.serviceName = theName; + this.workContext = workContext; + } + + public void start() { + super.start(); + + try { + configContext.getAxisConfiguration().addService(createAxisService(binding)); + } catch (AxisFault e) { + throw new Axis2BindingRunTimeException(e); + } + + Axis2ServiceServlet servlet = new Axis2ServiceServlet(); + servlet.init(configContext); + configContext.setContextRoot(getName()); + if (binding.isSpec10Compliant()) { + // TODO: TUSCANY-xxx, sort out what to do with system base URI etc + servletHost.registerMapping(binding.getActualURI().getPath(), servlet); + } else { + servletHost.registerMapping("/services/" + getName(), servlet); + } + } + + @Destroy + public void stop() { + if (binding.isSpec10Compliant()) { + servletHost.unregisterMapping(binding.getActualURI().getPath()); + } else { + servletHost.unregisterMapping("/services/" + getName()); + } + try { + configContext.getAxisConfiguration().removeService(getName()); + } catch (AxisFault e) { + throw new Axis2BindingRunTimeException(e); + } + super.stop(); + } + + private AxisService createAxisService(WebServiceBindingDefinition wsBinding) throws AxisFault { + Definition definition = wsBinding.getWSDLDefinition(); + WebServicePortMetaData wsdlPortInfo = + new WebServicePortMetaData(definition, wsBinding.getWSDLPort(), null, false); + + // TODO investigate if this is 20 wsdl what todo? + WSDLToAxisServiceBuilder builder = + new WSDL11ToAxisServiceBuilder(definition, wsdlPortInfo.getServiceName(), wsdlPortInfo.getPort() + .getName()); + builder.setServerSide(true); + AxisService axisService = builder.populateService(); + + axisService.setName(this.getName()); + axisService.setServiceDescription("Tuscany configured AxisService for service: '" + this.getName() + + "'"); + + // Use the existing WSDL + Parameter wsdlParam = new Parameter(WSDLConstants.WSDL_4_J_DEFINITION, null); + wsdlParam.setValue(definition); + axisService.addParameter(wsdlParam); + Parameter userWSDL = new Parameter("useOriginalwsdl", "true"); + axisService.addParameter(userWSDL); + + PortType wsdlPortType = wsdlPortInfo.getPortType(); + for (Object o : wsdlPortType.getOperations()) { + Operation wsdlOperation = (Operation) o; + String operationName = wsdlOperation.getName(); + QName operationQN = new QName(definition.getTargetNamespace(), operationName); + + org.apache.tuscany.spi.model.Operation<?> op = serviceContract.getOperations().get(operationName); + + MessageReceiver msgrec = null; + boolean opIsNonBlocking = op.isNonBlocking(); + if (serviceContract.getCallbackName() != null) { + msgrec = new Axis2ServiceInOutAsyncMessageReceiver(this, op); + } else if (opIsNonBlocking) { + msgrec = new Axis2ServiceInMessageReceiver(this, op); + } else { + msgrec = new Axis2ServiceInOutSyncMessageReceiver(this, op); + } + + AxisOperation axisOp = axisService.getOperation(operationQN); + if (opIsNonBlocking) { + axisOp.setMessageExchangePattern(WSDL20_2004Constants.MEP_URI_IN_ONLY); + } else { + axisOp.setMessageExchangePattern(WSDL20_2004Constants.MEP_URI_IN_OUT); + } + axisOp.setMessageReceiver(msgrec); + } + + return axisService; + } + + public Object invokeTarget(org.apache.tuscany.spi.model.Operation<?> op, Object[] args, Object messageId, + String conversationID) + throws InvocationTargetException { + InvocationChain chain = inboundWire.getInvocationChains().get(op); + Interceptor headInterceptor = chain.getHeadInterceptor(); + String oldConversationID = (String) workContext.getIdentifier(Scope.CONVERSATION); + if (isConversational() && conversationID != null) { + workContext.setIdentifier(Scope.CONVERSATION, conversationID); + } else { + workContext.clearIdentifier(Scope.CONVERSATION); + } + try { + if (headInterceptor == null) { + // short-circuit the dispatch and invoke the target directly + TargetInvoker targetInvoker = chain.getTargetInvoker(); + if (targetInvoker == null) { + throw new AssertionError("No target invoker [" + chain.getOperation().getName() + "]"); + } + return targetInvoker.invokeTarget(args, TargetInvoker.NONE); + } else { + + Message msg = new MessageImpl(); + msg.setTargetInvoker(chain.getTargetInvoker()); + msg.pushFromAddress(getFromAddress()); + if (messageId != null) { + msg.setMessageId(messageId); + } + msg.setBody(args); + Message resp; + + if (isConversational()) { + + + int opSeq = op.getConversationSequence(); + if (opSeq == org.apache.tuscany.spi.model.Operation.CONVERSATION_END) { + assert seenConversations + .contains(conversationID) : "End of conversation called when no conversation existed"; + msg.setConversationSequence(TargetInvoker.END); + seenConversations.remove(conversationID); //if a fault occurs does the conversation end? + //how do I know if a component called locally another opeation that ended this conversation? + + } else { + boolean ec = seenConversations.contains(conversationID); + if (ec) { + + msg.setConversationSequence(TargetInvoker.CONTINUE); + } else { + seenConversations.add(conversationID); + msg.setConversationSequence(TargetInvoker.START); + } + } + + } + // dispatch the wire down the chain and get the response + resp = headInterceptor.invoke(msg); + Object body = resp.getBody(); + if (resp.isFault()) { + throw new InvocationTargetException((Throwable) body); + } + return body; + } + } finally { + if (null != oldConversationID) { + workContext.setIdentifier(Scope.CONVERSATION, conversationID); + } else { + workContext.clearIdentifier(Scope.CONVERSATION); + } + } + } + + protected Object getFromAddress() { + return this.serviceName; + } + + /** + * Get the Method from an interface matching the WSDL operation name + */ + protected Method getMethod(Class<?> serviceInterface, String operationName) throws BuilderConfigException { + // Note: this doesn't support overloaded operations + Method[] methods = serviceInterface.getMethods(); + for (Method m : methods) { + if (m.getName().equals(operationName)) { + return m; + } + // tolerate WSDL with capatalized operation name + StringBuilder sb = new StringBuilder(operationName); + sb.setCharAt(0, Character.toLowerCase(sb.charAt(0))); + if (m.getName().equals(sb.toString())) { + return m; + } + } + throw new BuilderConfigException("no operation named " + operationName + + " found on service interface: " + + serviceInterface.getName()); + } + + public QName getBindingType() { + return BINDING_WS; + } + + public TargetInvoker createTargetInvoker(ServiceContract contract, org.apache.tuscany.spi.model.Operation operation) + throws TargetInvokerCreationException { + if (!operation.isCallback()) { + throw new UnsupportedOperationException(); + } else { + return new Axis2ServiceCallbackTargetInvoker(this); + } + } + + public void addMapping(Object msgId, InvocationContext invCtx) { + this.invCtxMap.put(msgId, invCtx); + } + + public InvocationContext retrieveMapping(Object msgId) { + return this.invCtxMap.get(msgId); + } + + public void removeMapping(Object msgId) { + this.invCtxMap.remove(msgId); + } + + /** + * @param inMC + * @return + */ + protected static String getConversationID(MessageContext inMC) { + String conversationID = null; + Iterator i = inMC.getEnvelope().getHeader() + .getChildrenWithName(new QName("http://www.w3.org/2005/08/addressing", "From")); + for (; i.hasNext();) { + Object a = i.next(); + if (a instanceof OMElement) { + OMElement ao = (OMElement) a; + for (Iterator rpI = + ao.getChildrenWithName(new QName("http://www.w3.org/2005/08/addressing", "ReferenceParameters")); + rpI.hasNext();) { + OMElement rpE = (OMElement) rpI.next(); + for ( + Iterator cidI = rpE.getChildrenWithName(WebServiceBindingDefinition.CONVERSATION_ID_REFPARM_QN); + cidI.hasNext();) { + OMElement cidE = (OMElement) cidI.next(); + conversationID = cidE.getText(); + } + } + + } + + } + return conversationID; + } + + protected class InvocationContext { + public MessageContext inMessageContext; + + public org.apache.tuscany.spi.model.Operation<?> operation; + + public SOAPFactory soapFactory; + + public CountDownLatch doneSignal; + + public InvocationContext(MessageContext messageCtx, + org.apache.tuscany.spi.model.Operation<?> operation, + SOAPFactory soapFactory, + CountDownLatch doneSignal) { + this.inMessageContext = messageCtx; + this.operation = operation; + this.soapFactory = soapFactory; + this.doneSignal = doneSignal; + } + } + + WorkContext getWorkContext() { + return workContext; + } + + boolean isConversational() { + if (conversational == null) { + conversational = serviceContract.getInteractionScope() == InteractionScope.CONVERSATIONAL; + + } + return conversational; + } + + @Override + public boolean allowsPassByReference() { + return true; + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java new file mode 100644 index 0000000000..7ec4a13669 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceCallbackTargetInvoker.java @@ -0,0 +1,120 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPEnvelope; +import org.apache.axis2.AxisFault; +import org.apache.axis2.Constants; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.engine.AxisEngine; +import org.apache.axis2.util.Utils; +import org.apache.tuscany.binding.axis2.Axis2ServiceBinding.InvocationContext; + +public class Axis2ServiceCallbackTargetInvoker implements TargetInvoker { + + private Axis2ServiceBinding service; + + protected static final OMElement RESPONSE = null; + + public Axis2ServiceCallbackTargetInvoker(Axis2ServiceBinding service) { + this.service = service; + } + + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + throw new InvocationTargetException(new InvocationRuntimeException("Operation not supported")); + } + + private Object invokeTarget(final Object payload, Object correlationId) throws InvocationTargetException { + try { + // Use current correlation id as index to retrieve inv context + InvocationContext invCtx = service.retrieveMapping(correlationId); + + MessageContext outMC = Utils.createOutMessageContext(invCtx.inMessageContext); + outMC.getOperationContext().addMessageContext(outMC); + + OMElement responseOM; + if (payload != null && !payload.getClass().isArray()) { + responseOM = (OMElement) payload; + } else { + responseOM = (OMElement) ((Object[]) payload)[0]; + } + SOAPEnvelope soapEnvelope = invCtx.soapFactory.getDefaultEnvelope(); + soapEnvelope.getBody().addChild(responseOM); + outMC.setEnvelope(soapEnvelope); + outMC.getOperationContext().setProperty(Constants.RESPONSE_WRITTEN, Constants.VALUE_TRUE); + + AxisEngine engine = + new AxisEngine( + invCtx.inMessageContext.getOperationContext().getServiceContext().getConfigurationContext()); + engine.send(outMC); + + invCtx.doneSignal.countDown(); + + service.removeMapping(correlationId); + } catch (AxisFault e) { + throw new InvocationTargetException(e); + } catch (Throwable t) { + throw new Axis2BindingRunTimeException(t); + } + + return RESPONSE; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object correlationId = msg.getCorrelationId(); + if (correlationId == null) { + throw new InvocationRuntimeException("Missing correlation id"); + } + Object resp = invokeTarget(msg.getBody(), correlationId); + msg.setBody(resp); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public Axis2ServiceCallbackTargetInvoker clone() throws CloneNotSupportedException { + try { + return (Axis2ServiceCallbackTargetInvoker) super.clone(); + } catch (CloneNotSupportedException e) { + // will not happen + return null; + } + } + + public boolean isCacheable() { + return true; + } + + public void setCacheable(boolean cacheable) { + + } + + public boolean isOptimizable() { + return false; + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java new file mode 100644 index 0000000000..53b85ea887 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInMessageReceiver.java @@ -0,0 +1,68 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; + +import org.apache.axiom.om.OMElement; +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.receivers.AbstractInMessageReceiver; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; + +public class Axis2ServiceInMessageReceiver extends AbstractInMessageReceiver { + + protected Operation<?> operation; + + private Axis2ServiceBinding axis2Service; + + public Axis2ServiceInMessageReceiver(Axis2ServiceBinding service, Operation<?> operation) { + this.axis2Service = service; + this.operation = operation; + } + + public Axis2ServiceInMessageReceiver() { + + } + + @Override + public void invokeBusinessLogic(MessageContext inMC) throws AxisFault { + try { + OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement(); + Object[] args = new Object[] {requestOM}; + String conversationID = axis2Service.isConversational() ? Axis2ServiceBinding.getConversationID(inMC) : null; + + axis2Service.invokeTarget(operation, args, null, conversationID); + + } catch (InvocationTargetException e) { + Throwable t = e.getCause(); + if (t instanceof Exception) { + throw AxisFault.makeFault((Exception)t); + } + throw new InvocationRuntimeException(e); + } catch (Throwable t) { + if (t instanceof Exception) { + throw AxisFault.makeFault((Exception)t); + } + throw new Axis2BindingRunTimeException(t); + } + + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java new file mode 100644 index 0000000000..9d7b711701 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutAsyncMessageReceiver.java @@ -0,0 +1,91 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; +import java.util.concurrent.CountDownLatch; + +import org.apache.axiom.om.OMElement; +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.receivers.AbstractMessageReceiver; +import org.apache.tuscany.binding.axis2.Axis2ServiceBinding.InvocationContext; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.MessageId; + +public class Axis2ServiceInOutAsyncMessageReceiver extends AbstractMessageReceiver { + + private Operation<?> operation; + + private Axis2ServiceBinding service; + + public Axis2ServiceInOutAsyncMessageReceiver(Axis2ServiceBinding service, + Operation operation) { + this.operation = operation; + this.service = service; + } + + public Axis2ServiceInOutAsyncMessageReceiver() { + } + + public final void receive(final MessageContext messageCtx) { + try { + Object messageId = messageCtx.getMessageID(); + if (messageId == null) { + messageId = new MessageId(); + } + + // Now use message id as index to context to be used by callback + // target invoker + CountDownLatch doneSignal = new CountDownLatch(1); + InvocationContext invCtx = + service.new InvocationContext(messageCtx, operation, getSOAPFactory(messageCtx), doneSignal); + service.addMapping(messageId, invCtx); + + invokeBusinessLogic(messageCtx, messageId); + + try { + doneSignal.await(); + } catch(InterruptedException e) { + e.printStackTrace(); + } + } catch (AxisFault e) { + // log.error(e); + } + } + + private void invokeBusinessLogic(MessageContext inMC, Object messageId) throws AxisFault { + try { + OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement(); + Object[] args = new Object[] {requestOM}; + String conversationID = service.isConversational() ? Axis2ServiceBinding.getConversationID(inMC) : null; + service.invokeTarget(operation, args, messageId, conversationID); + } catch (InvocationTargetException e) { + Throwable t = e.getCause(); + if (t instanceof Exception) { + throw AxisFault.makeFault((Exception)t); + } + throw new InvocationRuntimeException(e); + } catch (Exception e) { + throw AxisFault.makeFault(e); + } + + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java new file mode 100644 index 0000000000..8af613450d --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceInOutSyncMessageReceiver.java @@ -0,0 +1,117 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; + +import javax.xml.namespace.QName; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPEnvelope; +import org.apache.axis2.AxisFault; +import org.apache.axis2.Constants; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.receivers.AbstractInOutSyncMessageReceiver; +import org.apache.tuscany.spi.idl.ServiceFaultException; +import org.apache.tuscany.spi.model.Operation; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; + +public class Axis2ServiceInOutSyncMessageReceiver extends AbstractInOutSyncMessageReceiver { + + protected Operation<?> operation; + + private Axis2ServiceBinding axis2Service; + + public Axis2ServiceInOutSyncMessageReceiver(Axis2ServiceBinding service, Operation<?> operation) { + this.axis2Service = service; + this.operation = operation; + } + + public Axis2ServiceInOutSyncMessageReceiver() { + + } + + @Override + public void invokeBusinessLogic(MessageContext inMC, MessageContext outMC) throws AxisFault { + QName envQName = null; + try { + envQName= inMC.getEnvelope().getQName(); + OMElement requestOM = inMC.getEnvelope().getBody().getFirstElement(); + Object[] args = new Object[] {requestOM}; + + String conversationID = axis2Service.isConversational() ? Axis2ServiceBinding.getConversationID(inMC) : null; + + OMElement responseOM = (OMElement)axis2Service.invokeTarget(operation, args, null, conversationID); + + + SOAPEnvelope soapEnvelope = getSOAPFactory(inMC).getDefaultEnvelope(); + if(null != responseOM ){ + soapEnvelope.getBody().addChild(responseOM); + } + outMC.setEnvelope(soapEnvelope); + outMC.getOperationContext().setProperty(Constants.RESPONSE_WRITTEN, Constants.VALUE_TRUE); + + } catch (InvocationTargetException e) { + // e.printStackTrace(); + throw processMessageFault(envQName.getNamespaceURI(), e.getCause()); + } catch(InvocationRuntimeException e){ + // e.printStackTrace(); + throw processMessageFault(envQName.getNamespaceURI(), e.getCause()); + } catch (AxisFault e) { + // e.printStackTrace(); + throw e; + } catch (Exception e) { + // e.printStackTrace(); + throw AxisFault.makeFault(e); + } + } + + /** + * @param envQName + * @param e + * @throws AxisFault + */ + private AxisFault processMessageFault(String nsURI, Throwable t) { + + if (t instanceof ServiceFaultException) { //Business fault. + OMElement faultdetail = null; + String reason = ""; + + ServiceFaultException sfe = (ServiceFaultException)t; + reason= sfe.getMessage(); + reason = reason == null ? "" : reason; + Object finfo = sfe.getFaultInfo(); + + if (finfo instanceof OMElement) { + faultdetail = (OMElement)finfo; + + } + QName faultCode= new QName(nsURI , + org.apache.axiom.soap.SOAP12Constants.SOAP_FAULT_VALUE_SENDER); + return new AxisFault(faultCode, reason, null, null, faultdetail); + + + } else if ( t instanceof Exception) { + return AxisFault.makeFault((Exception) t); + } + + + return new AxisFault(t); + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java new file mode 100644 index 0000000000..74b79de3ed --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2ServiceServlet.java @@ -0,0 +1,211 @@ +/* + * 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.binding.axis2; + +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collections; +import java.util.Enumeration; +import java.util.Set; +import java.util.Vector; + +import javax.servlet.RequestDispatcher; +import javax.servlet.Servlet; +import javax.servlet.ServletConfig; +import javax.servlet.ServletContext; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.transport.http.AxisServlet; + +/** + * This overrides the servlet init of the AxisServlet so Tuscany can use + * a single Axis2 ConfigurationContext instance shared between AxisServlet + * instances for each SCA service with a ws binding. + * TODO: need to review if thats really what we want to be doing + */ +public class Axis2ServiceServlet extends AxisServlet { + + private static final long serialVersionUID = 1L; + + private static final ServletConfig DUMMY_CONFIG = createDummyServletConfig(); + + private boolean inited; + + public void init(ConfigurationContext configContext) { + this.configContext = configContext; + try { + super.init(DUMMY_CONFIG); + } catch (ServletException e) { + throw new RuntimeException(e); + } + } + + /** + * We've setup the Servlet by passing in a ConfigurationContext on our init method + * override this method to just return that + */ + @Override + protected ConfigurationContext initConfigContext(ServletConfig config) throws ServletException { + return this.configContext; + } + + /** + * The AxisServlet gets NPE during init without a ServletConfig so this is a mocked up one to prevent that. + */ + private static ServletConfig createDummyServletConfig() { + ServletConfig sc = new ServletConfig() { + + public String getServletName() { + return "TuscanyAxis2DummyServlet"; + } + + public ServletContext getServletContext() { + return new ServletContext() { + + public ServletContext getContext(String uripath) { + return null; + } + + public String getContextPath() { + return null; + } + + public int getMajorVersion() { + return 0; + } + + public int getMinorVersion() { + return 0; + } + + public String getMimeType(String file) { + return null; + } + + public Set getResourcePaths(String path) { + return Collections.emptySet(); + } + + public URL getResource(String path) throws MalformedURLException { + if("/".equals(path)) { + // HACK: To avoid NPE + return new URL("/axis2"); + } + return null; + } + + public InputStream getResourceAsStream(String path) { + return null; + } + + public RequestDispatcher getRequestDispatcher(String path) { + return null; + } + + public RequestDispatcher getNamedDispatcher(String arg0) { + return null; + } + + public Servlet getServlet(String arg0) throws ServletException { + return null; + } + + public Enumeration getServlets() { + return null; + } + + public Enumeration getServletNames() { + return null; + } + + public void log(String arg0) { + } + + public void log(Exception arg0, String arg1) { + } + + public void log(String arg0, Throwable arg1) { + } + + public String getRealPath(String arg0) { + return null; + } + + public String getServerInfo() { + return null; + } + + public String getInitParameter(String arg0) { + return null; + } + + public Enumeration getInitParameterNames() { + return null; + } + + public Object getAttribute(String arg0) { + return null; + } + + public Enumeration getAttributeNames() { + return null; + } + + public void setAttribute(String arg0, Object arg1) { + } + + public void removeAttribute(String arg0) { + } + + public String getServletContextName() { + return null; + } + }; + } + + public String getInitParameter(String arg0) { + return null; + } + + public Enumeration getInitParameterNames() { + return new Vector().elements(); + } + }; + return sc; + } + + @Override + protected void service(HttpServletRequest request, HttpServletResponse response) + throws ServletException, IOException { + // HACK: Get the correct context root which is not available during init() call + if (!inited) { + synchronized (configContext) { + configContext.setContextRoot(request.getContextPath()); + inited = true; + } + } + super.service(request, response); + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java new file mode 100755 index 0000000000..52768b973c --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/Axis2TargetInvoker.java @@ -0,0 +1,186 @@ +/* + * 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.binding.axis2; + +import java.lang.reflect.InvocationTargetException; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.component.WorkContext; +import org.apache.tuscany.spi.idl.ServiceFaultException; +import org.apache.tuscany.spi.model.Scope; +import org.apache.tuscany.spi.wire.InvocationRuntimeException; +import org.apache.tuscany.spi.wire.Message; +import org.apache.tuscany.spi.wire.TargetInvoker; + +import org.apache.axiom.om.OMElement; +import org.apache.axiom.soap.SOAPBody; +import org.apache.axiom.soap.SOAPEnvelope; +import org.apache.axiom.soap.SOAPFactory; +import org.apache.axiom.soap.SOAPHeader; +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.AddressingConstants; +import org.apache.axis2.addressing.EndpointReference; +import org.apache.axis2.client.OperationClient; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.wsdl.WSDLConstants; + +/** + * Axis2TargetInvoker uses an Axis2 OperationClient to invoke a remote web + * service + */ +public class Axis2TargetInvoker implements TargetInvoker { + + private QName wsdlOperationName; + + private Options options; + + private SOAPFactory soapFactory; + + private ServiceClient serviceClient; + + private WorkContext workContext; + + public Axis2TargetInvoker(ServiceClient serviceClient, + QName wsdlOperationName, + Options options, + SOAPFactory soapFactory, + WorkContext workContext) { + this.wsdlOperationName = wsdlOperationName; + this.options = options; + this.soapFactory = soapFactory; + this.serviceClient = serviceClient; + this.workContext = workContext; + } + + /** + * Invoke a WS operation + * + * @param payload + * @param sequence + * @return + * @throws InvocationTargetException + */ + public Object invokeTarget(final Object payload, final short sequence) throws InvocationTargetException { + try { + Object[] args = (Object[])payload; + OperationClient operationClient = createOperationClient(args); + + operationClient.execute(true); + + MessageContext responseMC = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); + + return responseMC.getEnvelope().getBody().getFirstElement(); + + } catch (AxisFault e) { + // convert exception to an exception independent on Axis runtime. + Throwable cause = e.getCause(); + cause = cause == null ? e : cause; + ServiceFaultException serviceFaultException = + new ServiceFaultException(e.getMessage(), e.getDetail(), cause); + OMElement detail = e.getDetail(); + if (null != detail) { + detail.getQName(); + serviceFaultException.setLogical(detail.getQName()); + } + throw new InvocationTargetException(serviceFaultException); + + } + + } + + @SuppressWarnings("deprecation") + protected OperationClient createOperationClient(Object[] args) throws AxisFault { + SOAPEnvelope env = soapFactory.getDefaultEnvelope(); + if (args != null && args.length > 0) { + SOAPBody body = env.getBody(); + for (Object bc : args) { + if (bc instanceof OMElement) { + body.addChild((OMElement)bc); + } else { + throw new IllegalArgumentException( + "Can't handle mixed payloads betweem OMElements and other types."); + } + } + } + MessageContext requestMC = new MessageContext(); + requestMC.setEnvelope(env); + // Axis2 operationClients can not be shared so create a new one for each + // request + OperationClient operationClient = serviceClient.createClient(wsdlOperationName); + + if (workContext != null) { + String conversationId = (String)workContext.getIdentifier(Scope.CONVERSATION); + if (conversationId != null && conversationId.length() != 0) { + EndpointReference fromEPR = new EndpointReference(AddressingConstants.Final.WSA_ANONYMOUS_URL); + fromEPR.addReferenceParameter(WebServiceBindingDefinition.CONVERSATION_ID_REFPARM_QN, conversationId); + options.setFrom(fromEPR); + requestMC.setFrom(fromEPR); // who knows why two ways ? + + // For now do this the brute force method. Need to figure out + // how to do axis addressing .. configure mar in flow. + SOAPEnvelope sev = requestMC.getEnvelope(); + SOAPHeader sh = sev.getHeader(); + OMElement el = + fromEPR.toOM(AddressingConstants.Final.WSA_NAMESPACE, + AddressingConstants.WSA_FROM, + AddressingConstants.WSA_DEFAULT_PREFIX); + sh.addChild(el); + } + + } + + operationClient.setOptions(options); + operationClient.addMessageContext(requestMC); + return operationClient; + } + + public Message invoke(Message msg) throws InvocationRuntimeException { + try { + Object resp = invokeTarget(msg.getBody(), NONE); + msg.setBody(resp); + } catch (Throwable e) { + msg.setBodyWithFault(e); + } + return msg; + } + + public Axis2TargetInvoker clone() throws CloneNotSupportedException { + try { + return (Axis2TargetInvoker)super.clone(); + } catch (CloneNotSupportedException e) { + // will not happen + return null; + } + } + + public boolean isCacheable() { + return true; + } + + public void setCacheable(boolean cacheable) { + + } + + public boolean isOptimizable() { + return false; + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java new file mode 100644 index 0000000000..64ccb94193 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/TuscanyDispatcher.java @@ -0,0 +1,79 @@ +/* + * 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.binding.axis2; + +import java.net.URI; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.addressing.EndpointReference; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.description.AxisService; +import org.apache.axis2.description.HandlerDescription; +import org.apache.axis2.engine.AxisConfiguration; +import org.apache.axis2.engine.RequestURIBasedDispatcher; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + */ +public class TuscanyDispatcher extends RequestURIBasedDispatcher { + + public static final String NAME = "TuscanyDispatcher"; + private static final Log log = LogFactory.getLog(RequestURIBasedDispatcher.class); + private static final boolean isDebugEnabled = log.isDebugEnabled(); + + /* + * (non-Javadoc) + * + * @see org.apache.axis2.engine.AbstractDispatcher#findService(org.apache.axis2.context.MessageContext) + */ + public AxisService findService(MessageContext messageContext) throws AxisFault { + EndpointReference toEPR = messageContext.getTo(); + + if (toEPR != null) { + if(isDebugEnabled){ + log.debug("Checking for Service using target endpoint address : " + toEPR.getAddress()); + } + + String path = URI.create(toEPR.getAddress()).getPath(); + + // remove the leading slash + if (path != null && path.length() > 1 && path.startsWith("/")) { + path = path.substring(1); + } + + ConfigurationContext configurationContext = messageContext.getConfigurationContext(); + AxisConfiguration registry = configurationContext.getAxisConfiguration(); + + return registry.getService(path); + + } else { + if(isDebugEnabled){ + log.debug("Attempted to check for Service using null target endpoint URI"); + } + return null; + } + } + + public void initDispatcher() { + init(new HandlerDescription(NAME)); + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java new file mode 100755 index 0000000000..3f59ec0130 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingDefinition.java @@ -0,0 +1,210 @@ +/* + * 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.binding.axis2; + + +import java.net.URI; +import java.net.URISyntaxException; +import java.util.List; +import java.util.Map; + +import javax.wsdl.Binding; +import javax.wsdl.Definition; +import javax.wsdl.Port; +import javax.wsdl.Service; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.xml.namespace.QName; + +import org.apache.tuscany.spi.model.BindingDefinition; +import org.osoa.sca.Constants; + +/** + * Represents a Celtix binding configuration in an assembly + * + * @version $Rev$ $Date$ + */ +public class WebServiceBindingDefinition extends BindingDefinition { + public static final QName CONVERSATION_ID_REFPARM_QN = new QName(Constants.SCA_NS,"conversationID"); + private Definition definition; + private Port port; + private Service service; + private String uri; + private String namespace; + private String serviceName; + private String portName; + private String bindingName; + private Binding binding; + private boolean spec10Compliant; // hack just to allow any existing WS scdl to still work for now + private URI actualURI; + + /** + * @deprecated pre 1.0 binding.ws spec + */ + @Deprecated + public WebServiceBindingDefinition(Definition definition, Port port, String uri, String portURI, Service service) { + this.definition = definition; + this.port = port; + this.uri = uri; + this.service = service; + } + + public WebServiceBindingDefinition(String ns, Definition definition, String serviceName, String portName, String bindingName, String uri) { + this.namespace = ns; + this.definition = definition; + this.serviceName = serviceName; + this.portName = portName; + this.bindingName = bindingName; + this.uri = uri; + this.spec10Compliant = true; + } + + public Port getWSDLPort() { + if (port == null) { + Service service = getWSDLService(); + if (portName == null) { + Map ports = service.getPorts(); + if (ports.size() != 1) { + throw new IllegalStateException("when portName is null WSDL service must have exactly one WSDL port"); + } + port = (Port)ports.values().iterator().next(); + } else { + port = service.getPort(portName); + } + } + return port; + } + + public Service getWSDLService() { + if (service == null) { + if (definition == null) { + throw new IllegalStateException("WSDL definition is null"); + } + Map services = definition.getServices(); + if (serviceName != null) { + QName serviceQN = new QName(namespace, serviceName); + for (Object o : services.values()) { + Service s = (Service) o; + if (s.getQName().equals(serviceQN)) { + service = s; + break; + } + } + if (service == null) { + throw new IllegalStateException("no service: " + serviceQN); + } + } else { + service = (Service)services.values().iterator().next(); + } + } + return service; + } + + public void setWSDLPort(Port value) { + port = value; + } + + public Definition getWSDLDefinition() { + return definition; + } + + public void setWSDLDefinition(Definition def) { + definition = def; + } + + public String getURI() { + return uri; + } + + public URI getPortURI() { + URI portURI = null; + if (definition != null) { + Port port = getWSDLPort(); + final List wsdlPortExtensions = port.getExtensibilityElements(); + for (final Object extension : wsdlPortExtensions) { + if (extension instanceof SOAPAddress) { + try { + portURI = new URI(((SOAPAddress) extension).getLocationURI()); + } catch (URISyntaxException e) { + throw new RuntimeException(e); + } + break; + } + } + } + return portURI; + } + + public void setURI(String theUri) { + this.uri = theUri; + } + + public Binding getBinding() { + if (binding == null) { + if (definition == null) { + throw new IllegalStateException("WSDL definition is null"); + } + QName bindingQN = new QName(namespace, bindingName); + this.binding = definition.getBinding(bindingQN); + if (binding == null) { + throw new IllegalStateException("no binding: " + bindingQN); + } + } + return binding; + } + + public String getWSDLNamepace() { + return namespace; + } + + public String getPortName() { + return portName; + } + + public String getServiceName() { + return serviceName; + } + + public String getBindingName() { + return bindingName; + } + + public boolean isSpec10Compliant() { + return spec10Compliant; + } + + public URI getActualURI() { + return actualURI; + } + + public void setActualURI(URI actualURI) { + this.actualURI = actualURI; + } + + public Object clone() { + WebServiceBindingDefinition clone = + new WebServiceBindingDefinition(this.namespace, + this.definition, + this.serviceName, + this.portName, + this.bindingName, + this.uri); + + return clone; + } +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java new file mode 100755 index 0000000000..15b58b4305 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/WebServiceBindingLoader.java @@ -0,0 +1,244 @@ +/* + * 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.binding.axis2; + +import static org.osoa.sca.Constants.SCA_NS; + +import java.io.IOException; +import java.util.Collection; + +import javax.wsdl.Definition; +import javax.wsdl.Port; +import javax.wsdl.Service; +import javax.wsdl.WSDLException; +import javax.xml.namespace.QName; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; + +import org.apache.tuscany.idl.wsdl.WSDLDefinitionRegistry; +import org.apache.tuscany.spi.annotation.Autowire; +import org.apache.tuscany.spi.component.CompositeComponent; +import org.apache.tuscany.spi.deployer.DeploymentContext; +import org.apache.tuscany.spi.extension.LoaderExtension; +import org.apache.tuscany.spi.loader.LoaderException; +import org.apache.tuscany.spi.loader.LoaderRegistry; +import org.apache.tuscany.spi.loader.LoaderUtil; +import org.apache.tuscany.spi.model.ModelObject; + +import org.osoa.sca.annotations.Constructor; +import org.osoa.sca.annotations.Scope; + +/** + * Parses a <code>WebServiceBindingDefinition</code> entry in an assembly XML file + * + * TODO: TUSCANY-1153 support <wsa:EndpointReference> + * + * @version $Rev$ $Date$ + */ +@Scope("COMPOSITE") +@SuppressWarnings("deprecation") +public class WebServiceBindingLoader extends LoaderExtension<WebServiceBindingDefinition> { + public static final QName BINDING_WS = new QName(SCA_NS, "binding.ws"); + + private WSDLDefinitionRegistry wsdlDefinitionRegistry; + + @Constructor( { "loaderRegistry", "wsdlDefinitionRegistry" }) + public WebServiceBindingLoader(@Autowire LoaderRegistry loaderRegistry, + @Autowire WSDLDefinitionRegistry wsdlDefinitionRegistry) { + super(loaderRegistry); + this.wsdlDefinitionRegistry = wsdlDefinitionRegistry; + } + + public QName getXMLType() { + return BINDING_WS; + } + + public WebServiceBindingDefinition load(CompositeComponent parent, ModelObject object, XMLStreamReader reader, + DeploymentContext deploymentContext) + throws XMLStreamException, LoaderException { + + String uri = reader.getAttributeValue(null, "uri"); + String wsdlElement = reader.getAttributeValue(null, "wsdlElement"); + String wsdliLocation = reader.getAttributeValue(null, "wsdlLocation"); + + // TODO: keep these old attributes for now for backward compatability + String endpoint = reader.getAttributeValue(null, "endpoint"); + String wsdlLocation = reader.getAttributeValue(null, "location"); + + // TODO: support wsa:endpointreference + + LoaderUtil.skipToEndElement(reader); + + WebServiceBindingDefinition wsBinding; + if (endpoint != null && endpoint.length() > 0) { + // TODO: support these old attributes for now for backward compatability + try { + wsBinding = createBindingOld(uri, endpoint, wsdlLocation, deploymentContext); + } catch (Exception e) { + throw new LoaderException(e); + } + } else { + wsBinding = createWSBinding(wsdlElement, wsdliLocation, uri, deploymentContext); + } + + return wsBinding; + } + + protected WebServiceBindingDefinition createWSBinding(String wsdlElement, String wsdliLocation, String uri, DeploymentContext deploymentContext) throws LoaderException { + String ns = null; + String serviceName = null; + String portName = null; + String bindingName = null; + + if (wsdlElement != null && wsdlElement.length() > 0) { + + ns = getWSDLNamespace(wsdlElement); + + String uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.service"); + if (uriValue != null) { + serviceName = uriValue; + } else { + uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.port"); + if (uriValue != null) { + int i = uriValue.lastIndexOf('/'); + if (i == -1) { + throw new IllegalArgumentException("Missing '/' seperator between service and port in wsdl.port() in wsdlElement attribute"); + } + serviceName = uriValue.substring(0, i); + portName = uriValue.substring(i+1); + } else { + uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.endpoint"); + if (uriValue != null) { + throw new IllegalArgumentException("WSDL 2.0 not supported for '#wsdl.endpoint' in wsdlElement attribute"); + } + uriValue = getWSDLElementURIValue(wsdlElement, "wsdl.binding"); + if (uriValue == null) { + throw new IllegalArgumentException("missing '#wsdl.service' or '#wsdl.port' or '#wsdl.endpoint'or '#wsdl.binding' in wsdlElement attribute"); + } + bindingName = uriValue; + } + } + } + + Definition definition = null; + if (wsdliLocation != null && wsdliLocation.length() > 0) { + try { + definition = wsdlDefinitionRegistry.loadDefinition(wsdliLocation, deploymentContext.getClassLoader()); + } catch (Exception e) { + throw new LoaderException("Exception loading WSDL", e); + } + } else if (ns != null ){ + definition = wsdlDefinitionRegistry.getDefinition(ns); + } + + WebServiceBindingDefinition wsBinding = new WebServiceBindingDefinition(ns, definition, serviceName, portName, bindingName, uri); + + return wsBinding; + } + + protected String getWSDLElementURIValue(String wsdlElement, String type) { + String value = null; + String fullType = "#" + type + "("; + int i = wsdlElement.indexOf(fullType); + if (i > -1) { + int j = wsdlElement.indexOf(')',i); + if (j < 0) { + throw new IllegalArgumentException("missing closing bracket ')' on " + fullType + " in wsdlElement attribute"); + } + value = wsdlElement.substring(i + fullType.length(), j); + } + return value; + } + + protected String getWSDLNamespace(String wsdlElement) { + String ns = null; + if (wsdlElement != null && wsdlElement.length() > 0) { + int i = wsdlElement.indexOf('#'); + if (i < 0) { + throw new IllegalArgumentException("missing '#' namespace delimiter in wsdlElement attribute"); + } + if (i == 0) { + throw new IllegalArgumentException("no namespace in wsdlElement attribute"); + } + ns = wsdlElement.substring(0, i); + } + return ns; + } + + @SuppressWarnings("unchecked") + private WebServiceBindingDefinition createBindingOld(String uri, String endpoint, String wsdlLocation, DeploymentContext deploymentContext) + throws WSDLException, IOException, LoaderException { + // Get the WSDL port namespace and name + if (endpoint != null) { + int h = endpoint.indexOf('#'); + String serviceName; + String portName; + + String namespace = endpoint.substring(0, h); + String fragment = endpoint.substring(h + 1); + if (fragment.startsWith("wsdl.endpoint(") && fragment.endsWith(")")) { + fragment = fragment.substring(14, fragment.length() - 1); + int slash = fragment.indexOf('/'); + if (slash != -1) { + serviceName = fragment.substring(0, slash); + portName = fragment.substring(slash + 1); + } else { + serviceName = null; + portName = fragment; + } + } else { + serviceName = null; + portName = fragment; + } + // FIXME need to find out how to get wsdl and what context to use --- terrible hack attack! + if (null == wsdlLocation) { + throw new Axis2BindingRunTimeException( + "Failed to determine wsdl location on binding. Try specifying 'location' attribute on binding."); + } + Definition definition = + wsdlDefinitionRegistry.loadDefinition(namespace+" "+wsdlLocation, deploymentContext.getClassLoader()); + + Port thePort = null; + Service service = null; + // Find the port with the given name + for (Service serv : (Collection<Service>) definition.getServices().values()) { + QName sqn = serv.getQName(); + if (serviceName != null && !serviceName.equals(sqn.getLocalPart())) { + continue; + } + + Port p = serv.getPort(portName); + if (p != null) { + service = serv; + thePort = p; + break; + } + } + if (thePort == null) { + throw new IllegalArgumentException("Cannot find WSDL port " + endpoint); + + } + return new WebServiceBindingDefinition(definition, thePort, uri, endpoint, service); + } + // FIXME: Find the first port? + throw new LoaderException("Web Service endpoint cannot be resolved: " + endpoint); + + } + +}
\ No newline at end of file diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java new file mode 100755 index 0000000000..c0ef46fee3 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/TuscanyAxisConfigurator.java @@ -0,0 +1,44 @@ +/* + * 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.binding.axis2.util; + +import org.apache.axis2.AxisFault; +import org.apache.axis2.context.ConfigurationContext; +import org.apache.axis2.context.ConfigurationContextFactory; +import org.apache.axis2.deployment.URLBasedAxisConfigurator; +import org.apache.axis2.engine.AxisConfigurator; + +/** + * Helps configure Axis2 from a resource in binding.axis2 instead of Axis2.xml + * <p/> TODO: Review: should there be a single global Axis + * ConfigurationContext + */ +public class TuscanyAxisConfigurator extends URLBasedAxisConfigurator implements AxisConfigurator { + + public TuscanyAxisConfigurator() throws AxisFault { + super(TuscanyAxisConfigurator.class.getResource("/org/apache/tuscany/binding/axis2/engine/config/axis2.xml"), null); + } + + public ConfigurationContext getConfigurationContext() throws AxisFault { + if (configContext == null) + configContext = ConfigurationContextFactory.createConfigurationContext(this); + return configContext; + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java new file mode 100755 index 0000000000..c5d3733d01 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServiceOperationMetaData.java @@ -0,0 +1,491 @@ +/* + * 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.binding.axis2.util; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import javax.wsdl.Binding; +import javax.wsdl.BindingInput; +import javax.wsdl.BindingOperation; +import javax.wsdl.BindingOutput; +import javax.wsdl.Input; +import javax.wsdl.Message; +import javax.wsdl.Operation; +import javax.wsdl.Output; +import javax.wsdl.Part; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.wsdl.extensions.soap.SOAPHeader; +import javax.wsdl.extensions.soap.SOAPOperation; +import javax.xml.namespace.QName; + +/** + * Metadata for a WSDL operation + */ +@SuppressWarnings({"all"}) +public class WebServiceOperationMetaData implements Serializable { + private static final long serialVersionUID = 2425306250256227724L; + + // WSDL BindingDefinition and BindingOperation + private Binding binding; + private BindingOperation bindingOperation; + // Fields to cache derived metadata + private transient Set<Part> inputHeaderParts; + private transient Set<Part> outputHeaderParts; + private transient String style; + private transient String use; + private transient String soapAction; + private transient List<Object> signature; + private String encoding; + private transient QName rpcOperationName; + + public WebServiceOperationMetaData(Binding binding, BindingOperation bindingOperation) { + this.binding = binding; + this.bindingOperation = bindingOperation; + } + + public WebServiceOperationMetaData(Binding binding, BindingOperation bindingOperation, String style, String use, + String encoding, + String soapAction) { + this.binding = binding; + this.bindingOperation = bindingOperation; + this.style = style; + this.use = use; + this.encoding = encoding; + this.soapAction = soapAction; + } + + public Set<Part> getInputHeaderParts() { + if (inputHeaderParts == null) { + // Build a set of header parts that we need to exclude + inputHeaderParts = new HashSet<Part>(); + BindingInput bindingInput = bindingOperation.getBindingInput(); + + if (bindingInput != null) { + Operation operation = bindingOperation.getOperation(); + javax.wsdl.Message message = operation.getInput().getMessage(); + List elements = bindingInput.getExtensibilityElements(); + for (Iterator i = elements.iterator(); i.hasNext();) { + Object extensibilityElement = i.next(); + Part part = getPartFromSOAPHeader(message, extensibilityElement); + if (part != null) { + inputHeaderParts.add(part); + } + } + } + } + return inputHeaderParts; + } + + public Set<Part> getOutputHeaderParts() { + if (outputHeaderParts == null) { + // Build a set of header parts that we need to exclude + outputHeaderParts = new HashSet<Part>(); + BindingOutput bindingOutput = bindingOperation.getBindingOutput(); + + if (bindingOutput != null) { + Operation operation = bindingOperation.getOperation(); + javax.wsdl.Message message = operation.getOutput().getMessage(); + List elements = bindingOutput.getExtensibilityElements(); + for (Iterator i = elements.iterator(); i.hasNext();) { + Object extensibilityElement = i.next(); + Part part = getPartFromSOAPHeader(message, extensibilityElement); + if (part != null) { + outputHeaderParts.add(part); + } + } + } + } + return outputHeaderParts; + } + + private Part getPartFromSOAPHeader(Message message, Object extensibilityElement) { + Part part = null; + if (extensibilityElement instanceof SOAPHeader) { + SOAPHeader soapHeader = (SOAPHeader) extensibilityElement; + QName msgName = soapHeader.getMessage(); + if (message.getQName().equals(msgName)) { + part = message.getPart(soapHeader.getPart()); + } + } else if (extensibilityElement instanceof SOAPHeader) { + SOAPHeader soapHeader = (SOAPHeader) extensibilityElement; + QName msgName = soapHeader.getMessage(); + if (message.getQName().equals(msgName)) { + part = message.getPart(soapHeader.getPart()); + } + } + return part; + } + + public String getStyle() { + if (style == null) { + SOAPOperation soapOperation = (SOAPOperation) WebServicePortMetaData + .getExtensibilityElement(bindingOperation.getExtensibilityElements(), + SOAPOperation.class); + if (soapOperation != null) { + style = soapOperation.getStyle(); + } + if (style == null) { + SOAPBinding soapBinding = WebServicePortMetaData + .getExtensibilityElement(binding.getExtensibilityElements(), SOAPBinding.class); + if (soapBinding != null) { + style = soapBinding.getStyle(); + } + } + if (style == null) { + style = "document"; + } + } + return style; + } + + /** + * Returns the SOAP action for the given operation. + */ + public String getSOAPAction() { + if (soapAction == null) { + final List wsdlBindingOperationExtensions = bindingOperation.getExtensibilityElements(); + final SOAPOperation soapOp = + WebServicePortMetaData.getExtensibilityElement(wsdlBindingOperationExtensions, SOAPOperation.class); + if (soapOp != null) { + soapAction = soapOp.getSoapActionURI(); + } + } + return soapAction; + } + + public QName getRPCOperationName() { + if (rpcOperationName == null) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(true); + String ns = + (soapBody != null) ? soapBody.getNamespaceURI() : binding.getPortType().getQName().getNamespaceURI(); + String name = bindingOperation.getOperation().getName(); + rpcOperationName = new QName(ns, name); + } + return rpcOperationName; + } + + private List<String> getSOAPBodyParts(boolean input) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(input); + if (soapBody != null) { + List parts = soapBody.getParts(); + if (parts != null) { + List<String> names = new ArrayList<String>(); + for (Iterator i = parts.iterator(); i.hasNext();) { + Object part = i.next(); + if (part instanceof String) { + names.add((String) part); + } else if (part instanceof Part) { + names.add(((Part) part).getName()); + } + } + return names; + } else { + return null; + } + } else { + return null; + } + } + + private javax.wsdl.extensions.soap.SOAPBody getSOAPBody(boolean input) { + List elements = null; + if (input) { + BindingInput bindingInput = bindingOperation.getBindingInput(); + if (bindingInput == null) { + return null; + } + elements = bindingInput.getExtensibilityElements(); + } else { + BindingOutput bindingOutput = bindingOperation.getBindingOutput(); + if (bindingOutput == null) { + return null; + } + elements = bindingOutput.getExtensibilityElements(); + } + javax.wsdl.extensions.soap.SOAPBody soapBody = WebServicePortMetaData.getExtensibilityElement(elements, + javax.wsdl.extensions.soap.SOAPBody.class); + return soapBody; + } + + /** + * Returns the use attribute + */ + public String getUse() { + if (use == null) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(true); + if (soapBody != null) { + use = soapBody.getUse(); + } + if (use == null) { + use = "literal"; + } + } + return use; + } + + @SuppressWarnings("unchecked") + public String getEncoding() { + if (encoding == null) { + javax.wsdl.extensions.soap.SOAPBody soapBody = getSOAPBody(true); + if (soapBody != null) { + List<String> styles = (List<String>) soapBody.getEncodingStyles(); + if (styles != null && !styles.isEmpty()) { + encoding = styles.get(0); + } + } + if (encoding == null) { + encoding = ""; + } + } + return encoding; + } + + public boolean isDocLitWrapped() { + boolean flag = getStyle().equals("document") && getUse().equals("literal"); + if (!flag) { + return false; + } + Message msg = getMessage(true); + if (msg == null) { + return false; + } + List parts = msg.getOrderedParts(null); + if (parts.size() != 1) { + return false; + } + Part part = (Part) parts.get(0); + QName element = part.getElementName(); + if (element == null) { + return false; + } + return element.getLocalPart().equals(bindingOperation.getOperation().getName()); + } + + /* + * public SOAPMediator createMediator(boolean serverMode) throws SOAPException { + * // create a new mediator for each invoke for thread-safety + * boolean rpcStyle = getStyle().equals("rpc"); boolean rpcEncoded = isEncoded(); + * + * SOAPMediator mediator = null; + * + * if (!rpcStyle) { // Document mediator = new SOAPDocumentLiteralMediatorImpl(this, serverMode); + * } else { if (!rpcEncoded) mediator = new + * SOAPRPCLiteralMediatorImpl(this, serverMode); // RPC-literal else mediator = + * new SOAPRPCEncodedMediatorImpl(this, serverMode); // RPC-encoded } + * return mediator; } + */ + + /** + * Get the operation signature from the WSDL operation + */ + public List<?> getOperationSignature() { + if (signature == null) { + signature = new ArrayList<Object>(); + + Operation operation = bindingOperation.getOperation(); + if (operation == null) { + return signature; + } + + final Input input = operation.getInput(); + if (input == null) { + return signature; + } + + String sstyle = getStyle(); + + if ("rpc".equals(sstyle)) { + Collection partNames = input.getMessage().getParts().values(); + for (Iterator i = partNames.iterator(); i.hasNext();) { + Part part = (Part) i.next(); + signature.add(part.getName()); + } + } else { + /* + * WS-I Basic Profile 1.1 4.7.6 Operation Signatures Definition: operation signature + * + * The profile defines the "operation signature" to be the fully qualified name of the child element of + * SOAP body of the SOAP input + * message described by an operation in a WSDL binding. + * + * In the case of rpc-literal binding, the operation name is used as a wrapper for the part accessors. + * In the document-literal case, designed so that they meet this requirement. + * + * An endpoint that supports multiple operations must unambiguously identify the operation being + * invoked based on the input message + * that it receives. This is only possible if all the operations specified in the wsdl:binding + * associated with an endpoint have a + * unique operation signature. + * + * R2710 The operations in a wsdl:binding in a DESCRIPTION MUST result in operation signatures that are + * different from one another. + */ + List<String> bodyParts = getSOAPBodyParts(true); + + Collection<?> parts = input.getMessage().getParts().values(); + // Exclude the parts to be transmitted in SOAP header + if (bodyParts == null) { + parts.removeAll(getInputHeaderParts()); + } + for (Iterator i = parts.iterator(); i.hasNext();) { + Part part = (Part) i.next(); + if (bodyParts == null) { + // All parts + QName elementName = part.getElementName(); + if (elementName == null) { + elementName = new QName("", part.getName()); + // TODO: [rfeng] throw new + // ServiceRuntimeException("Message part for + // document style must refer to an XSD element + // using a QName: " + part); + } + signature.add(elementName); + } else { + // "parts" in soap:body + if (bodyParts.contains(part.getName())) { + QName elementName = part.getElementName(); + if (elementName == null) { + elementName = new QName("", part.getName()); + // TODO: [rfeng] throw new + // ServiceRuntimeException("Message part for + // document style must refer to an XSD + // element using a QName: " + part); + } + signature.add(elementName); + } + + } + } + } + } + return signature; + } + + public Message getMessage(boolean isInput) { + Operation operation = bindingOperation.getOperation(); + if (operation == null) { + return null; + } + + if (isInput) { + final Input input = operation.getInput(); + return input == null ? null : input.getMessage(); + } else { + final Output output = operation.getOutput(); + return output == null ? null : output.getMessage(); + } + } + + public Part getInputPart(int index) { + Part part = null; + Message message = getMessage(true); + if (message == null) { + return part; + } + + List parts = message.getOrderedParts(null); + return (Part) parts.get(index); + + } + + public Part getOutputPart(int index) { + Part part = null; + Message message = getMessage(false); + if (message == null) { + return part; + } + + List parts = message.getOrderedParts(null); + return (Part) parts.get(index); + + } + + /** + * Get a list of indexes for each part in the SOAP body + * + * @param isInput + */ + public List<Integer> getBodyPartIndexes(boolean isInput) { + List<Integer> indexes = new ArrayList<Integer>(); + + Message message = getMessage(isInput); + if (message == null) { + return indexes; + } + + List<String> bodyParts = getSOAPBodyParts(isInput); + List parts = message.getOrderedParts(null); + Set headerParts = isInput ? getInputHeaderParts() : getOutputHeaderParts(); + + int index = 0; + for (Iterator i = parts.iterator(); i.hasNext(); index++) { + Part part = (Part) i.next(); + if (headerParts.contains(part)) { + continue; + } + if (bodyParts == null) { + // All parts + indexes.add(index); + } else { + // "parts" in soap:body + if (bodyParts.contains(part.getName())) { + indexes.add(index); + } + } + } + return indexes; + } + + /** + * Get the corresponding index for a part in the SOAP header by element name + * + * @param elementName + * @param isInput + */ + public int getHeaderPartIndex(QName elementName, boolean isInput) { + + Message message = getMessage(isInput); + if (message == null) { + return -1; + } + + List parts = message.getOrderedParts(null); + Set headerParts = isInput ? getInputHeaderParts() : getOutputHeaderParts(); + + int index = 0; + for (Iterator i = parts.iterator(); i.hasNext(); index++) { + Part part = (Part) i.next(); + // Test if the part is in header section + if (headerParts.contains(part) && elementName.equals(part.getElementName())) { + return index; + } + } + return -1; + } + + public BindingOperation getBindingOperation() { + return bindingOperation; + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java new file mode 100755 index 0000000000..a8d4f0f581 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/java/org/apache/tuscany/binding/axis2/util/WebServicePortMetaData.java @@ -0,0 +1,377 @@ +/* + * 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.binding.axis2.util; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.wsdl.Binding; +import javax.wsdl.BindingOperation; +import javax.wsdl.Definition; +import javax.wsdl.Operation; +import javax.wsdl.Port; +import javax.wsdl.PortType; +import javax.wsdl.Service; +import javax.wsdl.extensions.soap.SOAPAddress; +import javax.wsdl.extensions.soap.SOAPBinding; +import javax.xml.namespace.QName; + +import org.apache.tuscany.idl.wsdl.WSDLServiceContract; + +/** + * Metadata for a WSDL port + * + */ +public class WebServicePortMetaData { + + private Service wsdlService; + private QName wsdlServiceName; + private Port wsdlPort; + private Binding wsdlBinding; + private QName wsdlPortName; + private PortType wsdlPortType; + private QName wsdlPortTypeName; + private String endpoint; + private boolean managed; + private List<WebServiceOperationMetaData> allOperationMetaData; + private WSDLServiceContract interfaceType; + + /** + * Constructor + * + * @param wsdlDefinition + */ + public WebServicePortMetaData(Definition wsdlDefinition, Port wsdlPort, String endpoint, boolean managed) { + + // Lookup the named port + this.wsdlPort = wsdlPort; + wsdlPortName = new QName(wsdlDefinition.getTargetNamespace(), wsdlPort.getName()); + Collection services = wsdlDefinition.getServices().values(); + for (Object serviceObj : services) { + Service service = (Service) serviceObj; + if (service.getPorts().containsValue(wsdlPort)) { + wsdlService = service; + wsdlServiceName = service.getQName(); + break; + } + } + + // Save the binding + wsdlBinding = wsdlPort.getBinding(); + if (wsdlBinding == null) { + throw new IllegalArgumentException("WSDL binding cannot be found for " + wsdlPortName); + } + + // Save the portType + wsdlPortType = wsdlBinding.getPortType(); + if (wsdlPortType == null) { + throw new IllegalArgumentException("WSDL portType cannot be found for " + wsdlPortName); + } + wsdlPortTypeName = wsdlPortType.getQName(); + + // Save the endpoint + this.endpoint = endpoint; + + // Track if this endpoint is managed or not + this.managed = managed; + } + + /** + * Constructor + * + * @param serviceName + * @param portName + * @param portTypeName + * @param endpoint + */ + public WebServicePortMetaData(QName serviceName, String portName, QName portTypeName, String endpoint) { + wsdlServiceName = serviceName; + wsdlPortName = new QName(serviceName.getNamespaceURI(), portName); + wsdlPortTypeName = portTypeName; + this.endpoint = endpoint; + } + + /** + * @return Returns the wsdlPort. + */ + public javax.wsdl.Port getPort() { + return wsdlPort; + } + + /** + * @return Returns the wsdlService. + */ + public QName getServiceName() { + return wsdlServiceName; + } + + /** + * @return Returns the wsdlService. + */ + public javax.wsdl.Service getService() { + return wsdlService; + } + + /** + * @return Returns the wsdlPortType. + */ + public PortType getPortType() { + return wsdlPortType; + } + + /** + * @return Returns the wsdlPortType. + */ + public QName getPortTypeName() { + return wsdlPortTypeName; + } + + /** + * @return Returns the wsdlBinding. + */ + public Binding getBinding() { + return wsdlBinding; + } + + /** + * @return Returns the wsdlPortName. + */ + public QName getPortName() { + return wsdlPortName; + } + + /** + * Returns the endpoint of a given port. + */ + public String getEndpoint() { + + // Return the specified endpoint + if (endpoint != null) { + return endpoint; + } + + // Find the target endpoint on the port + if (wsdlPort != null) { + final List wsdlPortExtensions = wsdlPort.getExtensibilityElements(); + for (final Object extension : wsdlPortExtensions) { + if (extension instanceof SOAPAddress) { + return ((SOAPAddress) extension).getLocationURI(); + } + } + } + + return null; + } + + /** + * Returns the SOAP binding style. + */ + public String getStyle() { + + // Find the binding style + String style = null; + if (wsdlBinding != null) { + final List wsdlBindingExtensions = wsdlBinding.getExtensibilityElements(); + SOAPBinding soapBinding = getExtensibilityElement(wsdlBindingExtensions, SOAPBinding.class); + if (soapBinding != null) { + style = soapBinding.getStyle(); + } + } + + // Default to document + return (style == null) ? "document" : style; + } + + /** + * Returns the use attribute + */ + public String getUse() { + List<WebServiceOperationMetaData> list = getAllOperationMetaData(); + return list.get(0).getUse(); + } + + /** + * Returns the encoding attribute + */ + public String getEncoding() { + List<WebServiceOperationMetaData> list = getAllOperationMetaData(); + return list.get(0).getEncoding(); + } + + /** + * @return Returns true if this is a managed web service. + */ + public boolean isManaged() { + return managed; + } + + /** + * Returns the first extensibility element of the given type. + * + * @param elements + * @param type + */ + public static <T> T getExtensibilityElement(List elements, Class<T> type) { + for (Object element : elements) { + if (type.isInstance(element)) { + return type.cast(element); + } + } + return null; + } + + /** + * Returns the extensibility elements of the given type. + * + * @param elements + * @param type + * @return List + */ + public static <T> List<T> getExtensibilityElements(List elements, Class<T> type) { + List<T> result = new ArrayList<T>(); + for (Object element : elements) { + if (type.isInstance(element)) { + result.add(type.cast(element)); + } + } + return result; + } + + /** + * Get the operation signature from the SOAP Body + * + * @return A list of QNames + */ + // public static List getOperationSignature(javax.xml.soap.SOAPBody body) { + // List signature = new ArrayList(); + // for (Iterator i = body.getChildElements(); i.hasNext();) { + // Object child = i.next(); + // if (child instanceof SOAPBodyElement) { + // Name name = ((SOAPBodyElement) child).getElementName(); + // QName qname = new QName(name.getURI(), name.getLocalName(), name.getPrefix()); + // signature.add(qname); + // } + // } + // return signature; + // } + // public static List getRPCOperationSignature(javax.xml.soap.SOAPBody body) { + // List signature = new ArrayList(); + // for (Iterator i = body.getChildElements(); i.hasNext();) { + // Object child = i.next(); + // if (child instanceof SOAPBodyElement) { + // SOAPBodyElement op = ((SOAPBodyElement) child); + // for (Iterator j = op.getChildElements(); j.hasNext();) { + // Object part = i.next(); + // if (part instanceof SOAPElement) { + // SOAPElement p = (SOAPElement) part; + // signature.add(p.getLocalName()); + // } + // } + // } + // } + // return signature; + // } + // public WebServiceOperationMetaData getOperationMetaData(javax.xml.soap.SOAPBody body) { + // List s1 = getOperationSignature(body); + // // List rpcParts = getRPCOperationSignature(body); + // for (Iterator it = getAllOperationMetaData().iterator(); it.hasNext();) { + // WebServiceOperationMetaData descriptor = (WebServiceOperationMetaData) it.next(); + // + // String style = descriptor.getStyle(); + // + // if (style.equals("document")) { + // List s2 = descriptor.getOperationSignature(); + // if (s1.equals(s2)) + // return descriptor; + // } else { + // QName op1 = (QName) s1.get(0); + // QName op2 = descriptor.getRPCOperationName(); + // if (op1.equals(op2)) { + // /* + // * // FIXME: [rfeng] We don't support method overloading + // * List partNames = getOperationSignature(binding, + // * bindingOperation); if (rpcParts.equals(partNames)) + // */ + // return descriptor; + // } + // } + // } + // return null; + // } + public List<WebServiceOperationMetaData> getAllOperationMetaData() { + if (allOperationMetaData == null) { + allOperationMetaData = new ArrayList<WebServiceOperationMetaData>(); + for (Iterator it = wsdlBinding.getBindingOperations().iterator(); it.hasNext();) { + final BindingOperation bindingOperation = (BindingOperation) it.next(); + if (bindingOperation.getOperation() != null) { + allOperationMetaData.add(new WebServiceOperationMetaData(wsdlBinding, bindingOperation)); + } + } + } + return allOperationMetaData; + } + + public WebServiceOperationMetaData getOperationMetaData(String operationName) { + StringBuilder sb = new StringBuilder(operationName); + sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); + String capatalizedOpName = sb.toString(); + + for (WebServiceOperationMetaData webServiceOperationMetaData : getAllOperationMetaData()) { + WebServiceOperationMetaData descriptor = (WebServiceOperationMetaData) webServiceOperationMetaData; + String opName = descriptor.getBindingOperation().getOperation().getName(); + + if (opName.equals(operationName) || opName.equals(capatalizedOpName)) { + return descriptor; + } + } + return null; + } + + /** + * Returns the WSDL service contract + * + * @return WSDLServiceContract + */ + public WSDLServiceContract getInterfaceType() { + return interfaceType; + } + + /** + * Get the WSDL operation name for a Java method name + */ + public String getWSDLOperationName(String methodName) { + StringBuilder sb = new StringBuilder(methodName); + sb.setCharAt(0, Character.toUpperCase(sb.charAt(0))); + String capatalizedOpName = sb.toString(); + for (Object o : wsdlPortType.getOperations()) { + Operation operation = (Operation) o; + String wsdlOpName = operation.getName(); + if (wsdlOpName.equals(methodName)) { + return wsdlOpName; + } + if (wsdlOpName.equals(capatalizedOpName)) { + return wsdlOpName; + } + } + return null; + } + +} diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl new file mode 100644 index 0000000000..ee1b8d9e81 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/binding.axis2.scdl @@ -0,0 +1,48 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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.
+-->
+<!-- Axis2 based WebService binding extension -->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT"
+ name="org.apache.tuscany.binding.axis2.include">
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.extensions.axis2</group>
+ <name>tuscany-axis2</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT">
+ <group>org.apache.tuscany.sca.extensions.axis2</group>
+ <name>databinding-axiom</name>
+ <version>0.1-integration-incubating-SNAPSHOT</version>
+ </dependency>
+
+ <component name="webservice.bindingLoader">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.WebServiceBindingLoader" />
+ </component>
+
+ <component name="webservice.axis2.bindingBuilder">
+ <system:implementation.system class="org.apache.tuscany.binding.axis2.Axis2BindingBuilder" />
+ </component>
+
+ <!-- A workaround to handle inter-extension dependencies -->
+ <include name="idl.wsdl" scdlResource="META-INF/sca/idl.wsdl.scdl" />
+ <include name="databinding.axiom" scdlResource="META-INF/sca/databinding.axiom.scdl" />
+
+</composite>
diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl new file mode 100644 index 0000000000..fd5c2f5baa --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/default.scdl @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<!-- Axis2 based WebService binding extension --> +<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" + xmlns:system="http://tuscany.apache.org/xmlns/system/1.0-SNAPSHOT" + name="org.apache.tuscany.binding.axis2.WebServiceBinding"> + + <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT"> + <group>org.apache.tuscany.sca.extensions.axis2</group> + <name>tuscany-axis2</name> + <version>0.1-integration-incubating-SNAPSHOT</version> + </dependency> + + <dependency xmlns="http://tuscany.apache.org/xmlns/1.0-SNAPSHOT"> + <group>org.apache.tuscany.sca.extensions.axis2</group> + <name>databinding-axiom</name> + <version>0.1-integration-incubating-SNAPSHOT</version> + </dependency> + + <component name="webservice.bindingLoader"> + <system:implementation.system class="org.apache.tuscany.binding.axis2.WebServiceBindingLoader"/> + </component> + + <component name="webservice.axis2.bindingBuilder"> + <system:implementation.system class="org.apache.tuscany.binding.axis2.Axis2BindingBuilder"/> + </component> + + <!-- A workaround to handle inter-extension dependencies --> + <include name="idl.wsdl" scdlResource="META-INF/sca/idl.wsdl.scdl"/> + <include name="databinding.axiom" scdlResource="META-INF/sca/databinding.axiom.scdl"/> + +</composite> diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite new file mode 100644 index 0000000000..10306d8968 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/META-INF/sca/extension.composite @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ * 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 peaxis2ssions and limitations
+ * under the License.
+-->
+<composite xmlns="http://www.osoa.org/xmlns/sca/1.0" name="org.apache.tuscany.binding.axis2">
+ <include name="org.apache.tuscany.binding.axis2.include" scdlLocation="binding.axis2.scdl" />
+</composite>
\ No newline at end of file diff --git a/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml new file mode 100755 index 0000000000..e4f6d699f9 --- /dev/null +++ b/branches/sca-java-integration/sca/extensions/axis2/binding/src/main/resources/org/apache/tuscany/binding/axis2/engine/config/axis2.xml @@ -0,0 +1,306 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + * 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. +--> +<axisconfig name="AxisJava2.0"> + <!-- ================================================= --> + <!-- Parameters --> + <!-- ================================================= --> + <parameter name="hotdeployment" locked="false">false</parameter> + <parameter name="hotupdate" locked="false">false</parameter> + <parameter name="enableMTOM" locked="false">false</parameter> + <parameter name="enableSwA" locked="false">false</parameter> + + <!--Uncomment if you want to enable file caching for attachments --> + <!--parameter name="cacheAttachments" locked="false">true</parameter> + <parameter name="attachmentDIR" locked="false"></parameter> + <parameter name="sizeThreshold" locked="false">4000</parameter--> + + <!--This will give out the timout of the configuration contexts, in seconds--> + <parameter name="ConfigContextTimeoutInterval" locked="false">30</parameter> + + <!--During a fault, stacktrace can be sent with the fault message. The following flag will control --> + <!--that behaviour.--> + <parameter name="sendStacktraceDetailsWithFaults" locked="false">true</parameter> + + <!--If there aren't any information available to find out the fault reason, we set the message of the expcetion--> + <!--as the faultreason/Reason. But when a fault is thrown from a service or some where, it will be --> + <!--wrapped by different levels. Due to this the initial exception message can be lost. If this flag--> + <!--is set then, Axis2 tries to get the first exception and set its message as the faultreason/Reason.--> + <parameter name="DrillDownToRootCauseForFaultReason" locked="false">false</parameter> + + <parameter name="userName" locked="false">admin</parameter> + <parameter name="password" locked="false">axis2</parameter> + + <!--Following params will set the proper context paths for invocations. All the endpoints will have a commons context--> + <!--root which can configured using the following contextRoot parameter--> + <!--<parameter name="contextRoot" locked="false">axis2</parameter>--> + + <!--Our HTTP endpoints can handle both REST and SOAP. Following parameters can be used to distingiush those endpoints--> + <!--In case of a servlet, if you change this you have to manually change the settings of your servlet container to map this --> + <!--context path to proper Axis2 servlets--> + <!--<parameter name="servicePath" locked="false">services</parameter>--> + <!--<parameter name="restPath" locked="false">rest</parameter>--> + + + <!--Set the flag to true if you want to enable transport level session mangment--> + <parameter name="manageTransportSession" locked="false">false</parameter> + + <!--Following two parameters will be used to handle REST in Axis2. The default settings will make Axis2 to have two--> + <!--different endpoints, one for REST (AxisRESTServlet) one for SOAP message handling (AxisServlet). But following--> + <!--parameters help to tweak the message handling of two main servlets. --> + + <!-- If the enableRESTInAxis2MainServlet is true, then Axis2MainServlet will handle both SOAP and REST messages --> + <parameter name="enableRESTInAxis2MainServlet" locked="true">true</parameter> + + <!-- Following parameter will completely disable REST handling in both the servlets--> + <parameter name="disableREST" locked="true">false</parameter> + + <!-- This will disable the separate servlet we have for REST handling. --> + <parameter name="disableSeparateEndpointForREST" locked="true">false</parameter> + + <!-- If you have a frontend host which exposes this webservice using a different public URL --> + <!-- use this parameter to override autodetected url --> + <!--<parameter name="httpFrontendHostUrl" locked="false">https://someotherhost/context</parameter>--> + + + <!-- The way of adding listener to the system--> + <!-- <listener class="org.apache.axis2.ObserverIMPL">--> + <!-- <parameter name="RSS_URL" locked="false">http://127.0.0.1/rss</parameter>--> + <!-- </listener>--> + + <!-- ================================================= --> + <!-- Message Receivers --> + <!-- ================================================= --> + <!--This is the Deafult Message Receiver for the system , if you want to have MessageReceivers for --> + <!--all the other MEP implement it and add the correct entry to here , so that you can refer from--> + <!--any operation --> + <!--Note : You can ovride this for particular service by adding the same element with your requirement--> + <messageReceivers> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" + class="org.apache.tuscany.binding.axis2.Axis2ServiceInMessageReceiver"/> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-only" + class="org.apache.axis2.receivers.RawXMLINOnlyMessageReceiver"/> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" + class="org.apache.axis2.receivers.RawXMLINOutMessageReceiver"/> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" + class="org.apache.tuscany.binding.axis2.Axis2ServiceInOutAsyncMessageReceiver"/> + <messageReceiver mep="http://www.w3.org/2004/08/wsdl/in-out" + class="org.apache.tuscany.binding.axis2.Axis2ServiceInOutSyncMessageReceiver"/> + </messageReceivers> + <!-- ================================================= --> + <!-- Transport Ins --> + <!-- ================================================= --> + <transportReceiver name="http" + class="org.apache.axis2.transport.http.SimpleHTTPServer"> + <parameter name="port" locked="false">6060</parameter> + <!-- Here is the complete list of supported parameters (see example settings further below): + port: the port to listen on (default 6060) + hostname: if non-null, url prefix used in reply-to endpoint references (default null) + originServer: value of http Server header in outgoing messages (default "Simple-Server/1.1") + requestTimeout: value in millis of time that requests can wait for data (default 20000) + requestTcpNoDelay: true to maximize performance and minimize latency (default true) + false to minimize bandwidth consumption by combining segments + requestCoreThreadPoolSize: number of threads available for request processing (unless queue fills up) (default 25) + requestMaxThreadPoolSize: number of threads available for request processing if queue fills us (default 150) + note that default queue never fills up: see HttpFactory + threadKeepAliveTime: time to keep threads in excess of core size alive while inactive (default 180) + note that no such threads can exist with default unbounded request queue + threadKeepAliveTimeUnit: TimeUnit of value in threadKeepAliveTime (default SECONDS) (default SECONDS) + --> + <!-- <parameter name="hostname" locked="false">http://www.myApp.com/ws</parameter> --> + <!-- <parameter name="originServer" locked="false">My-Server/1.1</parameter> --> + <!-- <parameter name="requestTimeout" locked="false">10000</parameter> --> + <!-- <parameter name="requestTcpNoDelay" locked="false">false</parameter> --> + <!-- <parameter name="requestCoreThreadPoolSize" locked="false">50</parameter> --> + <!-- <parameter name="RequestMaxThreadPoolSize" locked="false">100</parameter> --> + <!-- <parameter name="threadKeepAliveTime" locked="false">240000</parameter> --> + <!-- <parameter name="threadKeepAliveTimeUnit" locked="false">MILLISECONDS</parameter> --> + </transportReceiver> + + <!--Uncomment this and configure as appropriate for JMS transport support, after setting up your JMS environment (e.g. ActiveMQ) + <transportReceiver name="jms" class="org.apache.axis2.transport.jms.JMSListener"> + <parameter name="myTopicConnectionFactory" locked="false"> + <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter> + <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter> + <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">TopicConnectionFactory</parameter> + </parameter> + + <parameter name="myQueueConnectionFactory" locked="false"> + <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter> + <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter> + <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter> + </parameter> + + <parameter name="default" locked="false"> + <parameter name="java.naming.factory.initial" locked="false">org.apache.activemq.jndi.ActiveMQInitialContextFactory</parameter> + <parameter name="java.naming.provider.url" locked="false">tcp://localhost:61616</parameter> + <parameter name="transport.jms.ConnectionFactoryJNDIName" locked="false">QueueConnectionFactory</parameter> + </parameter> + </transportReceiver>--> + + <!--Uncomment if you want to have SMTP transport support--> + <!--<transportReceiver name="mail" class="org.apache.axis2.transport.mail.SimpleMailListener">--> + <!--<parameter name="transport.mail.pop3.host" locked="false">127.0.0.1</parameter>--> + <!--<parameter name="transport.mail.pop3.user" locked="false">axis2</parameter>--> + <!--<parameter name="transport.mail.pop3.password" locked="false">axis2</parameter>--> + <!--<parameter name="transport.mail.pop3.port" locked="false">110</parameter>--> + <!--<parameter name="transport.mail.replyToAddress" locked="false">axis2@127.0.0.1</parameter>--> + <!--</transportReceiver>--> + + <transportReceiver name="tcp" + class="org.apache.axis2.transport.tcp.TCPServer"> + <parameter name="port" locked="false">6060</parameter> + <!--If you want to give your own host address for EPR generation--> + <!--uncommet following paramter , and set as you required.--> + <!--<parameter name="hostname" locked="false">tcp://myApp.com/ws</parameter>--> + </transportReceiver> + + <!-- ================================================= --> + <!-- Transport Outs --> + <!-- ================================================= --> + + <transportSender name="tcp" + class="org.apache.axis2.transport.tcp.TCPTransportSender"/> + <transportSender name="local" + class="org.apache.axis2.transport.local.LocalTransportSender"/> + <transportSender name="http" + class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> + <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> + <parameter name="Transfer-Encoding" locked="false">chunked</parameter> + </transportSender> + <transportSender name="https" + class="org.apache.axis2.transport.http.CommonsHTTPTransportSender"> + <parameter name="PROTOCOL" locked="false">HTTP/1.1</parameter> + <parameter name="Transfer-Encoding" locked="false">chunked</parameter> + </transportSender> + + <!-- Commented out by Tuscany + <transportSender name="jms" + class="org.apache.axis2.transport.jms.JMSSender"/> + --> + + <!-- Uncomment this one with the appropriate papameters to enable the SMTP transport Receiver + <transportSender name="mailto" class="org.apache.axis2.transport.mail.MailTransportSender"> + <parameter name="transport.mail.smtp.host" locked="false">127.0.0.1</parameter> + <parameter name="transport.mail.smtp.user" locked="false">axis2</parameter> + <parameter name="transport.mail.smtp.password" locked="false">axis2</parameter> + <parameter name="transport.mail.smtp.port" locked="false">25</parameter> + </transportSender> + --> + + <!-- ================================================= --> + <!-- Global Modules --> + <!-- ================================================= --> + <!-- Comment this to disable Addressing --> + <!-- Commented out by Tuscany + <module ref="addressing"/> + --> + + <!--Configuring module , providing parameters for modules whether they refer or not--> + <!--<moduleConfig name="addressing">--> + <!--<parameter name="addressingPara" locked="false">N/A</parameter>--> + <!--</moduleConfig>--> + + <!-- ================================================= --> + <!-- Phases --> + <!-- ================================================= --> + <phaseOrder type="InFlow"> + <!-- System pre defined phases --> + <phase name="Transport"> + <handler name="TuscanyDispatcher" + class="org.apache.tuscany.binding.axis2.TuscanyDispatcher"> + <order phase="Transport"/> + </handler> + <handler name="RequestURIBasedDispatcher" + class="org.apache.axis2.engine.RequestURIBasedDispatcher"> + <order phase="Transport"/> + </handler> + <handler name="SOAPActionBasedDispatcher" + class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> + <order phase="Transport"/> + </handler> + </phase> + <phase name="Security"/> + <phase name="PreDispatch"/> + <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> + <handler name="AddressingBasedDispatcher" + class="org.apache.axis2.engine.AddressingBasedDispatcher"> + <order phase="Dispatch"/> + </handler> + + <handler name="SOAPMessageBodyBasedDispatcher" + class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> + <order phase="Dispatch"/> + </handler> + <handler name="InstanceDispatcher" + class="org.apache.axis2.engine.InstanceDispatcher"> + <order phase="Dispatch"/> + </handler> + </phase> + <!-- System pre defined phases --> + <!-- After Postdispatch phase module author or or service author can add any phase he want --> + <phase name="OperationInPhase"/> + </phaseOrder> + <phaseOrder type="OutFlow"> + <!-- user can add his own phases to this area --> + <phase name="OperationOutPhase"/> + <!--system predefined phase--> + <!--these phase will run irrespective of the service--> + <phase name="PolicyDetermination"/> + <phase name="MessageOut"/> + <phase name="Security"/> + </phaseOrder> + <phaseOrder type="InFaultFlow"> + <phase name="PreDispatch"/> + <phase name="Dispatch" class="org.apache.axis2.engine.DispatchPhase"> + <handler name="RequestURIBasedDispatcher" + class="org.apache.axis2.engine.RequestURIBasedDispatcher"> + <order phase="Dispatch"/> + </handler> + + <handler name="SOAPActionBasedDispatcher" + class="org.apache.axis2.engine.SOAPActionBasedDispatcher"> + <order phase="Dispatch"/> + </handler> + + <handler name="AddressingBasedDispatcher" + class="org.apache.axis2.engine.AddressingBasedDispatcher"> + <order phase="Dispatch"/> + </handler> + + <handler name="SOAPMessageBodyBasedDispatcher" + class="org.apache.axis2.engine.SOAPMessageBodyBasedDispatcher"> + <order phase="Dispatch"/> + </handler> + <handler name="InstanceDispatcher" + class="org.apache.axis2.engine.InstanceDispatcher"> + <order phase="PostDispatch"/> + </handler> + </phase> + <!-- user can add his own phases to this area --> + <phase name="OperationInFaultPhase"/> + </phaseOrder> + <phaseOrder type="OutFaultFlow"> + <!-- user can add his own phases to this area --> + <phase name="OperationOutFaultPhase"/> + <phase name="PolicyDetermination"/> + <phase name="MessageOut"/> + </phaseOrder> +</axisconfig> + |