Coverage Report - org.mule.providers.soap.axis.extensions.UniversalSender
 
Classes in this File Line Coverage Branch Coverage Complexity
UniversalSender
0%
0/106
0%
0/21
11
 
 1  
 /*
 2  
  * $Id: UniversalSender.java 7976 2007-08-21 14:26:13Z dirk.olmes $
 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.providers.soap.axis.extensions;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.config.MuleProperties;
 15  
 import org.mule.impl.MuleEvent;
 16  
 import org.mule.impl.MuleMessage;
 17  
 import org.mule.impl.RequestContext;
 18  
 import org.mule.impl.endpoint.MuleEndpoint;
 19  
 import org.mule.impl.endpoint.MuleEndpointURI;
 20  
 import org.mule.impl.model.ModelHelper;
 21  
 import org.mule.providers.http.HttpConstants;
 22  
 import org.mule.providers.soap.axis.AxisConnector;
 23  
 import org.mule.providers.soap.axis.extras.AxisCleanAndAddProperties;
 24  
 import org.mule.umo.UMODescriptor;
 25  
 import org.mule.umo.UMOEvent;
 26  
 import org.mule.umo.UMOException;
 27  
 import org.mule.umo.UMOMessage;
 28  
 import org.mule.umo.UMOSession;
 29  
 import org.mule.umo.endpoint.UMOEndpoint;
 30  
 import org.mule.umo.endpoint.UMOEndpointURI;
 31  
 import org.mule.umo.endpoint.UMOImmutableEndpoint;
 32  
 import org.mule.umo.routing.UMOOutboundRouter;
 33  
 import org.mule.umo.routing.UMOOutboundRouterCollection;
 34  
 
 35  
 import java.io.File;
 36  
 import java.io.FileInputStream;
 37  
 import java.io.FileOutputStream;
 38  
 import java.util.HashMap;
 39  
 import java.util.Iterator;
 40  
 import java.util.Map;
 41  
 
 42  
 import org.apache.axis.AxisFault;
 43  
 import org.apache.axis.Message;
 44  
 import org.apache.axis.MessageContext;
 45  
 import org.apache.axis.client.Call;
 46  
 import org.apache.axis.handlers.BasicHandler;
 47  
 import org.apache.commons.io.output.ByteArrayOutputStream;
 48  
 import org.apache.commons.logging.Log;
 49  
 import org.apache.commons.logging.LogFactory;
 50  
 
 51  
 /**
 52  
  * An Axis handler that will dispatch the SOAP event via a Mule endpoint
 53  
  */
 54  0
 public class UniversalSender extends BasicHandler
 55  
 {
 56  
     /**
 57  
      * Serial version
 58  
      */
 59  
     private static final long serialVersionUID = 7943380365092172940L;
 60  
 
 61  
     /**
 62  
      * logger used by this class
 63  
      */
 64  0
     protected transient Log logger = LogFactory.getLog(getClass());
 65  
 
 66  0
     protected Map endpointsCache = new HashMap();
 67  
 
 68  
     public void invoke(MessageContext msgContext) throws AxisFault
 69  
     {
 70  0
         boolean sync = true;
 71  0
         Call call = (Call)msgContext.getProperty("call_object");
 72  0
         if (call == null)
 73  
         {
 74  0
             throw new IllegalStateException(
 75  
                 "The call_object property must be set on the message context to the client Call object");
 76  
         }
 77  0
         if (Boolean.TRUE.equals(call.getProperty("axis.one.way")))
 78  
         {
 79  0
             sync = false;
 80  
         }
 81  
         // Get the event stored in call
 82  
         // If a receive call is made there will be no event
 83  
         // UMOEvent event =
 84  
         // (UMOEvent)call.getProperty(MuleProperties.MULE_EVENT_PROPERTY);
 85  
         // Get the dispatch endpoint
 86  0
         String uri = msgContext.getStrProp(MessageContext.TRANS_URL);
 87  0
         UMOImmutableEndpoint requestEndpoint = (UMOImmutableEndpoint)call
 88  
             .getProperty(MuleProperties.MULE_ENDPOINT_PROPERTY);
 89  0
         UMOImmutableEndpoint endpoint = null;
 90  
 
 91  
         // put username and password in URI if they are set on the current event
 92  0
         if (msgContext.getUsername() != null)
 93  
         {
 94  0
             String[] tempEndpoint = uri.split("//");
 95  0
             String credentialString = msgContext.getUsername() + ":"
 96  
                                       + msgContext.getPassword();
 97  0
             uri = tempEndpoint[0] + "//" + credentialString + "@" + tempEndpoint[1];
 98  
             try
 99  
             {
 100  0
                 endpoint = lookupEndpoint(uri);
 101  
             }
 102  0
             catch (UMOException e)
 103  
             {
 104  0
                 requestEndpoint.getConnector().handleException(e);
 105  0
                 return;
 106  0
             }
 107  
         }
 108  
         else
 109  
         {
 110  
             try
 111  
             {
 112  0
                 endpoint = lookupEndpoint(uri);
 113  
             }
 114  0
             catch (UMOException e)
 115  
             {
 116  0
                 requestEndpoint.getConnector().handleException(e);
 117  0
                 return;
 118  0
             }
 119  
         }
 120  
 
 121  
         try
 122  
         {
 123  0
             if (requestEndpoint.getConnector() instanceof AxisConnector)
 124  
             {
 125  0
                 msgContext.setTypeMappingRegistry(((AxisConnector)requestEndpoint.getConnector())
 126  
                     .getAxisServer().getTypeMappingRegistry());
 127  
             }
 128  0
             Object payload = null;
 129  0
             int contentLength = 0;
 130  0
             if (msgContext.getRequestMessage().countAttachments() > 0)
 131  
             {
 132  0
                 File temp = File.createTempFile("soap", ".tmp");
 133  0
                 temp.deleteOnExit(); // TODO cleanup files earlier (IOUtils has a
 134  
                 // file tracker)
 135  0
                 FileOutputStream fos = new FileOutputStream(temp);
 136  0
                 msgContext.getRequestMessage().writeTo(fos);
 137  0
                 fos.close();
 138  0
                 contentLength = (int)temp.length();
 139  0
                 payload = new FileInputStream(temp);
 140  
             }
 141  
             else
 142  
             {
 143  0
                 ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
 144  0
                 msgContext.getRequestMessage().writeTo(baos);
 145  0
                 baos.close();
 146  0
                 payload = baos.toByteArray();
 147  
             }
 148  
 
 149  0
             Map props = new HashMap();
 150  
             // props.putAll(event.getProperties());
 151  0
             for (Iterator iterator = msgContext.getPropertyNames(); iterator.hasNext();)
 152  
             {
 153  0
                 String name = (String)iterator.next();
 154  0
                 if (!name.equals("call_object") && !name.equals("wsdl.service"))
 155  
                 {
 156  0
                     props.put(name, msgContext.getProperty(name));
 157  
                 }
 158  
             }
 159  
 
 160  
             // add all custom headers, filter out all mule headers (such as
 161  
             // MULE_SESSION) except
 162  
             // for MULE_USER header. Filter out other headers like "soapMethods" and
 163  
             // MuleProperties.MULE_METHOD_PROPERTY and "soapAction"
 164  
             // and also filter out any http related header
 165  0
             if ((RequestContext.getEvent() != null)
 166  
                 && (RequestContext.getEvent().getMessage() != null))
 167  
             {
 168  0
                 props = AxisCleanAndAddProperties.cleanAndAdd(RequestContext.getEventContext());
 169  
             }
 170  
             
 171  
             // with jms and vm the default SOAPAction will result in the name of the endpoint, which we may not necessarily want. This should be set manually on the endpoint
 172  0
             String scheme = requestEndpoint.getEndpointURI().getScheme(); 
 173  0
             if (!("vm".equalsIgnoreCase(scheme) || "jms".equalsIgnoreCase(scheme)))
 174  
             {
 175  0
                 if (call.useSOAPAction())
 176  
                 {
 177  0
                     uri = call.getSOAPActionURI();
 178  
                 }
 179  0
                 props.put("SOAPAction", uri);
 180  
             }
 181  0
             if (contentLength > 0)
 182  
             {
 183  0
                 props.put(HttpConstants.HEADER_CONTENT_LENGTH, Integer.toString(contentLength)); // necessary
 184  
                 // for
 185  
                 // supporting
 186  
                 // httpclient
 187  
             }
 188  
 
 189  0
             if (props.get(HttpConstants.HEADER_CONTENT_TYPE) == null)
 190  
             {
 191  0
                 props.put(HttpConstants.HEADER_CONTENT_TYPE, "text/xml");
 192  
             }
 193  0
             UMOMessage message = new MuleMessage(payload, props);
 194  0
             UMOSession session = RequestContext.getEventContext().getSession();
 195  
 
 196  0
             UMOEvent dispatchEvent = new MuleEvent(message, endpoint, session, sync);
 197  0
             logger.info("Making Axis soap request on: " + uri);
 198  0
             if (logger.isDebugEnabled())
 199  
             {
 200  0
                 logger.debug("Soap request is:\n" + payload.toString());
 201  
             }
 202  0
             if (sync)
 203  
             {
 204  
                 // We need to rewrite the endpoint on the event to set the
 205  
                 // reomoteSync property
 206  0
                 MuleEndpoint syncEndpoint = new MuleEndpoint(dispatchEvent.getEndpoint());
 207  0
                 syncEndpoint.setRemoteSync(true);
 208  0
                 dispatchEvent = new MuleEvent(dispatchEvent.getMessage(), syncEndpoint,
 209  
                     dispatchEvent.getSession(), dispatchEvent.isSynchronous());
 210  
                 
 211  
                 //set username and password
 212  
                 
 213  
                 
 214  0
                 UMOMessage result = session.sendEvent(dispatchEvent);
 215  0
                 if (result != null)
 216  
                 {
 217  0
                     byte[] response = result.getPayloadAsBytes();
 218  0
                     Message responseMessage = new Message(response);
 219  0
                     msgContext.setResponseMessage(responseMessage);
 220  
 
 221  
                 }
 222  
                 else
 223  
                 {
 224  0
                     logger
 225  
                         .warn("No response message was returned from synchronous call to: " + uri);
 226  
                 }
 227  
                 // remove temp file created for streaming
 228  0
                 if (payload instanceof File)
 229  
                 {
 230  0
                     ((File)payload).delete();
 231  
                 }
 232  
             }
 233  
             else
 234  
             {
 235  0
                 session.dispatchEvent(dispatchEvent);
 236  
             }
 237  
         }
 238  0
         catch (AxisFault axisFault)
 239  
         {
 240  0
             throw axisFault;
 241  
         }
 242  0
         catch (Exception e)
 243  
         {
 244  0
             throw new AxisFault(e.getMessage(), new Throwable(e));
 245  0
         }
 246  
 
 247  0
     }
 248  
 
 249  
     protected UMOEndpoint lookupEndpoint(String uri) throws UMOException
 250  
     {
 251  0
         UMODescriptor axis = MuleManager.getInstance().lookupModel(ModelHelper.SYSTEM_MODEL)
 252  
             .getDescriptor(AxisConnector.AXIS_SERVICE_COMPONENT_NAME);
 253  0
         UMOEndpointURI endpoint = new MuleEndpointURI(uri);
 254  
         UMOEndpoint ep;
 255  0
         if (axis != null)
 256  
         {
 257  0
             synchronized (endpointsCache)
 258  
             {
 259  0
                 ep = (UMOEndpoint)endpointsCache.get(endpoint.getAddress());
 260  0
                 if (ep == null)
 261  
                 {
 262  0
                     updateEndpointCache(axis.getOutboundRouter());
 263  0
                     ep = (UMOEndpoint)endpointsCache.get(endpoint.getAddress());
 264  0
                     if (ep == null)
 265  
                     {
 266  0
                         logger.debug("Dispatch Endpoint uri: " + uri
 267  
                                      + " not found on the cache. Creating the endpoint instead.");
 268  0
                         ep = new MuleEndpoint(uri, false);
 269  
                     }
 270  
                     else
 271  
                     {
 272  0
                         logger.info("Found endpoint: " + uri + " on the Axis service component");
 273  
                     }
 274  
                 }
 275  
                 else
 276  
                 {
 277  0
                     logger.info("Found endpoint: " + uri + " on the Axis service component");
 278  
                 }
 279  0
             }
 280  
         }
 281  
         else
 282  
         {
 283  0
             ep = new MuleEndpoint(uri, false);
 284  
         }
 285  0
         return ep;
 286  
     }
 287  
 
 288  
     private void updateEndpointCache(UMOOutboundRouterCollection router)
 289  
     {
 290  0
         endpointsCache.clear();
 291  0
         for (Iterator iterator = router.getRouters().iterator(); iterator.hasNext();)
 292  
         {
 293  0
             UMOOutboundRouter r = (UMOOutboundRouter)iterator.next();
 294  0
             for (Iterator iterator1 = r.getEndpoints().iterator(); iterator1.hasNext();)
 295  
             {
 296  0
                 UMOEndpoint endpoint = (UMOEndpoint)iterator1.next();
 297  0
                 endpointsCache.put(endpoint.getEndpointURI().getAddress(), endpoint);
 298  
             }
 299  
         }
 300  0
     }
 301  
 }