View Javadoc

1   /*
2    * $Id: AxisServiceComponent.java 22439 2011-07-18 19:06:39Z dfeist $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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.soap.axis;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.RequestContext;
15  import org.mule.api.MessagingException;
16  import org.mule.api.MuleEventContext;
17  import org.mule.api.MuleException;
18  import org.mule.api.MuleMessage;
19  import org.mule.api.config.MuleProperties;
20  import org.mule.api.endpoint.EndpointURI;
21  import org.mule.api.lifecycle.Callable;
22  import org.mule.api.lifecycle.Initialisable;
23  import org.mule.api.lifecycle.InitialisationException;
24  import org.mule.api.transport.PropertyScope;
25  import org.mule.config.MuleManifest;
26  import org.mule.config.i18n.CoreMessages;
27  import org.mule.config.i18n.MessageFactory;
28  import org.mule.endpoint.MuleEndpointURI;
29  import org.mule.module.cxf.SoapConstants;
30  import org.mule.transport.http.HttpConnector;
31  import org.mule.transport.http.HttpConstants;
32  import org.mule.transport.soap.axis.extensions.AxisMuleSession;
33  import org.mule.transport.soap.axis.extensions.MuleConfigProvider;
34  import org.mule.util.StringUtils;
35  
36  import java.io.ByteArrayInputStream;
37  import java.io.ByteArrayOutputStream;
38  import java.io.File;
39  import java.io.FileInputStream;
40  import java.io.IOException;
41  import java.util.ArrayList;
42  import java.util.HashMap;
43  import java.util.Iterator;
44  import java.util.Map;
45  import java.util.Properties;
46  import java.util.Set;
47  
48  import javax.xml.namespace.QName;
49  
50  import org.apache.axis.AxisEngine;
51  import org.apache.axis.AxisFault;
52  import org.apache.axis.ConfigurationException;
53  import org.apache.axis.Constants;
54  import org.apache.axis.Message;
55  import org.apache.axis.MessageContext;
56  import org.apache.axis.description.OperationDesc;
57  import org.apache.axis.description.ServiceDesc;
58  import org.apache.axis.handlers.soap.SOAPService;
59  import org.apache.axis.i18n.Messages;
60  import org.apache.axis.security.servlet.ServletSecurityProvider;
61  import org.apache.axis.server.AxisServer;
62  import org.apache.axis.transport.http.HTTPConstants;
63  import org.apache.axis.transport.http.ServletEndpointContextImpl;
64  import org.apache.axis.utils.Admin;
65  import org.apache.axis.utils.XMLUtils;
66  import org.apache.commons.logging.Log;
67  import org.w3c.dom.Document;
68  
69  /**
70   * <code>AxisServiceComponent</code> is a Mule component implementation of the Axis
71   * servlet. This component supports all the features of the Axis servlet except -
72   * <ol>
73   * <li>Jws class services are not supported as they don't add any value to the Mule�
74   * model</li>
75   * <li>Currently there is no HttpSession support. This will be fixed when MuleSession
76   * support is added to the Http Connector</li>
77   * </ol>
78   */
79  
80  public class AxisServiceComponent implements Initialisable, Callable
81  {
82      protected static final Log logger = org.apache.commons.logging.LogFactory.getLog(AxisServiceComponent.class);
83  
84      public static final String INIT_PROPERTY_TRANSPORT_NAME = "transport.name";
85      public static final String INIT_PROPERTY_USE_SECURITY = "use-servlet-security";
86      public static final String INIT_PROPERTY_ENABLE_LIST = "axis.enableListQuery";
87      public static final String DEFAULT_AXIS_HOME = "/axisHome";
88  
89      private String transportName = "http";
90      private ServletSecurityProvider securityProvider = null;
91      private boolean enableList = true;
92      private String homeDir;
93      private AxisServer axis;
94  
95      /** For IoC */
96      public AxisServiceComponent()
97      {
98          // do nothing
99      }
100 
101     /**
102      * Passes the context to the listener
103      * 
104      * @param context the context to process
105      * @return Object this object can be anything. When the
106      *         <code>LifecycleAdapter</code> for the component receives this
107      *         object it will first see if the Object is an <code>MuleEvent</code>
108      *         if not and the Object is not null a new context will be created using
109      *         the returned object as the payload. This new context will then get
110      *         published to the configured outbound endpoint if-
111      *         <ol>
112      *         <li>One has been configured for the component.</li>
113      *         <li>the <code>setStopFurtherProcessing(true)</code> wasn't called
114      *         on the previous context.</li>
115      *         </ol>
116      * @throws Exception if the context fails to process properly. If exceptions
117      *             aren't handled by the implementation they will be handled by the
118      *             exceptionListener associated with the component
119      */
120     public Object onCall(MuleEventContext context) throws Exception
121     {
122         AxisStringWriter response = new AxisStringWriter();
123         String method = context.getMessage().getInboundProperty(HttpConnector.HTTP_METHOD_PROPERTY, HttpConstants.METHOD_POST);
124         if (HttpConstants.METHOD_GET.equalsIgnoreCase(method))
125         {
126             doGet(context, response);
127         }
128         else
129         {
130             doPost(context, response);
131         }
132         response.close();
133         
134         String payload = response.getWriter().toString();
135         Map<String, Object> properties = response.getProperties();
136         return new DefaultMuleMessage(payload, properties, context.getMuleContext());
137     }
138 
139     public void initialise() throws InitialisationException
140     {
141         if (axis == null)
142         {
143             throw new InitialisationException(MessageFactory.createStaticMessage("No Axis instance, this component has not been initialized properly."), this);
144         }
145     }
146 
147     public void doGet(MuleEventContext context, AxisStringWriter response)
148         throws MuleException, IOException
149     {
150         try
151         {
152             // We parse a new uri based on the listening host and port with the
153             // request parameters appended
154             // Using the soap prefix ensures that we use a soap endpoint builder
155             EndpointURI endpointUri = new MuleEndpointURI(context.getEndpointURI().toString(), context.getMuleContext());
156             //We need to re-parse the URI here because we are only give the listening endpoint, not the actual
157             //request endpoint. The request endpoint needs to have the query parameters from the client
158             //There is no need to do this for Servlet because it does things differently
159             if (!"true".equalsIgnoreCase((String) context.getMessage().getInvocationProperty("servlet.endpoint")))
160             {
161                 String uri = SoapConstants.SOAP_ENDPOINT_PREFIX + context.getEndpointURI().getScheme()
162                                 + "://" + context.getEndpointURI().getHost() + ":"
163                                 + context.getEndpointURI().getPort();
164                 uri += context.getMessage().getInboundProperty(HttpConnector.HTTP_REQUEST_PROPERTY, StringUtils.EMPTY);
165                 endpointUri = new MuleEndpointURI(uri, context.getMuleContext());
166             }
167 
168             endpointUri.initialise();
169             
170             AxisEngine engine = getAxis();
171             String pathInfo = endpointUri.getPath();
172             boolean wsdlRequested = false;
173             boolean listRequested = false;
174 
175             if (endpointUri.getAddress().endsWith(".jws"))
176             {
177                 throw new AxisFault("Jws not supported by the Mule Axis service");
178             }
179 
180             String queryString = endpointUri.getQuery();
181             if (queryString != null)
182             {
183                 if (queryString.equalsIgnoreCase(SoapConstants.WSDL_PROPERTY))
184                 {
185                     wsdlRequested = true;
186                 }
187                 else
188                 {
189                     if (queryString.equalsIgnoreCase(SoapConstants.LIST_PROPERTY))
190                     {
191                         listRequested = true;
192                     }
193                 }
194             }
195 
196             boolean hasNoPath = (StringUtils.isEmpty(pathInfo) || pathInfo.equals("/"));
197             if (!wsdlRequested && !listRequested && hasNoPath)
198             {
199                 reportAvailableServices(context, response);
200             }
201             else
202             {
203                 MessageContext msgContext = new MessageContext(engine);
204                 populateMessageContext(msgContext, context, endpointUri);
205 
206                 msgContext.setProperty("transport.url", endpointUri.toString());
207                 if (wsdlRequested)
208                 {
209                     processWsdlRequest(msgContext, response);
210                 }
211                 else if (listRequested)
212                 {
213                     processListRequest(response);
214                 }
215                 else
216                 {
217                     processMethodRequest(msgContext, context, response, endpointUri);
218                 }
219             }
220         }
221         catch (AxisFault fault)
222         {
223             reportTroubleInGet(fault, response);
224         }
225         catch (Exception e)
226         {
227             reportTroubleInGet(e, response);
228         }
229     }
230 
231     protected void doPost(MuleEventContext context, AxisStringWriter response)
232         throws Exception
233     {
234         String soapAction;
235         Message responseMsg;
236         AxisEngine engine = getAxis();
237         if (engine == null)
238         {
239 
240             throw new MessagingException(CoreMessages.objectIsNull("Axis Engine"), context.getMessage());
241         }
242         MessageContext msgContext = new MessageContext(engine);
243 
244         String contentType;
245         try
246         {
247             EndpointURI endpointUri = new MuleEndpointURI(context.getEndpointURI().toString(), context.getMuleContext());
248             endpointUri.initialise();
249             populateMessageContext(msgContext, context, endpointUri);
250             if (securityProvider != null)
251             {
252                 if (logger.isDebugEnabled())
253                 {
254                     logger.debug("securityProvider:" + securityProvider);
255                 }
256                 msgContext.setProperty("securityProvider", securityProvider);
257             }
258 
259             Object request = context.getMessage().getPayload();
260             if (request instanceof File)
261             {
262                 request = new FileInputStream((File)request);
263             }
264             else if (request instanceof byte[])
265             {
266                 request = new ByteArrayInputStream((byte[])request);
267             }
268 
269             final String cType = context.getMessage().getInboundProperty(HTTPConstants.HEADER_CONTENT_TYPE);
270             final String cLocation = context.getMessage().getInboundProperty(HTTPConstants.HEADER_CONTENT_LOCATION);
271             Message requestMsg = new Message(request, false, cType, cLocation);
272 
273             if (logger.isDebugEnabled())
274             {
275                 logger.debug("Request Message:" + requestMsg);
276             }
277             msgContext.setRequestMessage(requestMsg);
278             msgContext.setProperty("transport.url", endpointUri.toString());
279 
280             soapAction = getSoapAction(context);
281             if (soapAction != null)
282             {
283                 msgContext.setUseSOAPAction(true);
284                 msgContext.setSOAPActionURI(soapAction);
285             }
286             msgContext.setSession(new AxisMuleSession(context.getSession()));
287 
288             if (logger.isDebugEnabled())
289             {
290                 logger.debug("Invoking Axis Engine.");
291             }
292             populateAxisProperties();
293             engine.invoke(msgContext);
294             if (logger.isDebugEnabled())
295             {
296                 logger.debug("Return from Axis Engine.");
297             }
298             if (RequestContext.getExceptionPayload() instanceof Exception)
299             {
300                 throw (Exception)RequestContext.getExceptionPayload().getException();
301             }
302             // remove temporary file used for soap message with attachment
303             if (request instanceof File)
304             {
305                 ((File)request).delete();
306             }
307             responseMsg = msgContext.getResponseMessage();
308             if (responseMsg == null)
309             {
310                 throw new Exception(Messages.getMessage("noResponse01"));
311             }
312         }
313         catch (AxisFault fault)
314         {
315             logger.error(fault.toString() + " target service is: " + msgContext.getTargetService()
316                             + ". MuleEvent is: " + context.toString(), fault);
317             processAxisFault(fault);
318             configureResponseFromAxisFault(response, fault);
319             responseMsg = msgContext.getResponseMessage();
320             if (responseMsg == null)
321             {
322                 responseMsg = new Message(fault);
323             }
324         }
325         catch (Exception e)
326         {
327             responseMsg = msgContext.getResponseMessage();
328             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
329             responseMsg = convertExceptionToAxisFault(e, responseMsg);
330         }
331 
332         contentType = responseMsg.getContentType(msgContext.getSOAPConstants());
333 
334         sendResponse(contentType, response, responseMsg);
335 
336         if (logger.isDebugEnabled())
337         {
338             logger.debug("Response sent.");
339         }
340     }
341 
342     private void reportTroubleInGet(Exception exception, AxisStringWriter response)
343     {
344         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
345         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
346         response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
347         response.write("<p>" + Messages.getMessage("somethingWrong00") + "</p>");
348         if (exception instanceof AxisFault)
349         {
350             AxisFault fault = (AxisFault)exception;
351             processAxisFault(fault);
352             writeFault(response, fault);
353         }
354         else
355         {
356             logger.error(exception.getMessage(), exception);
357             response.write("<pre>Exception - " + exception + "<br>");
358             response.write("</pre>");
359         }
360     }
361 
362     protected void processAxisFault(AxisFault fault)
363     {
364         org.w3c.dom.Element runtimeException = fault
365             .lookupFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
366         if (runtimeException != null)
367         {
368             logger.info(Messages.getMessage("axisFault00"), fault);
369             fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
370         }
371         else if (logger.isDebugEnabled())
372         {
373             logger.debug(Messages.getMessage("axisFault00"), fault);
374         }
375 
376     }
377 
378     private void writeFault(AxisStringWriter response, AxisFault axisFault)
379     {
380         String localizedMessage = XMLUtils.xmlEncodeString(axisFault.getLocalizedMessage());
381         response.write("<pre>Fault - " + localizedMessage + "<br>");
382         response.write(axisFault.dumpToString());
383         response.write("</pre>");
384     }
385 
386     protected void processMethodRequest(MessageContext msgContext,
387                                         MuleEventContext context,
388                                         AxisStringWriter response,
389                                         EndpointURI endpointUri) throws AxisFault
390     {
391         Properties params = endpointUri.getUserParams();
392 
393         String method = (String)params.remove(MuleProperties.MULE_METHOD_PROPERTY);
394         if (method == null)
395         {
396             method = endpointUri.getPath().substring(endpointUri.getPath().lastIndexOf("/") + 1);
397         }
398         StringBuffer args = new StringBuffer(64);
399 
400         Map.Entry entry;
401         for (Iterator iterator = params.entrySet().iterator(); iterator.hasNext();)
402         {
403             entry = (Map.Entry)iterator.next();
404             args.append("<").append(entry.getKey()).append(">");
405             args.append(entry.getValue());
406             args.append("</").append(entry.getKey()).append(">");
407         }
408 
409         if (method == null)
410         {
411             response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
412             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "400");
413             response.write("<h2>" + Messages.getMessage("error00") + ":  "
414                             + Messages.getMessage("invokeGet00") + "</h2>");
415             response.write("<p>" + Messages.getMessage("noMethod01") + "</p>");
416         }
417         else
418         {
419             invokeEndpointFromGet(msgContext, response, method, args.toString());
420         }
421     }
422 
423     protected void processWsdlRequest(MessageContext msgContext, AxisStringWriter response)
424         throws AxisFault
425     {
426         AxisEngine engine = getAxis();
427         try
428         {
429             engine.generateWSDL(msgContext);
430             Document doc = (Document)msgContext.getProperty("WSDL");
431             if (doc != null)
432             {
433                 response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/xml");
434                 XMLUtils.DocumentToWriter(doc, response.getWriter());
435             }
436             else
437             {
438                 if (logger.isDebugEnabled())
439                 {
440                     logger.debug("processWsdlRequest: failed to create WSDL");
441                 }
442                 reportNoWSDL(response, "noWSDL02", null);
443             }
444         }
445         catch (AxisFault axisFault)
446         {
447             if (axisFault.getFaultCode().equals(Constants.QNAME_NO_SERVICE_FAULT_CODE))
448             {
449                 processAxisFault(axisFault);
450                 response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
451                 reportNoWSDL(response, "noWSDL01", axisFault);
452             }
453             else
454             {
455                 throw axisFault;
456             }
457         }
458     }
459 
460     protected void invokeEndpointFromGet(MessageContext msgContext,
461                                          AxisStringWriter response,
462                                          String method,
463                                          String args) throws AxisFault
464     {
465         String body = "<" + method + ">" + args + "</" + method + ">";
466         String msgtxt = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body>"
467                         + body + "</SOAP-ENV:Body>" + "</SOAP-ENV:Envelope>";
468         Message responseMsg = null;
469         try
470         {
471             ByteArrayInputStream istream = new ByteArrayInputStream(msgtxt.getBytes("ISO-8859-1"));
472             AxisEngine engine = getAxis();
473             Message msg = new Message(istream, false);
474             msgContext.setRequestMessage(msg);
475             populateAxisProperties();
476             engine.invoke(msgContext);
477             responseMsg = msgContext.getResponseMessage();
478             response.setProperty(HTTPConstants.HEADER_CACHE_CONTROL, "no-cache");
479             response.setProperty(HTTPConstants.HEADER_PRAGMA, "no-cache");
480             if (responseMsg == null)
481             {
482                 throw new Exception(Messages.getMessage("noResponse01"));
483             }
484         }
485         catch (AxisFault fault)
486         {
487             processAxisFault(fault);
488             configureResponseFromAxisFault(response, fault);
489             responseMsg = new Message(fault);
490         }
491         catch (Exception e)
492         {
493             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
494             responseMsg = convertExceptionToAxisFault(e, responseMsg);
495         }
496         response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE, "text/xml");
497         response.write(responseMsg.getSOAPPartAsString());
498     }
499     
500     private void populateAxisProperties()
501     {
502 
503         Map<String, Object> invocationProperties = new HashMap<String, Object>();
504         Set<String> propertyNames = RequestContext.getEvent()
505             .getMessage()
506             .getPropertyNames(PropertyScope.INVOCATION);
507         for (String propName : propertyNames)
508         {
509             invocationProperties.put(propName,
510                 RequestContext.getEvent().getMessage().getInvocationProperty(propName));
511         }
512         AxisServiceProxy.setProperties(invocationProperties);
513     }
514 
515     protected void reportServiceInfo(AxisStringWriter response, SOAPService service, String serviceName)
516     {
517         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
518         response.write("<h1>" + service.getName() + "</h1>");
519         response.write("<p>" + Messages.getMessage("axisService00") + "</p>");
520         response.write("<i>" + Messages.getMessage("perhaps00") + "</i>");
521     }
522 
523     protected void processListRequest(AxisStringWriter response) throws AxisFault
524     {
525         AxisEngine engine = getAxis();
526         response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE, "text/html");
527         if (enableList)
528         {
529             Document doc = Admin.listConfig(engine);
530             if (doc != null)
531             {
532                 XMLUtils.DocumentToWriter(doc, response.getWriter());
533             }
534             else
535             {
536                 response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
537                 response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
538                 response.write("<p>" + Messages.getMessage("noDeploy00") + "</p>");
539             }
540         }
541         else
542         {
543             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "403");
544             response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
545             response.write("<p><i>?list</i> " + Messages.getMessage("disabled00") + "</p>");
546         }
547     }
548 
549     private void reportNoWSDL(AxisStringWriter response, String moreDetailCode, AxisFault axisFault)
550     {
551         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
552         response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE, "text/html");
553         response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
554         response.write("<p>" + Messages.getMessage("noWSDL00") + "</p>");
555         if (moreDetailCode != null)
556         {
557             response.write("<p>" + Messages.getMessage(moreDetailCode) + "</p>");
558         }
559 
560     }
561 
562     protected void reportAvailableServices(MuleEventContext context, AxisStringWriter response)
563         throws ConfigurationException, AxisFault
564     {
565         AxisEngine engine = getAxis();
566         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
567         response.write("<h2>And now... Some Services</h2>");
568         String version = MuleManifest.getProductVersion();
569         if (version == null)
570         {
571             version = "Version Not Set";
572         }
573         response.write("<h5>(Mule - " + version + ")</h5>");
574         Iterator i;
575 
576         try
577         {
578             response
579                 .write("<table width=\"400\"><tr><th>Mule Component Services</th><th>Axis Services</th></tr><tr><td width=\"200\" valign=\"top\">");
580             i = engine.getConfig().getDeployedServices();
581             listServices(i, response);
582             response.write("</td><td width=\"200\" valign=\"top\">");
583             i = ((MuleConfigProvider)engine.getConfig()).getAxisDeployedServices();
584             listServices(i, response);
585             response.write("</td></tr></table>");
586         }
587         catch (ConfigurationException configException)
588         {
589             if (configException.getContainedException() instanceof AxisFault)
590             {
591                 throw (AxisFault)configException.getContainedException();
592             }
593             else
594             {
595                 throw configException;
596             }
597         }
598 
599     }
600 
601     private void listServices(Iterator i, AxisStringWriter response)
602     {
603         response.write("<ul>");
604         while (i.hasNext())
605         {
606             ServiceDesc sd = (ServiceDesc)i.next();
607             StringBuffer sb = new StringBuffer(512);
608             sb.append("<li>");
609             String name = sd.getName();
610             sb.append(name);
611             sb.append(" <a href=\"");
612             if (sd.getEndpointURL() != null)
613             {
614                 sb.append(sd.getEndpointURL());
615                 if (!sd.getEndpointURL().endsWith("/"))
616                 {
617                     sb.append("/");
618                 }
619             }
620             sb.append(name);
621             sb.append("?wsdl\"><i>(wsdl)</i></a></li>");
622             response.write(sb.toString());
623             if (sd.getDocumentation() != null)
624             {
625                 response.write("<ul><h6>" + sd.getDocumentation() + "</h6></ul>");
626             }
627             ArrayList operations = sd.getOperations();
628             if (!operations.isEmpty())
629             {
630                 response.write("<ul>");
631                 OperationDesc desc;
632                 for (Iterator it = operations.iterator(); it.hasNext();)
633                 {
634                     desc = (OperationDesc)it.next();
635                     response.write("<li>" + desc.getName());
636                 }
637                 response.write("</ul>");
638             }
639         }
640         response.write("</ul>");
641     }
642 
643     protected void reportCantGetAxisService(MuleEventContext context, AxisStringWriter response)
644     {
645         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
646         response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, "text/html");
647         response.write("<h2>" + Messages.getMessage("error00") + "</h2>");
648         response.write("<p>" + Messages.getMessage("noService06") + "</p>");
649     }
650 
651     private void configureResponseFromAxisFault(AxisStringWriter response, AxisFault fault)
652     {
653         int status = getHttpResponseStatus(fault);
654         if (status == 401)
655         {
656             response.setProperty(HttpConstants.HEADER_WWW_AUTHENTICATE, "Basic realm=\"AXIS\"");
657         }
658         response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, String.valueOf(status));
659     }
660 
661     private Message convertExceptionToAxisFault(Exception exception, Message responseMsg)
662     {
663         logger.error(exception.getMessage(), exception);
664         if (responseMsg == null)
665         {
666             AxisFault fault = AxisFault.makeFault(exception);
667             processAxisFault(fault);
668             responseMsg = new Message(fault);
669         }
670         return responseMsg;
671     }
672 
673     protected int getHttpResponseStatus(AxisFault af)
674     {
675         return af.getFaultCode().getLocalPart().startsWith("Server.Unauth") ? 401 : '\u01F4';
676     }
677 
678     private void sendResponse(String contentType,
679                               AxisStringWriter response,
680                               Message responseMsg) throws Exception
681     {
682         if (responseMsg == null)
683         {
684             response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "204");
685             if (logger.isDebugEnabled())
686             {
687                 logger.debug("NO AXIS MESSAGE TO RETURN!");
688             }
689         }
690         else
691         {
692             if (logger.isDebugEnabled())
693             {
694                 logger.debug("Returned Content-Type:" + contentType);
695             }
696                 response.setProperty(HttpConstants.HEADER_CONTENT_TYPE, contentType);
697                 ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
698                 responseMsg.writeTo(baos);
699                 response.write(baos.toString());
700         }
701     }
702 
703     private void populateMessageContext(MessageContext msgContext,
704                                         MuleEventContext context,
705                                         EndpointURI endpointUri) throws AxisFault, ConfigurationException
706     {
707         MuleMessage msg = context.getMessage();
708 
709         if (logger.isDebugEnabled())
710         {
711             logger.debug("MessageContext:" + msgContext);
712             logger.debug("HEADER_CONTENT_TYPE:" + msg.getInboundProperty(HttpConstants.HEADER_CONTENT_TYPE));
713             logger.debug("HEADER_CONTENT_LOCATION:" + msg.getInboundProperty(HttpConstants.HEADER_CONTENT_LOCATION));
714             logger.debug("Constants.MC_HOME_DIR:" + String.valueOf(getHomeDir()));
715             logger.debug("Constants.MC_RELATIVE_PATH:" + endpointUri.getPath());
716             logger.debug("HTTPConstants.HEADER_AUTHORIZATION:" + msg.getInboundProperty("Authorization"));
717             logger.debug("Constants.MC_REMOTE_ADDR:" + endpointUri.getHost());
718         }
719 
720         msgContext.setTransportName(transportName);
721         msgContext.setProperty("home.dir", getHomeDir());
722         msgContext.setProperty("path", endpointUri.getPath());
723         msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this);
724         msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION, endpointUri.getPath());
725         // determine service name
726         String serviceName = getServiceName(context, endpointUri);
727         // Validate Service path against request path
728         SOAPService service = msgContext.getAxisEngine().getConfig().getService(
729             new QName(serviceName.substring(1)));
730 
731         // if using jms or vm we can skip this
732         String scheme = endpointUri.getScheme();
733         if (!("vm".equalsIgnoreCase(scheme)
734                         || "jms".equalsIgnoreCase(scheme)
735                         || "servlet".equalsIgnoreCase(scheme)))
736         {
737             // Component Name is set by Mule so if its null we can skip this check
738             if (service.getOption(AxisConnector.SERVICE_PROPERTY_COMPONENT_NAME) != null)
739             {
740                 String servicePath = (String)service.getOption("servicePath");
741                 if (StringUtils.isEmpty(endpointUri.getPath()))
742                 {
743                     if (!("/" + endpointUri.getAddress()).startsWith(servicePath + serviceName))
744                     {
745                         throw new AxisFault("Failed to find service: " + "/" + endpointUri.getAddress());
746                     }
747                 }
748                 //We use ends with rather than starts with because if a servlet binding is used we do not have the full
749                 //path info when the service is registered.  Track MULE-3931 for more info.
750                 else if (!endpointUri.getPath().endsWith(servicePath + serviceName))
751                 {
752                     throw new AxisFault("Failed to find service: " + endpointUri.getPath());
753                 }
754             }
755         }
756 
757         msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO, serviceName);
758         msgContext.setProperty("serviceName", serviceName);
759 
760         msgContext.setProperty("Authorization", msg.getInboundProperty("Authorization"));
761         msgContext.setProperty("remoteaddr", endpointUri.getHost());
762         ServletEndpointContextImpl sec = new ServletEndpointContextImpl();
763         msgContext.setProperty("servletEndpointContext", sec);
764     }
765 
766     private String getSoapAction(MuleEventContext context) throws AxisFault
767     {
768         String soapAction = context.getMessage().getInboundProperty(SoapConstants.SOAP_ACTION_PROPERTY_CAPS);
769         if (logger.isDebugEnabled())
770         {
771             logger.debug("Header Soap Action:" + soapAction);
772         }
773 
774         if (StringUtils.isEmpty(soapAction))
775         {
776             EndpointURI endpointUri;
777             try
778             {
779                 endpointUri = new MuleEndpointURI(context.getEndpointURI().toString(), context.getMuleContext());
780                 endpointUri.initialise();
781             }
782             catch (Exception e)
783             {
784                 throw new AxisFault(e.getMessage(), e);
785             }
786             soapAction = endpointUri.getAddress();
787         }
788         return soapAction;
789     }
790 
791     protected String getServiceName(MuleEventContext context, EndpointURI endpointUri) throws AxisFault
792     {
793         String serviceName = endpointUri.getPath();
794         if (StringUtils.isEmpty(serviceName))
795         {
796             serviceName = getSoapAction(context);
797             serviceName = serviceName.replaceAll("\"", "");
798             int i = serviceName.indexOf("/", serviceName.indexOf("//"));
799             if (i < -1)
800             {
801                 serviceName = serviceName.substring(i + 2);
802             }
803 
804         }
805 
806         int i = serviceName.lastIndexOf('/');
807         if (i > -1)
808         {
809             serviceName = serviceName.substring(i);
810         }
811         i = serviceName.lastIndexOf('?');
812         if (i > -1)
813         {
814             serviceName = serviceName.substring(0, i);
815         }
816         return serviceName;
817     }
818 
819     public String getTransportName()
820     {
821         return transportName;
822     }
823 
824     public void setTransportName(String transportName)
825     {
826         this.transportName = transportName;
827     }
828 
829     public boolean isEnableList()
830     {
831         return enableList;
832     }
833 
834     public void setEnableList(boolean enableList)
835     {
836         this.enableList = enableList;
837     }
838 
839     public String getHomeDir()
840     {
841         if (homeDir == null)
842         {
843             //TODO fix homeDir = muleContext.getConfiguration().getWorkingDirectory() + DEFAULT_AXIS_HOME;
844             homeDir = DEFAULT_AXIS_HOME;
845         }
846         return homeDir;
847     }
848 
849     public void setHomeDir(String homeDir)
850     {
851         this.homeDir = homeDir;
852     }
853 
854     public AxisServer getAxis()
855     {
856         return axis;
857     }
858 
859     public void setAxis(AxisServer axisServer)
860     {
861         this.axis = axisServer;
862     }
863 }