View Javadoc

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