Coverage Report - org.mule.transport.soap.axis.extensions.UniversalSender
 
Classes in this File Line Coverage Branch Coverage Complexity
UniversalSender
0%
0/118
0%
0/62
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transport.soap.axis.extensions;
 8  
 
 9  
 import org.mule.DefaultMuleEvent;
 10  
 import org.mule.DefaultMuleMessage;
 11  
 import org.mule.MessageExchangePattern;
 12  
 import org.mule.RequestContext;
 13  
 import org.mule.api.MuleContext;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleException;
 16  
 import org.mule.api.MuleMessage;
 17  
 import org.mule.api.MuleSession;
 18  
 import org.mule.api.config.MuleProperties;
 19  
 import org.mule.api.endpoint.EndpointBuilder;
 20  
 import org.mule.api.endpoint.EndpointURI;
 21  
 import org.mule.api.endpoint.ImmutableEndpoint;
 22  
 import org.mule.api.endpoint.OutboundEndpoint;
 23  
 import org.mule.api.processor.MessageProcessor;
 24  
 import org.mule.api.routing.OutboundRouter;
 25  
 import org.mule.api.routing.OutboundRouterCollection;
 26  
 import org.mule.api.service.Service;
 27  
 import org.mule.endpoint.EndpointURIEndpointBuilder;
 28  
 import org.mule.endpoint.MuleEndpointURI;
 29  
 import org.mule.module.cxf.SoapConstants;
 30  
 import org.mule.session.DefaultMuleSession;
 31  
 import org.mule.transport.http.HttpConstants;
 32  
 import org.mule.transport.soap.axis.AxisConnector;
 33  
 import org.mule.transport.soap.axis.extras.AxisCleanAndAddProperties;
 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  
     protected MuleContext muleContext;
 69  
 
 70  
 
 71  
     public void invoke(MessageContext msgContext) throws AxisFault
 72  
     {
 73  
         try
 74  
         {
 75  0
             boolean sync = true;
 76  0
             Call call = (Call)msgContext.getProperty("call_object");
 77  
 
 78  0
             if (call == null)
 79  
             {
 80  0
                 throw new IllegalStateException(
 81  
                     "The call_object property must be set on the message context to the client Call object");
 82  
             }
 83  
 
 84  0
             muleContext = (MuleContext)call.getProperty(MuleProperties.MULE_CONTEXT_PROPERTY);
 85  0
             if(muleContext==null)
 86  
             {
 87  0
                 throw new IllegalArgumentException("Property org.mule.MuleContext not set on Axis MessageContext");
 88  
             }
 89  
 
 90  
             // Get the event stored in call if a request call is made there will be no event
 91  0
             MuleEvent event = (MuleEvent)call.getProperty(MuleProperties.MULE_EVENT_PROPERTY);
 92  
 
 93  0
             if (Boolean.TRUE.equals(call.getProperty("axis.one.way")))
 94  
             {
 95  0
                 sync = false;
 96  
             }
 97  
 
 98  
             // Get the dispatch endpoint
 99  0
             String uri = msgContext.getStrProp(MessageContext.TRANS_URL);
 100  0
             ImmutableEndpoint requestEndpoint = (ImmutableEndpoint)call
 101  
                 .getProperty(MuleProperties.MULE_ENDPOINT_PROPERTY);
 102  
 
 103  
             OutboundEndpoint endpoint;
 104  
 
 105  
             // put username and password in URI if they are set on the current event
 106  0
             if (msgContext.getUsername() != null)
 107  
             {
 108  0
                 String[] tempEndpoint = uri.split("//");
 109  0
                 String credentialString = msgContext.getUsername() + ":"
 110  
                                           + msgContext.getPassword();
 111  0
                 uri = tempEndpoint[0] + "//" + credentialString + "@" + tempEndpoint[1];
 112  0
                 endpoint = lookupEndpoint(uri);
 113  0
             }
 114  
             else
 115  
             {
 116  0
                 endpoint = lookupEndpoint(uri);
 117  
             }
 118  
 
 119  0
             if (requestEndpoint.getConnector() instanceof AxisConnector)
 120  
             {
 121  0
                 msgContext.setTypeMappingRegistry(((AxisConnector)requestEndpoint.getConnector())
 122  
                     .getAxis().getTypeMappingRegistry());
 123  
             }
 124  
 
 125  0
             Map<String, Object> props = new HashMap<String, Object>();
 126  
             Object payload;
 127  0
             int contentLength = 0;
 128  0
             String contentType = null;
 129  0
             if (msgContext.getRequestMessage().countAttachments() > 0)
 130  
             {
 131  0
                 File temp = File.createTempFile("soap", ".tmp");
 132  0
                 temp.deleteOnExit(); // TODO cleanup files earlier (IOUtils has a
 133  
                 // file tracker)
 134  0
                 FileOutputStream fos = new FileOutputStream(temp);
 135  0
                 msgContext.getRequestMessage().writeTo(fos);
 136  0
                 fos.close();
 137  0
                 contentLength = (int)temp.length();
 138  0
                 payload = new FileInputStream(temp);
 139  0
                 contentType = "multipart/related";
 140  0
             }
 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  
             // props.putAll(event.getProperties());
 150  0
             for (Iterator iterator = msgContext.getPropertyNames(); iterator.hasNext();)
 151  
             {
 152  0
                 String name = (String)iterator.next();
 153  0
                 if (!name.equals("call_object") && !name.equals("wsdl.service"))
 154  
                 {
 155  0
                     props.put(name, msgContext.getProperty(name));
 156  
                 }
 157  0
             }
 158  
 
 159  
             // add all custom headers, filter out all mule headers (such as
 160  
             // MULE_SESSION) except
 161  
             // for MULE_USER header. Filter out other headers like "soapMethods" and
 162  
             // MuleProperties.MULE_METHOD_PROPERTY and "soapAction"
 163  
             // and also filter out any http related header
 164  0
             if ((RequestContext.getEvent() != null)
 165  
                 && (RequestContext.getEvent().getMessage() != null))
 166  
             {
 167  0
                 props = AxisCleanAndAddProperties.cleanAndAdd(RequestContext.getEventContext());
 168  
             }
 169  
 
 170  
             // 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
 171  0
             String scheme = requestEndpoint.getEndpointURI().getScheme();
 172  0
             if (!("vm".equalsIgnoreCase(scheme) || "jms".equalsIgnoreCase(scheme)))
 173  
             {
 174  0
                 if (call.useSOAPAction())
 175  
                 {
 176  0
                     uri = call.getSOAPActionURI();
 177  
                 }
 178  0
                 props.put(SoapConstants.SOAP_ACTION_PROPERTY_CAPS, uri);
 179  
             }
 180  0
             if (contentLength > 0)
 181  
             {
 182  0
                 props.put(HttpConstants.HEADER_CONTENT_LENGTH, Integer.toString(contentLength)); // necessary
 183  
                 // for
 184  
                 // supporting
 185  
                 // httpclient
 186  
             }
 187  
 
 188  
 
 189  0
             if (props.get(HttpConstants.HEADER_CONTENT_TYPE) == null)
 190  
             {
 191  0
                 if (contentType == null)
 192  
                 {
 193  0
                     contentType = "text/xml";
 194  
                 }
 195  
 
 196  0
                 props.put(HttpConstants.HEADER_CONTENT_TYPE, contentType);
 197  
             }
 198  0
             MuleMessage message = new DefaultMuleMessage(payload, props, muleContext);
 199  
             MuleSession session;
 200  
 
 201  0
             if(event != null)
 202  
             {
 203  0
                 session = event.getSession();
 204  
             }
 205  
             else
 206  
             {
 207  0
                 session = new DefaultMuleSession(muleContext);
 208  
             }
 209  
 
 210  0
             logger.info("Making Axis soap request on: " + uri);
 211  0
             if (logger.isDebugEnabled())
 212  
             {
 213  0
                 logger.debug("Soap request is:\n" + new String((payload instanceof byte[] ? (byte[])payload : payload.toString().getBytes())));
 214  
             }
 215  
 
 216  0
             if (sync)
 217  
             {
 218  0
                 EndpointBuilder builder = new EndpointURIEndpointBuilder(endpoint);
 219  0
                 builder.setExchangePattern(MessageExchangePattern.REQUEST_RESPONSE);
 220  0
                 OutboundEndpoint syncEndpoint = muleContext.getEndpointFactory()
 221  
                     .getOutboundEndpoint(builder);
 222  0
                 MuleEvent dispatchEvent = new DefaultMuleEvent(message, syncEndpoint, session);
 223  0
                 MuleMessage result = null;
 224  0
                 MuleEvent resultEvent = syncEndpoint.process(dispatchEvent);
 225  0
                 if (resultEvent != null)
 226  
                 {
 227  0
                     result = resultEvent.getMessage();
 228  
                 }
 229  
 
 230  0
                 if (result != null)
 231  
                 {
 232  0
                     byte[] response = result.getPayloadAsBytes();
 233  0
                     Message responseMessage = new Message(response);
 234  0
                     msgContext.setResponseMessage(responseMessage);
 235  
 
 236  0
                 }
 237  
                 else
 238  
                 {
 239  0
                     logger
 240  
                         .warn("No response message was returned from synchronous call to: " + uri);
 241  
                 }
 242  
                 // remove temp file created for streaming
 243  0
                 if (payload instanceof File)
 244  
                 {
 245  0
                     ((File)payload).delete();
 246  
                 }
 247  0
             }
 248  
             else
 249  
             {
 250  0
                 MuleEvent dispatchEvent = new DefaultMuleEvent(message, endpoint, session);
 251  0
                 endpoint.process(dispatchEvent);
 252  
             }
 253  
         }
 254  0
         catch (Exception e)
 255  
         {
 256  0
             if (e instanceof AxisFault)
 257  
             {
 258  0
                 throw (AxisFault) e;
 259  
             }
 260  
             else
 261  
             {
 262  0
                 throw new AxisFault(e.getMessage(), e);
 263  
             }
 264  0
         }
 265  
 
 266  0
     }
 267  
 
 268  
     protected OutboundEndpoint lookupEndpoint(String uri) throws MuleException
 269  
     {
 270  0
         Service axis = muleContext.getRegistry().lookupService(AxisConnector.AXIS_SERVICE_COMPONENT_NAME);
 271  0
         EndpointURI endpoint = new MuleEndpointURI(uri, muleContext);
 272  
 
 273  
         OutboundEndpoint ep;
 274  
 
 275  0
         if (axis != null)
 276  
         {
 277  0
             synchronized (endpointsCache)
 278  
             {
 279  0
                 ep = (OutboundEndpoint) endpointsCache.get(endpoint.getAddress());
 280  0
                 if (ep == null)
 281  
                 {
 282  0
                     updateEndpointCache((OutboundRouterCollection) axis.getOutboundMessageProcessor());
 283  0
                     ep = (OutboundEndpoint) endpointsCache.get(endpoint.getAddress());
 284  0
                     if (ep == null)
 285  
                     {
 286  0
                         logger.debug("Dispatch Endpoint uri: " + uri
 287  
                                      + " not found on the cache. Creating the endpoint instead.");
 288  0
                         ep = muleContext.getEndpointFactory().getOutboundEndpoint(uri);
 289  
                     }
 290  
                     else
 291  
                     {
 292  0
                         logger.info("Found endpoint: " + uri + " on the Axis service component");
 293  
                     }
 294  
                 }
 295  
                 else
 296  
                 {
 297  0
                     logger.info("Found endpoint: " + uri + " on the Axis service component");
 298  
                 }
 299  0
             }
 300  
         }
 301  
         else
 302  
         {
 303  0
             ep = muleContext.getEndpointFactory().getOutboundEndpoint(uri);
 304  
         }
 305  0
         return ep;
 306  
     }
 307  
 
 308  
     private void updateEndpointCache(OutboundRouterCollection router)
 309  
     {
 310  0
         endpointsCache.clear();
 311  0
         for (Iterator iterator = router.getRoutes().iterator(); iterator.hasNext();)
 312  
         {
 313  0
             OutboundRouter r = (OutboundRouter)iterator.next();
 314  0
             for (MessageProcessor mp : r.getRoutes())
 315  
             {
 316  0
                 if (mp instanceof ImmutableEndpoint)
 317  
                 {
 318  0
                     ImmutableEndpoint endpoint = (ImmutableEndpoint) mp;
 319  0
                     endpointsCache.put(endpoint.getEndpointURI().getAddress(), endpoint);
 320  0
                 }
 321  
             }
 322  0
         }
 323  0
     }
 324  
 }