Coverage Report - org.mule.transport.cxf.CxfMessageDispatcher
 
Classes in this File Line Coverage Branch Coverage Complexity
CxfMessageDispatcher
64%
58/91
50%
18/36
0
 
 1  
 /*
 2  
  * $Id: CxfMessageDispatcher.java 12248 2008-07-07 22:08:28Z dandiep $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.transport.cxf;
 12  
 
 13  
 import org.mule.DefaultMuleMessage;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.config.MuleProperties;
 17  
 import org.mule.api.endpoint.EndpointURI;
 18  
 import org.mule.api.endpoint.OutboundEndpoint;
 19  
 import org.mule.api.transformer.TransformerException;
 20  
 import org.mule.transport.AbstractMessageDispatcher;
 21  
 import org.mule.transport.soap.SoapConstants;
 22  
 import org.mule.util.TemplateParser;
 23  
 
 24  
 import java.lang.reflect.Method;
 25  
 import java.util.ArrayList;
 26  
 import java.util.Arrays;
 27  
 import java.util.HashMap;
 28  
 import java.util.Iterator;
 29  
 import java.util.List;
 30  
 import java.util.Map;
 31  
 import java.util.Set;
 32  
 import java.util.regex.Pattern;
 33  
 
 34  
 import javax.activation.DataHandler;
 35  
 import javax.xml.namespace.QName;
 36  
 import javax.xml.ws.BindingProvider;
 37  
 
 38  
 import org.apache.cxf.endpoint.Client;
 39  
 import org.apache.cxf.endpoint.ClientImpl;
 40  
 import org.apache.cxf.service.model.BindingOperationInfo;
 41  
 
 42  
 /**
 43  
  * The CxfMessageDispatcher is used for making Soap client requests to remote
 44  
  * services.
 45  
  */
 46  
 public class CxfMessageDispatcher extends AbstractMessageDispatcher
 47  
 {
 48  
 
 49  
     private static final String URI_REGEX = "cxf:\\[(.+?)\\]:(.+?)/\\[(.+?)\\]:(.+?)";
 50  58
     Pattern URI_PATTERN = Pattern.compile(URI_REGEX);
 51  
 
 52  
     protected final CxfConnector connector;
 53  
     protected ClientWrapper wrapper;
 54  58
     private final TemplateParser soapActionTemplateParser = TemplateParser.createAntStyleParser();
 55  
 
 56  
     public CxfMessageDispatcher(OutboundEndpoint endpoint)
 57  
     {
 58  58
         super(endpoint);
 59  58
         this.connector = (CxfConnector) endpoint.getConnector();
 60  58
     }
 61  
 
 62  
     /*
 63  
     We need a way to associate an endpoint with a specific CXF service and operation, and the most sensible way to
 64  
     accomplish that is to overload URI syntax:
 65  
 
 66  
     cxf:[service_URI]:service_localname/[ep_URI]:ep_localname
 67  
 
 68  
     And the map method to operation
 69  
      */
 70  
     protected void doConnect() throws Exception
 71  
     {
 72  58
         wrapper = new ClientWrapper();
 73  58
         wrapper.setBus(connector.getCxfBus());
 74  58
         wrapper.setEndpoint(endpoint);
 75  58
         wrapper.initialize();
 76  58
     }
 77  
 
 78  
     protected void doDisconnect() throws Exception
 79  
     {
 80  58
         wrapper = null;
 81  58
     }
 82  
 
 83  
     protected void doDispose()
 84  
     {
 85  
         // nothing to do
 86  58
     }
 87  
 
 88  
 
 89  
     protected Object[] getArgs(MuleEvent event) throws TransformerException
 90  
     {
 91  58
         Object payload = event.transformMessage();
 92  
         Object[] args;
 93  
 
 94  58
         if (payload instanceof Object[])
 95  
         {
 96  2
             args = (Object[])payload;
 97  
         }
 98  
         else
 99  
         {
 100  56
             args = new Object[]{payload};
 101  
         }
 102  
 
 103  58
         MuleMessage message = event.getMessage();
 104  58
         Set<?> attachmentNames = message.getAttachmentNames();
 105  58
         if (attachmentNames != null && !attachmentNames.isEmpty())
 106  
         {
 107  0
             List<DataHandler> attachments = new ArrayList<DataHandler>();
 108  0
             for (Iterator<?> i = attachmentNames.iterator(); i.hasNext();)
 109  
             {
 110  0
                 attachments.add(message.getAttachment((String)i.next()));
 111  
             }
 112  0
             List<Object> temp = new ArrayList<Object>(Arrays.asList(args));
 113  0
             temp.add(attachments.toArray(new DataHandler[0]));
 114  0
             args = temp.toArray();
 115  
         }
 116  
 
 117  58
         if (args.length == 0)
 118  
         {
 119  0
             return null;
 120  
         }
 121  58
         return args;
 122  
     }
 123  
 
 124  
     protected MuleMessage doSend(MuleEvent event) throws Exception
 125  
     {
 126  58
         ((ClientImpl)wrapper.getClient()).setSynchronousTimeout(event.getTimeout());
 127  58
         if (!wrapper.isClientProxyAvailable())
 128  
         {
 129  52
             return doSendWithClient(event);
 130  
         }
 131  
         else
 132  
         {
 133  6
             return doSendWithProxy(event);
 134  
         }
 135  
     }
 136  
 
 137  
     protected MuleMessage doSendWithProxy(MuleEvent event) throws Exception
 138  
     {
 139  6
         Method method = wrapper.getMethod(event);
 140  
 
 141  6
         Map<String, Object> props = new HashMap<String, Object>();
 142  6
         props.put(MuleProperties.MULE_EVENT_PROPERTY, event); 
 143  
         
 144  
         // Set custom soap action if set on the event or endpoint
 145  6
         String soapAction = (String)event.getMessage().getProperty(SoapConstants.SOAP_ACTION_PROPERTY);
 146  6
         if (soapAction != null)
 147  
         {
 148  0
             soapAction = parseSoapAction(soapAction, new QName(method.getName()), event);
 149  0
             props.put(org.apache.cxf.binding.soap.SoapConstants.SOAP_ACTION, soapAction);
 150  
         }
 151  
         
 152  6
         BindingProvider bp = wrapper.getClientProxy();
 153  6
         bp.getRequestContext().putAll(props);
 154  
         
 155  6
         Object response = method.invoke(wrapper.getClientProxy(), (Object[]) getArgs(event));
 156  
         
 157  
         // TODO: handle holders
 158  
         
 159  6
         return buildResponseMessage(event, new Object[] { response });
 160  
     }
 161  
 
 162  
     protected MuleMessage doSendWithClient(MuleEvent event) throws Exception
 163  
     {
 164  52
         BindingOperationInfo bop = wrapper.getOperation(event);
 165  
         
 166  52
         Map<String, Object> props = new HashMap<String, Object>();
 167  52
         props.put(MuleProperties.MULE_EVENT_PROPERTY, event); 
 168  
         
 169  
         // Set custom soap action if set on the event or endpoint
 170  52
         String soapAction = (String)event.getMessage().getProperty(SoapConstants.SOAP_ACTION_PROPERTY);
 171  52
         if (soapAction != null)
 172  
         {
 173  0
             soapAction = parseSoapAction(soapAction, bop.getName(), event);
 174  0
             props.put(org.apache.cxf.binding.soap.SoapConstants.SOAP_ACTION, soapAction);
 175  0
             event.getMessage().setProperty(SoapConstants.SOAP_ACTION_PROPERTY, soapAction);
 176  
         }
 177  
         
 178  52
         Map<String, Object> ctx = new HashMap<String, Object>();
 179  52
         ctx.put(Client.REQUEST_CONTEXT, props); 
 180  52
         ctx.put(Client.RESPONSE_CONTEXT, props); 
 181  
         
 182  
         // Set Custom Headers on the client
 183  52
         Object[] arr = event.getMessage().getPropertyNames().toArray();
 184  
         String head;
 185  
 
 186  324
         for (int i = 0; i < arr.length; i++)
 187  
         {
 188  272
             head = (String) arr[i];
 189  272
             if ((head != null) && (!head.startsWith("MULE")))
 190  
             {
 191  108
                 props.put((String) arr[i], event.getMessage().getProperty((String) arr[i]));
 192  
             }
 193  
         }
 194  
         
 195  52
         Object[] response = wrapper.getClient().invoke(bop, getArgs(event), ctx);
 196  
 
 197  44
         return buildResponseMessage(event, response);
 198  
     }
 199  
 
 200  
     protected MuleMessage buildResponseMessage(MuleEvent event, Object[] response) 
 201  
     {
 202  50
         MuleMessage result = null;
 203  50
         if (response != null && response.length <= 1)
 204  
         {
 205  40
             if (response.length == 1)
 206  
             {
 207  40
                 result = new DefaultMuleMessage(response[0], event.getMessage());
 208  
             }
 209  
         }
 210  
         else
 211  
         {
 212  10
             result = new DefaultMuleMessage(response, event.getMessage());
 213  
         }
 214  
 
 215  50
         return result;
 216  
     }
 217  
     protected void doDispatch(MuleEvent event) throws Exception
 218  
     {
 219  8
         doSend(event);
 220  8
     }
 221  
 
 222  
     public String parseSoapAction(String soapAction, QName method, MuleEvent event)
 223  
     {
 224  0
         EndpointURI endpointURI = event.getEndpoint().getEndpointURI();
 225  0
         Map<String, String> properties = new HashMap<String, String>();
 226  0
         MuleMessage msg = event.getMessage();
 227  0
         for (Iterator<?> iterator = msg.getPropertyNames().iterator(); iterator.hasNext();)
 228  
         {
 229  0
             String propertyKey = (String)iterator.next();
 230  0
             properties.put(propertyKey, msg.getProperty(propertyKey).toString());
 231  0
         }
 232  0
         properties.put(MuleProperties.MULE_METHOD_PROPERTY, method.getLocalPart());
 233  0
         properties.put("methodNamespace", method.getNamespaceURI());
 234  0
         properties.put("address", endpointURI.getAddress());
 235  0
         properties.put("scheme", endpointURI.getScheme());
 236  0
         properties.put("host", endpointURI.getHost());
 237  0
         properties.put("port", String.valueOf(endpointURI.getPort()));
 238  0
         properties.put("path", endpointURI.getPath());
 239  0
         properties.put("hostInfo", endpointURI.getScheme()
 240  
                                    + "://"
 241  
                                    + endpointURI.getHost()
 242  
                                    + (endpointURI.getPort() > -1
 243  
                                                    ? ":" + String.valueOf(endpointURI.getPort()) : ""));
 244  0
         if (event.getService() != null)
 245  
         {
 246  0
             properties.put("serviceName", event.getService().getName());
 247  
         }
 248  
 
 249  0
         soapAction = soapActionTemplateParser.parse(properties, soapAction);
 250  
 
 251  0
         if (logger.isDebugEnabled())
 252  
         {
 253  0
             logger.debug("SoapAction for this call is: " + soapAction);
 254  
         }
 255  
 
 256  0
         return soapAction;
 257  
     }
 258  
 }