diff options
Diffstat (limited to 'branches/sca-java-0.99/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java')
-rw-r--r-- | branches/sca-java-0.99/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/branches/sca-java-0.99/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java b/branches/sca-java-0.99/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java new file mode 100644 index 0000000000..87ba29636f --- /dev/null +++ b/branches/sca-java-0.99/modules/binding-ws-axis2/src/main/java/org/apache/tuscany/sca/binding/ws/axis2/Axis2BindingInvoker.java @@ -0,0 +1,178 @@ +/* + * 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.lang.reflect.InvocationTargetException; + +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.client.OperationClient; +import org.apache.axis2.client.Options; +import org.apache.axis2.client.ServiceClient; +import org.apache.axis2.context.MessageContext; +import org.apache.axis2.transport.http.HTTPConstants; +import org.apache.axis2.wsdl.WSDLConstants; +import org.apache.tuscany.sca.invocation.Invoker; +import org.apache.tuscany.sca.invocation.Message; +import org.osoa.sca.Constants; + +/** + * Axis2BindingInvoker uses an Axis2 OperationClient to invoke a remote web service + */ +public class Axis2BindingInvoker implements Invoker { + + private ServiceClient serviceClient; + private QName wsdlOperationName; + private Options options; + private SOAPFactory soapFactory; + + public static final QName CONVERSATION_ID_REFPARM_QN = new QName(Constants.SCA_NS, "conversationID"); + + public Axis2BindingInvoker(ServiceClient serviceClient, + QName wsdlOperationName, + Options options, + SOAPFactory soapFactory) { + this.serviceClient = serviceClient; + this.wsdlOperationName = wsdlOperationName; + this.options = options; + this.soapFactory = soapFactory; + } + + public Message invoke(Message msg) { + try { + Object resp = invokeTarget(msg); + msg.setBody(resp); + } catch (InvocationTargetException e) { + msg.setFaultBody(e.getCause()); + } catch (Throwable e) { + msg.setFaultBody(e); + } + + return msg; + } + + protected Object invokeTarget(Message msg) throws InvocationTargetException { + try { + OperationClient operationClient = createOperationClient(msg); + + // ensure connections are tracked so that they can be closed by the reference binding + MessageContext requestMC = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE); + requestMC.getOptions().setProperty(HTTPConstants.REUSE_HTTP_CLIENT, Boolean.TRUE); + requestMC.getOptions().setTimeOutInMilliSeconds(120000L); + + operationClient.execute(true); + + MessageContext responseMC = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE); + + operationClient.complete(requestMC); + + return responseMC.getEnvelope().getBody().getFirstElement(); + + } catch (AxisFault e) { + throw new InvocationTargetException(e); + } + } + + @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 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); + + String conversationId = msg.getConversationID(); + if (conversationId != null && conversationId.length() != 0) { + EndpointReference fromEPR = new EndpointReference(AddressingConstants.Final.WSA_ANONYMOUS_URL); + fromEPR.addReferenceParameter(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); + // 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) { + org.apache.tuscany.sca.runtime.EndpointReference ep = msg.getTo(); + if (ep != null) { + requestMC.setTo(new EndpointReference(ep.getURI())); + } else { + throw new RuntimeException("Unable to determine destination endpoint"); + } + } + //FIXME: need to consolidate the following code with similar code above for + // conversations, so that conversations and callbacks work when used together + if (options.getFrom() != null) { + requestMC.setFrom(options.getFrom()); + //FIXME: is there any way to use the Axis2 addressing support for this? + SOAPEnvelope sev = requestMC.getEnvelope(); + SOAPHeader sh = sev.getHeader(); + OMElement el = + options.getFrom().toOM(AddressingConstants.Final.WSA_NAMESPACE, + AddressingConstants.WSA_FROM, + AddressingConstants.WSA_DEFAULT_PREFIX); + sh.addChild(el); + } else if (msg.getFrom() != null) { + EndpointReference fromEpr = new EndpointReference(msg.getFrom().getURI()); + requestMC.setFrom(fromEpr); + 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); + } else { + // the from field remains blank + } + operationClient.addMessageContext(requestMC); + + return operationClient; + } + +} |