From 3739ece0a0cdb420cff1a5d7cd80d45bb6de1bef Mon Sep 17 00:00:00 2001 From: slaws Date: Fri, 12 Feb 2010 13:01:03 +0000 Subject: Enable reference side binding wire. Mainly so I can start trying out some binding specific policy implementations. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@909388 13f79535-47bb-0310-9956-ffa450edef68 --- .../binding-ws-runtime-axis2/META-INF/MANIFEST.MF | 2 + .../trunk/modules/binding-ws-runtime-axis2/pom.xml | 7 +- .../sca/binding/ws/axis2/Axis2BindingInvoker.java | 272 --------------------- .../ws/axis2/Axis2OneWayBindingInvoker.java | 66 ----- .../ws/axis2/Axis2ReferenceBindingProvider.java | 40 ++- .../ws/axis2/provider/Axis2BindingInvoker.java | 172 +++++++++++++ .../transport/TransportReferenceInterceptor.java | 137 +++++++++++ 7 files changed, 346 insertions(+), 350 deletions(-) delete mode 100644 sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java delete mode 100644 sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java create mode 100644 sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/provider/Axis2BindingInvoker.java create mode 100644 sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/transport/TransportReferenceInterceptor.java diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF index 6ddb93b622..24fddd2cb3 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/META-INF/MANIFEST.MF @@ -128,6 +128,8 @@ Import-Package: com.ctc.wstx.stax, org.apache.tuscany.sca.interfacedef.wsdl;version="2.0.0", org.apache.tuscany.sca.invocation;version="2.0.0", org.apache.tuscany.sca.policy;version="2.0.0", + org.apache.tuscany.sca.policy.security;version="2.0.0", + org.apache.tuscany.sca.policy.authentication.basic;version="2.0.0", org.apache.tuscany.sca.policy.util;version="2.0.0", org.apache.tuscany.sca.provider;version="2.0.0", org.apache.tuscany.sca.runtime;version="2.0.0", diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/pom.xml b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/pom.xml index e33a2864b9..52d3fb08ac 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/pom.xml +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/pom.xml @@ -104,12 +104,17 @@ 2.0-SNAPSHOT - org.apache.tuscany.sca tuscany-xsd 2.0-SNAPSHOT + + + org.apache.tuscany.sca + tuscany-policy-security + 2.0-SNAPSHOT + org.apache.axis2 diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java deleted file mode 100644 index fd18997adc..0000000000 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.binding.ws.axis2; - -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.util.ArrayList; -import java.util.List; - -import javax.xml.namespace.QName; - -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.addressing.EndpointReferenceHelper; -import org.apache.axis2.client.OperationClient; -import org.apache.axis2.client.Options; -import org.apache.axis2.context.MessageContext; -import org.apache.axis2.transport.http.HTTPConstants; -import org.apache.tuscany.sca.assembly.Endpoint; -import org.apache.tuscany.sca.binding.ws.WebServiceBinding; -import org.apache.tuscany.sca.interfacedef.util.FaultException; -import org.apache.tuscany.sca.invocation.DataExchangeSemantics; -import org.apache.tuscany.sca.invocation.Invoker; -import org.apache.tuscany.sca.invocation.Message; -import org.apache.tuscany.sca.runtime.ReferenceParameters; - - -/** - * Axis2BindingInvoker uses an Axis2 OperationClient to invoke a remote web service - * - * @version $Rev$ $Date$ - */ -public class Axis2BindingInvoker implements Invoker, DataExchangeSemantics { - private final static String SCA11_TUSCANY_NS = "http://tuscany.apache.org/xmlns/sca/1.1"; - - public static final QName QNAME_WSA_FROM = - new QName(AddressingConstants.Final.WSA_NAMESPACE, AddressingConstants.WSA_FROM, - AddressingConstants.WSA_DEFAULT_PREFIX); - public static final String TUSCANY_PREFIX = "tuscany"; - public static final QName CALLBACK_ID_REFPARM_QN = - new QName(SCA11_TUSCANY_NS, "CallbackID", TUSCANY_PREFIX); - public static final QName CONVERSATION_ID_REFPARM_QN = - new QName(SCA11_TUSCANY_NS, "ConversationID", TUSCANY_PREFIX); - - private Axis2ReferenceBindingProvider bindingProvider; - private QName wsdlOperationName; - private Options options; - private SOAPFactory soapFactory; - private WebServiceBinding wsBinding; - -// private BasicAuthenticationPolicy basicAuthenticationPolicy = null; -// private Axis2TokenAuthenticationPolicy axis2TokenAuthenticationPolicy = null; -// private List axis2HeaderPolicies = new ArrayList(); - - public Axis2BindingInvoker(Axis2ReferenceBindingProvider bindingProvider, - QName wsdlOperationName, - Options options, - SOAPFactory soapFactory, - WebServiceBinding wsBinding) { - this.bindingProvider = bindingProvider; - this.wsdlOperationName = wsdlOperationName; - this.options = options; - this.soapFactory = soapFactory; - this.wsBinding = wsBinding; - - // find out which policies are active - /* - if (wsBinding instanceof PolicySubject) { - List policySets = ((PolicySubject)wsBinding).getPolicySets(); - for (PolicySet ps : policySets) { - for (Object p : ps.getPolicies()) { - if (BasicAuthenticationPolicy.class.isInstance(p)) { - basicAuthenticationPolicy = (BasicAuthenticationPolicy)p; - } else if (Axis2TokenAuthenticationPolicy.class.isInstance(p)) { - axis2TokenAuthenticationPolicy = (Axis2TokenAuthenticationPolicy)p; - } else if (Axis2HeaderPolicy.class.isInstance(p)) { - axis2HeaderPolicies.add((Axis2HeaderPolicy)p); - }else { - // etc. check for other types of policy being present - } - } - } - } - */ - } - - private static final QName EXCEPTION = new QName("", "Exception"); - - public Message invoke(Message msg) { - try { - Object resp = invokeTarget(msg); - - msg.setBody(resp); - } catch (AxisFault e) { - if (e.getDetail() != null ) { - FaultException f = new FaultException(e.getMessage(), e.getDetail(), e); - f.setFaultName(e.getDetail().getQName()); - msg.setFaultBody(f); - } else { - msg.setFaultBody(e); - } - } catch (Throwable e) { - msg.setFaultBody(e); - } - - return msg; - } - - protected Object invokeTarget(Message msg) throws AxisFault { - final OperationClient operationClient = createOperationClient(msg); - - // ensure connections are tracked so that they can be closed by the reference binding - MessageContext requestMC = operationClient.getMessageContext("Out"); - requestMC.getOptions().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); - requestMC.getOptions().setTimeOutInMilliSeconds(240000L); - - /* - for ( PolicyHandler policyHandler : policyHandlerList ) { - policyHandler.beforeInvoke(msg, requestMC, operationClient); - } - */ - - // set policy specified headers -/* - for (Axis2HeaderPolicy policy : axis2HeaderPolicies){ - Axis2BindingHeaderConfigurator.setHeader(requestMC, msg, policy.getHeaderName()); - } - - if (basicAuthenticationPolicy != null) { - Axis2BindingBasicAuthenticationConfigurator.setOperationOptions(operationClient, msg, basicAuthenticationPolicy); - } - - if (axis2TokenAuthenticationPolicy != null) { - Axis2BindingHeaderConfigurator.setHeader(requestMC, msg, axis2TokenAuthenticationPolicy.getTokenName()); - } -*/ - - // Allow privileged access to read properties. Requires PropertiesPermission read in - // security policy. - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws AxisFault { - operationClient.execute(true); - return null; - } - }); - } catch (PrivilegedActionException e) { - operationClient.complete(requestMC); - throw (AxisFault)e.getException(); - } - - MessageContext responseMC = operationClient.getMessageContext("In"); - - /* - for ( PolicyHandler policyHandler : policyHandlerList ) { - policyHandler.afterInvoke(msg, responseMC, operationClient); - } - */ - - OMElement response = responseMC.getEnvelope().getBody().getFirstElement(); - - // FIXME: [rfeng] We have to pay performance penalty to build the complete OM as the operationClient.complete() will - // release the underlying HTTP connection. - // Force the response to be populated, see https://issues.apache.org/jira/browse/TUSCANY-1541 - if (response != null) { - response.build(); - } - - operationClient.complete(requestMC); - - return response; - } - - @SuppressWarnings("deprecation") - protected OperationClient createOperationClient(Message msg) throws AxisFault { - SOAPEnvelope env = soapFactory.getDefaultEnvelope(); - Object[] args = (Object[])msg.getBody(); - 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 between OMElements and other types."); - } - } - } - final MessageContext requestMC = new MessageContext(); - requestMC.setEnvelope(env); - - // Axis2 operationClients can not be shared so create a new one for each request - final OperationClient operationClient = bindingProvider.getServiceClient().createClient(wsdlOperationName); - operationClient.setOptions(options); - - Endpoint callbackEndpoint = msg.getFrom().getCallbackEndpoint(); - - // add WS-Addressing header - //FIXME: is there any way to use the Axis2 addressing support for this? - if (callbackEndpoint != null) { - EndpointReference fromEPR = new EndpointReference(callbackEndpoint.getURI()); - SOAPEnvelope sev = requestMC.getEnvelope(); - SOAPHeader sh = sev.getHeader(); - OMElement epr = - EndpointReferenceHelper.toOM(sev.getOMFactory(), - fromEPR, - QNAME_WSA_FROM, - AddressingConstants.Final.WSA_NAMESPACE); - sh.addChild(epr); - requestMC.setFrom(fromEPR); - } - - // Set any message headers required by policy - // Get the header from the tuscany message - // If its not already an OM convert it to OM - // add it to the envelope header - - // if target endpoint was not specified when this invoker was created, - // use dynamically specified target endpoint passed in on this call - if (options.getTo() == null) { - Endpoint ep = msg.getTo(); - if (ep != null) { - requestMC.setTo(new EndpointReference(ep.getBinding().getURI())); - } else { - throw new RuntimeException("Unable to determine destination endpoint"); - } - } else { - requestMC.setTo(new EndpointReference(options.getTo().getAddress())); - } - - // Allow privileged access to read properties. Requires PropertiesPermission read in - // security policy. - try { - AccessController.doPrivileged(new PrivilegedExceptionAction() { - public Object run() throws AxisFault { - operationClient.addMessageContext(requestMC); - return null; - } - }); - } catch (PrivilegedActionException e) { - throw (AxisFault)e.getException(); - } - return operationClient; - } - - public boolean allowsPassByReference() { - return true; - } -} diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java deleted file mode 100644 index 4a22b39ed9..0000000000 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2OneWayBindingInvoker.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package org.apache.tuscany.sca.binding.ws.axis2; - -import javax.xml.namespace.QName; - -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.context.MessageContext; -import org.apache.axis2.transport.http.HTTPConstants; -import org.apache.tuscany.sca.binding.ws.WebServiceBinding; -import org.apache.tuscany.sca.invocation.Message; - -/** - * Axis2OneWayBindingInvoker uses an Axis2 OperationClient to invoke a OneWay remote web service. - * - * @version $Rev$ $Date$ - */ -public class Axis2OneWayBindingInvoker extends Axis2BindingInvoker { - - public Axis2OneWayBindingInvoker(Axis2ReferenceBindingProvider bindingProvider, - QName wsdlOperationName, - Options options, - SOAPFactory soapFactory, - WebServiceBinding wsBinding) { - - super(bindingProvider, wsdlOperationName, options, soapFactory, wsBinding); - } - - @Override - protected Object invokeTarget(Message msg) throws AxisFault { - OperationClient operationClient = createOperationClient(msg); - - // ensure connections are tracked so that they can be closed by the reference binding - MessageContext requestMC = operationClient.getMessageContext("Out"); - //requestMC.getOptions().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); - Options opt = requestMC.getOptions(); - opt.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); - opt.setUseSeparateListener(true); - opt.setProperty(HTTPConstants.AUTO_RELEASE_CONNECTION,Boolean.TRUE); - - operationClient.execute(false); - - // REVIEW it seems ok to return null - return null; - } - -} diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java index 15e4ea3435..8a5aab0ac6 100644 --- a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2ReferenceBindingProvider.java @@ -55,21 +55,26 @@ import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.params.HttpConnectionManagerParams; import org.apache.tuscany.sca.assembly.EndpointReference; import org.apache.tuscany.sca.assembly.xml.Constants; +import org.apache.tuscany.sca.binding.ws.axis2.transport.TransportReferenceInterceptor; import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.binding.ws.axis2.provider.Axis2BindingInvoker; import org.apache.tuscany.sca.core.ExtensionPointRegistry; import org.apache.tuscany.sca.core.FactoryExtensionPoint; -import org.apache.tuscany.sca.databinding.DataBindingExtensionPoint; import org.apache.tuscany.sca.interfacedef.InterfaceContract; import org.apache.tuscany.sca.interfacedef.Operation; +import org.apache.tuscany.sca.invocation.InvocationChain; import org.apache.tuscany.sca.invocation.Invoker; import org.apache.tuscany.sca.invocation.MessageFactory; +import org.apache.tuscany.sca.invocation.Phase; import org.apache.tuscany.sca.policy.util.PolicyHelper; +import org.apache.tuscany.sca.provider.EndpointReferenceProvider; import org.apache.tuscany.sca.provider.ReferenceBindingProvider; import org.apache.tuscany.sca.runtime.RuntimeComponent; import org.apache.tuscany.sca.runtime.RuntimeComponentReference; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; import org.oasisopen.sca.ServiceRuntimeException; -public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { +public class Axis2ReferenceBindingProvider implements EndpointReferenceProvider { // Tuscany extensions private ExtensionPointRegistry extensionPoints; @@ -78,7 +83,7 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { // the endpoint reference configuration that's driving this binding provider // and some convenience data retrieved from the endpoint reference - private EndpointReference endpointReference; + private RuntimeEndpointReference endpointReference; private RuntimeComponent component; private RuntimeComponentReference reference; private WebServiceBinding wsBinding; @@ -99,7 +104,7 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { EndpointReference endpointReference) { this.extensionPoints = extensionPoints; - this.endpointReference = endpointReference; + this.endpointReference = (RuntimeEndpointReference)endpointReference; this.modelFactories = extensionPoints.getExtensionPoint(FactoryExtensionPoint.class); this.messageFactory = modelFactories.getFactory(MessageFactory.class); @@ -202,6 +207,7 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { public InterfaceContract getBindingInterfaceContract() { return wsBinding.getBindingInterfaceContract(); + } public boolean supportsOneWayInvocation() { @@ -241,14 +247,31 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { { options.setProperty(org.apache.axis2.Constants.Configuration.ENABLE_MTOM, org.apache.axis2.Constants.VALUE_TRUE); } - Axis2BindingInvoker invoker; + + return new Axis2BindingInvoker(endpointReference, serviceClient, wsdlOperationQName, options, soapFactory, wsBinding); + +/* if (operation.isNonBlocking()) { invoker = new Axis2OneWayBindingInvoker(this, wsdlOperationQName, options, soapFactory, wsBinding); } else { - invoker = new Axis2BindingInvoker(this, wsdlOperationQName, options, soapFactory, wsBinding); + invoker = new Axis2BindingInvoker(endpointReference, serviceClient, wsdlOperationQName, options, soapFactory, wsBinding); } return invoker; +*/ + } + + /* + * set up the reference binding wire with the right set of ws reference + * interceptors + */ + public void configure() { + InvocationChain bindingChain = endpointReference.getBindingInvocationChain(); + + // add transport interceptor + bindingChain.addInterceptor(Phase.REFERENCE_BINDING_TRANSPORT, + new TransportReferenceInterceptor()); + } // Reference specific utility operations @@ -326,9 +349,4 @@ public class Axis2ReferenceBindingProvider implements ReferenceBindingProvider { } return null; } - - public ServiceClient getServiceClient() { - return serviceClient; - } - } diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/provider/Axis2BindingInvoker.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/provider/Axis2BindingInvoker.java new file mode 100644 index 0000000000..dd5a49d4dd --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/provider/Axis2BindingInvoker.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.binding.ws.axis2.provider; + +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import javax.xml.namespace.QName; + +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.addressing.EndpointReferenceHelper; +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.tuscany.sca.assembly.Endpoint; +import org.apache.tuscany.sca.binding.ws.WebServiceBinding; +import org.apache.tuscany.sca.interfacedef.util.FaultException; +import org.apache.tuscany.sca.invocation.DataExchangeSemantics; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.apache.tuscany.sca.runtime.RuntimeEndpointReference; + + +/** + * Axis2BindingInvoker creates an Axis2 OperationClient to pass down the + * binding chain + * + * @version $Rev$ $Date$ + */ +public class Axis2BindingInvoker implements Invoker, DataExchangeSemantics { + public static final QName QNAME_WSA_FROM = + new QName(AddressingConstants.Final.WSA_NAMESPACE, + AddressingConstants.WSA_FROM, + AddressingConstants.WSA_DEFAULT_PREFIX); + + private RuntimeEndpointReference endpointReference; + private ServiceClient serviceClient; + private QName wsdlOperationName; + private Options options; + private SOAPFactory soapFactory; + private WebServiceBinding wsBinding; + + public Axis2BindingInvoker(RuntimeEndpointReference endpointReference, + ServiceClient serviceClient, + QName wsdlOperationName, + Options options, + SOAPFactory soapFactory, + WebServiceBinding wsBinding) { + this.endpointReference = endpointReference; + this.serviceClient = serviceClient; + this.wsdlOperationName = wsdlOperationName; + this.options = options; + this.soapFactory = soapFactory; + this.wsBinding = wsBinding; + } + + public Message invoke(Message msg) { + try { + final OperationClient operationClient = createOperationClient(msg); + msg.setBindingContext(operationClient); + msg = endpointReference.getBindingInvocationChain().getHeadInvoker().invoke(msg); + + } catch (AxisFault e) { + if (e.getDetail() != null ) { + FaultException f = new FaultException(e.getMessage(), e.getDetail(), e); + f.setFaultName(e.getDetail().getQName()); + msg.setFaultBody(f); + } else { + msg.setFaultBody(e); + } + } catch (Throwable e) { + msg.setFaultBody(e); + } + + return msg; + } + + @SuppressWarnings("deprecation") + protected OperationClient createOperationClient(Message msg) throws AxisFault { + SOAPEnvelope env = soapFactory.getDefaultEnvelope(); + Object[] args = (Object[])msg.getBody(); + 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 between OMElements and other types."); + } + } + } + final MessageContext requestMC = new MessageContext(); + requestMC.setEnvelope(env); + + // Axis2 operationClients can not be shared so create a new one for each request + final OperationClient operationClient = serviceClient.createClient(wsdlOperationName); + operationClient.setOptions(options); + + Endpoint callbackEndpoint = msg.getFrom().getCallbackEndpoint(); + + // add WS-Addressing header + //FIXME: is there any way to use the Axis2 addressing support for this? + if (callbackEndpoint != null) { + EndpointReference fromEPR = new EndpointReference(callbackEndpoint.getURI()); + SOAPEnvelope sev = requestMC.getEnvelope(); + SOAPHeader sh = sev.getHeader(); + OMElement epr = + EndpointReferenceHelper.toOM(sev.getOMFactory(), + fromEPR, + QNAME_WSA_FROM, + AddressingConstants.Final.WSA_NAMESPACE); + sh.addChild(epr); + requestMC.setFrom(fromEPR); + } + + // if target endpoint was not specified when this invoker was created, + // use dynamically specified target endpoint passed in on this call + if (options.getTo() == null) { + Endpoint ep = msg.getTo(); + if (ep != null) { + requestMC.setTo(new EndpointReference(ep.getBinding().getURI())); + } else { + throw new RuntimeException("Unable to determine destination endpoint"); + } + } else { + requestMC.setTo(new EndpointReference(options.getTo().getAddress())); + } + + // Allow privileged access to read properties. Requires PropertiesPermission read in + // security policy. + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws AxisFault { + operationClient.addMessageContext(requestMC); + return null; + } + }); + } catch (PrivilegedActionException e) { + throw (AxisFault)e.getException(); + } + return operationClient; + } + + public boolean allowsPassByReference() { + return true; + } +} diff --git a/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/transport/TransportReferenceInterceptor.java b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/transport/TransportReferenceInterceptor.java new file mode 100644 index 0000000000..7daa58bf29 --- /dev/null +++ b/sca-java-2.x/trunk/modules/binding-ws-runtime-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/transport/TransportReferenceInterceptor.java @@ -0,0 +1,137 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.tuscany.sca.binding.ws.axis2.transport; + +import java.security.AccessController; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import org.apache.axiom.om.OMElement; +import org.apache.axis2.AxisFault; +import org.apache.axis2.client.OperationClient; +import org.apache.axis2.client.Options; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.tuscany.sca.interfacedef.util.FaultException; +import org.apache.tuscany.sca.invocation.Interceptor; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; + +/** + * Use an Axis2 OperationClient to invoke a remote web service + * + * @version $Rev$ $Date$ + */ +public class TransportReferenceInterceptor implements Interceptor { + + private Invoker next; + + public TransportReferenceInterceptor() { + } + + public Message invoke(Message msg) { + try { + Object resp = null; + + if (msg.getOperation().isNonBlocking()) { + resp = invokeTargetOneWay(msg); + } else { + resp = invokeTarget(msg); + } + + msg.setBody(resp); + } catch (AxisFault e) { + if (e.getDetail() != null ) { + FaultException f = new FaultException(e.getMessage(), e.getDetail(), e); + f.setFaultName(e.getDetail().getQName()); + msg.setFaultBody(f); + } else { + msg.setFaultBody(e); + } + } catch (Throwable e) { + msg.setFaultBody(e); + } + + return msg; + } + + protected Object invokeTarget(Message msg) throws AxisFault { + final OperationClient operationClient = msg.getBindingContext(); + + // ensure connections are tracked so that they can be closed by the reference binding + MessageContext requestMC = operationClient.getMessageContext("Out"); + requestMC.getOptions().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); + requestMC.getOptions().setTimeOutInMilliSeconds(240000L); + + + // Allow privileged access to read properties. Requires PropertiesPermission read in + // security policy. + try { + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws AxisFault { + operationClient.execute(true); + return null; + } + }); + } catch (PrivilegedActionException e) { + operationClient.complete(requestMC); + throw (AxisFault)e.getException(); + } + + MessageContext responseMC = operationClient.getMessageContext("In"); + + OMElement response = responseMC.getEnvelope().getBody().getFirstElement(); + + // FIXME: [rfeng] We have to pay performance penalty to build the complete OM as the operationClient.complete() will + // release the underlying HTTP connection. + // Force the response to be populated, see https://issues.apache.org/jira/browse/TUSCANY-1541 + if (response != null) { + response.build(); + } + + operationClient.complete(requestMC); + + return response; + } + + protected Object invokeTargetOneWay(Message msg) throws AxisFault { + OperationClient operationClient = msg.getBindingContext(); + + // ensure connections are tracked so that they can be closed by the reference binding + MessageContext requestMC = operationClient.getMessageContext("Out"); + //requestMC.getOptions().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); + Options opt = requestMC.getOptions(); + opt.setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); + opt.setUseSeparateListener(true); + opt.setProperty(HTTPConstants.AUTO_RELEASE_CONNECTION,Boolean.TRUE); + + operationClient.execute(false); + + // REVIEW it seems ok to return null + return null; + } + + public Invoker getNext() { + return next; + } + + public void setNext(Invoker next) { + this.next = next; + } +} -- cgit v1.2.3