001: /*
002: * $Id: AxisServiceComponent.java 10808 2008-02-14 20:36:57Z acooke $
003: * --------------------------------------------------------------------------------------
004: * Copyright (c) MuleSource, Inc. All rights reserved. http://www.mulesource.com
005: *
006: * The software in this package is published under the terms of the CPAL v1.0
007: * license, a copy of which has been included with this distribution in the
008: * LICENSE.txt file.
009: */
010:
011: package org.mule.transport.soap.axis;
012:
013: import org.mule.DefaultMuleMessage;
014: import org.mule.RequestContext;
015: import org.mule.api.MuleException;
016: import org.mule.api.MessagingException;
017: import org.mule.api.MuleEventContext;
018: import org.mule.api.MuleMessage;
019: import org.mule.api.config.MuleProperties;
020: import org.mule.api.endpoint.EndpointException;
021: import org.mule.api.endpoint.EndpointURI;
022: import org.mule.api.lifecycle.Callable;
023: import org.mule.api.lifecycle.Initialisable;
024: import org.mule.api.lifecycle.InitialisationException;
025: import org.mule.api.lifecycle.LifecycleTransitionResult;
026: import org.mule.config.MuleManifest;
027: import org.mule.config.i18n.CoreMessages;
028: import org.mule.config.i18n.MessageFactory;
029: import org.mule.endpoint.MuleEndpointURI;
030: import org.mule.transport.WriterMessageAdapter;
031: import org.mule.transport.http.HttpConnector;
032: import org.mule.transport.http.HttpConstants;
033: import org.mule.transport.soap.SoapConstants;
034: import org.mule.transport.soap.axis.extensions.AxisMuleSession;
035: import org.mule.transport.soap.axis.extensions.MuleConfigProvider;
036: import org.mule.util.StringUtils;
037:
038: import java.io.ByteArrayInputStream;
039: import java.io.ByteArrayOutputStream;
040: import java.io.File;
041: import java.io.FileInputStream;
042: import java.io.IOException;
043: import java.io.StringWriter;
044: import java.util.ArrayList;
045: import java.util.Iterator;
046: import java.util.Map;
047: import java.util.Properties;
048:
049: import javax.xml.namespace.QName;
050:
051: import org.apache.axis.AxisEngine;
052: import org.apache.axis.AxisFault;
053: import org.apache.axis.ConfigurationException;
054: import org.apache.axis.Constants;
055: import org.apache.axis.Message;
056: import org.apache.axis.MessageContext;
057: import org.apache.axis.description.OperationDesc;
058: import org.apache.axis.description.ServiceDesc;
059: import org.apache.axis.handlers.soap.SOAPService;
060: import org.apache.axis.i18n.Messages;
061: import org.apache.axis.security.servlet.ServletSecurityProvider;
062: import org.apache.axis.server.AxisServer;
063: import org.apache.axis.transport.http.HTTPConstants;
064: import org.apache.axis.transport.http.ServletEndpointContextImpl;
065: import org.apache.axis.utils.Admin;
066: import org.apache.axis.utils.XMLUtils;
067: import org.apache.commons.logging.Log;
068: import org.w3c.dom.Document;
069:
070: /**
071: * <code>AxisServiceComponent</code> is a Mule component implementation of the Axis
072: * servlet. This component supports all the features of the Axis servlet except -
073: * <ol>
074: * <li>Jws class services are not supported as they don't add any value to the Mule
075: * model</li>
076: * <li>Currently there is no HttpSession support. This will be fixed when MuleSession
077: * support is added to the Http Connector</li>
078: * </ol>
079: */
080:
081: public class AxisServiceComponent implements Initialisable, Callable {
082: protected static final Log logger = org.apache.commons.logging.LogFactory
083: .getLog(AxisServiceComponent.class);
084:
085: public static final String INIT_PROPERTY_TRANSPORT_NAME = "transport.name";
086: public static final String INIT_PROPERTY_USE_SECURITY = "use-servlet-security";
087: public static final String INIT_PROPERTY_ENABLE_LIST = "axis.enableListQuery";
088: public static final String DEFAULT_AXIS_HOME = "/axisHome";
089:
090: private String transportName = "http";
091: private ServletSecurityProvider securityProvider = null;
092: private boolean enableList = true;
093: private String homeDir;
094: private AxisServer axis;
095:
096: /** For IoC */
097: public AxisServiceComponent() {
098: // do nothing
099: }
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 UMO.</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: WriterMessageAdapter response = new WriterMessageAdapter(
122: new StringWriter(4096));
123: String method = context.getMessage().getStringProperty(
124: HttpConnector.HTTP_METHOD_PROPERTY,
125: HttpConstants.METHOD_POST);
126: if (HttpConstants.METHOD_GET.equalsIgnoreCase(method)) {
127: doGet(context, response);
128: } else {
129: doPost(context, response);
130: }
131: response.getWriter().close();
132: return new DefaultMuleMessage(response);
133: }
134:
135: public LifecycleTransitionResult initialise()
136: throws InitialisationException {
137: if (axis == null) {
138: throw new InitialisationException(
139: MessageFactory
140: .createStaticMessage("No Axis instance, this component has not been initialized properly."),
141: this );
142: }
143: return LifecycleTransitionResult.OK;
144: }
145:
146: public void doGet(MuleEventContext context,
147: WriterMessageAdapter response) throws MuleException,
148: IOException {
149: try {
150: // We parse a new uri based on the listening host and port with the
151: // request parameters appended
152: // Using the soap prefix ensures that we use a soap endpoint builder
153: EndpointURI endpointUri = context.getEndpointURI();
154: if (!"servlet".equalsIgnoreCase(context.getEndpointURI()
155: .getSchemeMetaInfo())) {
156: String uri = SoapConstants.SOAP_ENDPOINT_PREFIX
157: + context.getEndpointURI().getScheme() + "://"
158: + context.getEndpointURI().getHost() + ":"
159: + context.getEndpointURI().getPort();
160: uri += context.getMessage().getStringProperty(
161: HttpConnector.HTTP_REQUEST_PROPERTY, "");
162: endpointUri = new MuleEndpointURI(uri);
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: throw new AxisFault(
173: "Jws not supported by the Mule Axis service");
174: }
175:
176: String queryString = endpointUri.getQuery();
177: if (queryString != null) {
178: if (queryString
179: .equalsIgnoreCase(SoapConstants.WSDL_PROPERTY)) {
180: wsdlRequested = true;
181: } else {
182: if (queryString
183: .equalsIgnoreCase(SoapConstants.LIST_PROPERTY)) {
184: listRequested = true;
185: }
186: }
187: }
188:
189: boolean hasNoPath = (StringUtils.isEmpty(pathInfo) || pathInfo
190: .equals("/"));
191: if (!wsdlRequested && !listRequested && hasNoPath) {
192: reportAvailableServices(context, response);
193: } else {
194: MessageContext msgContext = new MessageContext(engine);
195: populateMessageContext(msgContext, context, endpointUri);
196:
197: msgContext.setProperty("transport.url", endpointUri
198: .toString());
199: if (wsdlRequested) {
200: processWsdlRequest(msgContext, response);
201: } else if (listRequested) {
202: processListRequest(response);
203: } else {
204: processMethodRequest(msgContext, context, response,
205: endpointUri);
206: }
207: }
208: } catch (AxisFault fault) {
209: reportTroubleInGet(fault, response);
210: } catch (Exception e) {
211: reportTroubleInGet(e, response);
212: }
213: }
214:
215: private void reportTroubleInGet(Exception exception,
216: WriterMessageAdapter response) {
217: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
218: "text/html");
219: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "500");
220: response.write("<h2>" + Messages.getMessage("error00")
221: + "</h2>");
222: response.write("<p>" + Messages.getMessage("somethingWrong00")
223: + "</p>");
224: if (exception instanceof AxisFault) {
225: AxisFault fault = (AxisFault) exception;
226: processAxisFault(fault);
227: writeFault(response, fault);
228: } else {
229: logger.error(exception.getMessage(), exception);
230: response.write("<pre>Exception - " + exception + "<br>");
231: response.write("</pre>");
232: }
233: }
234:
235: protected void processAxisFault(AxisFault fault) {
236: org.w3c.dom.Element runtimeException = fault
237: .lookupFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
238: if (runtimeException != null) {
239: logger.info(Messages.getMessage("axisFault00"), fault);
240: fault
241: .removeFaultDetail(Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);
242: } else if (logger.isDebugEnabled()) {
243: logger.debug(Messages.getMessage("axisFault00"), fault);
244: }
245:
246: }
247:
248: private void writeFault(WriterMessageAdapter response,
249: AxisFault axisFault) {
250: String localizedMessage = XMLUtils.xmlEncodeString(axisFault
251: .getLocalizedMessage());
252: response.write("<pre>Fault - " + localizedMessage + "<br>");
253: response.write(axisFault.dumpToString());
254: response.write("</pre>");
255: }
256:
257: protected void processMethodRequest(MessageContext msgContext,
258: MuleEventContext context, WriterMessageAdapter response,
259: EndpointURI endpointUri) throws AxisFault {
260: Properties params = endpointUri.getUserParams();
261:
262: String method = (String) params
263: .remove(MuleProperties.MULE_METHOD_PROPERTY);
264: if (method == null) {
265: method = endpointUri.getPath().substring(
266: endpointUri.getPath().lastIndexOf("/") + 1);
267: }
268: StringBuffer args = new StringBuffer(64);
269:
270: Map.Entry entry;
271: for (Iterator iterator = params.entrySet().iterator(); iterator
272: .hasNext();) {
273: entry = (Map.Entry) iterator.next();
274: args.append("<").append(entry.getKey()).append(">");
275: args.append(entry.getValue());
276: args.append("</").append(entry.getKey()).append(">");
277: }
278:
279: if (method == null) {
280: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
281: "text/html");
282: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY,
283: "400");
284: response.write("<h2>" + Messages.getMessage("error00")
285: + ": " + Messages.getMessage("invokeGet00")
286: + "</h2>");
287: response.write("<p>" + Messages.getMessage("noMethod01")
288: + "</p>");
289: } else {
290: invokeEndpointFromGet(msgContext, response, method, args
291: .toString());
292: }
293: }
294:
295: protected void processWsdlRequest(MessageContext msgContext,
296: WriterMessageAdapter response) throws AxisFault {
297: AxisEngine engine = getAxis();
298: try {
299: engine.generateWSDL(msgContext);
300: Document doc = (Document) msgContext.getProperty("WSDL");
301: if (doc != null) {
302: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
303: "text/xml");
304: XMLUtils.DocumentToWriter(doc, response.getWriter());
305: } else {
306: if (logger.isDebugEnabled()) {
307: logger
308: .debug("processWsdlRequest: failed to create WSDL");
309: }
310: reportNoWSDL(response, "noWSDL02", null);
311: }
312: } catch (AxisFault axisFault) {
313: if (axisFault.getFaultCode().equals(
314: Constants.QNAME_NO_SERVICE_FAULT_CODE)) {
315: processAxisFault(axisFault);
316: response.setProperty(
317: HttpConnector.HTTP_STATUS_PROPERTY, "404");
318: reportNoWSDL(response, "noWSDL01", axisFault);
319: } else {
320: throw axisFault;
321: }
322: }
323: }
324:
325: protected void invokeEndpointFromGet(MessageContext msgContext,
326: WriterMessageAdapter response, String method, String args)
327: throws AxisFault {
328: String body = "<" + method + ">" + args + "</" + method + ">";
329: String msgtxt = "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body>"
330: + body + "</SOAP-ENV:Body>" + "</SOAP-ENV:Envelope>";
331: Message responseMsg = null;
332: try {
333: ByteArrayInputStream istream = new ByteArrayInputStream(
334: msgtxt.getBytes("ISO-8859-1"));
335: AxisEngine engine = getAxis();
336: Message msg = new Message(istream, false);
337: msgContext.setRequestMessage(msg);
338: AxisServiceProxy.setProperties(RequestContext.getEvent()
339: .getEndpoint().getProperties());
340: engine.invoke(msgContext);
341: responseMsg = msgContext.getResponseMessage();
342: response.setProperty(HTTPConstants.HEADER_CACHE_CONTROL,
343: "no-cache");
344: response.setProperty(HTTPConstants.HEADER_PRAGMA,
345: "no-cache");
346: if (responseMsg == null) {
347: throw new Exception(Messages.getMessage("noResponse01"));
348: }
349: } catch (AxisFault fault) {
350: processAxisFault(fault);
351: configureResponseFromAxisFault(response, fault);
352: responseMsg = new Message(fault);
353: } catch (Exception e) {
354: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY,
355: "500");
356: responseMsg = convertExceptionToAxisFault(e, responseMsg);
357: }
358: response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE,
359: "text/xml");
360: response.write(responseMsg.getSOAPPartAsString());
361: }
362:
363: protected void reportServiceInfo(WriterMessageAdapter response,
364: SOAPService service, String serviceName) {
365: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
366: "text/html");
367: response.write("<h1>" + service.getName() + "</h1>");
368: response.write("<p>" + Messages.getMessage("axisService00")
369: + "</p>");
370: response.write("<i>" + Messages.getMessage("perhaps00")
371: + "</i>");
372: }
373:
374: protected void processListRequest(WriterMessageAdapter response)
375: throws AxisFault {
376: AxisEngine engine = getAxis();
377: response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE,
378: "text/html");
379: if (enableList) {
380: Document doc = Admin.listConfig(engine);
381: if (doc != null) {
382: XMLUtils.DocumentToWriter(doc, response.getWriter());
383: } else {
384: response.setProperty(
385: HttpConnector.HTTP_STATUS_PROPERTY, "404");
386: response.write("<h2>" + Messages.getMessage("error00")
387: + "</h2>");
388: response.write("<p>"
389: + Messages.getMessage("noDeploy00") + "</p>");
390: }
391: } else {
392: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY,
393: "403");
394: response.write("<h2>" + Messages.getMessage("error00")
395: + "</h2>");
396: response.write("<p><i>?list</i> "
397: + Messages.getMessage("disabled00") + "</p>");
398: }
399: }
400:
401: private void reportNoWSDL(WriterMessageAdapter response,
402: String moreDetailCode, AxisFault axisFault) {
403: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
404: response.setProperty(HTTPConstants.HEADER_CONTENT_TYPE,
405: "text/html");
406: response.write("<h2>" + Messages.getMessage("error00")
407: + "</h2>");
408: response
409: .write("<p>" + Messages.getMessage("noWSDL00") + "</p>");
410: if (moreDetailCode != null) {
411: response.write("<p>" + Messages.getMessage(moreDetailCode)
412: + "</p>");
413: }
414:
415: }
416:
417: protected void reportAvailableServices(MuleEventContext context,
418: WriterMessageAdapter response)
419: throws ConfigurationException, AxisFault {
420: AxisEngine engine = getAxis();
421: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
422: "text/html");
423: response.write("<h2>And now... Some Services</h2>");
424: String version = MuleManifest.getProductVersion();
425: if (version == null) {
426: version = "Version Not Set";
427: }
428: response.write("<h5>(Mule - " + version + ")</h5>");
429: Iterator i;
430:
431: try {
432: response
433: .write("<table width=\"400\"><tr><th>Mule Component Services</th><th>Axis Services</th></tr><tr><td width=\"200\" valign=\"top\">");
434: i = engine.getConfig().getDeployedServices();
435: listServices(i, response);
436: response.write("</td><td width=\"200\" valign=\"top\">");
437: i = ((MuleConfigProvider) engine.getConfig())
438: .getAxisDeployedServices();
439: listServices(i, response);
440: response.write("</td></tr></table>");
441: } catch (ConfigurationException configException) {
442: if (configException.getContainedException() instanceof AxisFault) {
443: throw (AxisFault) configException
444: .getContainedException();
445: } else {
446: throw configException;
447: }
448: }
449:
450: }
451:
452: private void listServices(Iterator i, WriterMessageAdapter response) {
453: response.write("<ul>");
454: while (i.hasNext()) {
455: ServiceDesc sd = (ServiceDesc) i.next();
456: StringBuffer sb = new StringBuffer(512);
457: sb.append("<li>");
458: String name = sd.getName();
459: sb.append(name);
460: sb.append(" <a href=\"");
461: if (sd.getEndpointURL() != null) {
462: sb.append(sd.getEndpointURL());
463: if (!sd.getEndpointURL().endsWith("/")) {
464: sb.append("/");
465: }
466: }
467: sb.append(name);
468: sb.append("?wsdl\"><i>(wsdl)</i></a></li>");
469: response.write(sb.toString());
470: if (sd.getDocumentation() != null) {
471: response.write("<ul><h6>" + sd.getDocumentation()
472: + "</h6></ul>");
473: }
474: ArrayList operations = sd.getOperations();
475: if (!operations.isEmpty()) {
476: response.write("<ul>");
477: OperationDesc desc;
478: for (Iterator it = operations.iterator(); it.hasNext();) {
479: desc = (OperationDesc) it.next();
480: response.write("<li>" + desc.getName());
481: }
482: response.write("</ul>");
483: }
484: }
485: response.write("</ul>");
486: }
487:
488: protected void reportCantGetAxisService(MuleEventContext context,
489: WriterMessageAdapter response) {
490: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, "404");
491: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
492: "text/html");
493: response.write("<h2>" + Messages.getMessage("error00")
494: + "</h2>");
495: response.write("<p>" + Messages.getMessage("noService06")
496: + "</p>");
497: }
498:
499: protected void doPost(MuleEventContext context,
500: WriterMessageAdapter response) throws Exception {
501: String soapAction;
502: Message responseMsg;
503: AxisEngine engine = getAxis();
504: if (engine == null) {
505:
506: throw new MessagingException(CoreMessages
507: .objectIsNull("Axis Engine"), context.getMessage());
508: }
509: MessageContext msgContext = new MessageContext(engine);
510:
511: String contentType;
512: try {
513: EndpointURI endpointUri = getEndpoint(context);
514: populateMessageContext(msgContext, context, endpointUri);
515: if (securityProvider != null) {
516: if (logger.isDebugEnabled()) {
517: logger
518: .debug("securityProvider:"
519: + securityProvider);
520: }
521: msgContext.setProperty("securityProvider",
522: securityProvider);
523: }
524:
525: Object request = context.transformMessage();
526: if (request instanceof File) {
527: request = new FileInputStream((File) request);
528: } else if (request instanceof byte[]) {
529: request = new ByteArrayInputStream((byte[]) request);
530: }
531:
532: Message requestMsg = new Message(
533: request,
534: false,
535: context.getMessage().getStringProperty(
536: HTTPConstants.HEADER_CONTENT_TYPE, null),
537: context
538: .getMessage()
539: .getStringProperty(
540: HTTPConstants.HEADER_CONTENT_LOCATION,
541: null));
542:
543: if (logger.isDebugEnabled()) {
544: logger.debug("Request Message:" + requestMsg);
545: }
546: msgContext.setRequestMessage(requestMsg);
547: msgContext.setProperty("transport.url", endpointUri
548: .toString());
549:
550: soapAction = getSoapAction(context);
551: if (soapAction != null) {
552: msgContext.setUseSOAPAction(true);
553: msgContext.setSOAPActionURI(soapAction);
554: }
555: msgContext.setSession(new AxisMuleSession(context
556: .getSession()));
557:
558: if (logger.isDebugEnabled()) {
559: logger.debug("Invoking Axis Engine.");
560: }
561: AxisServiceProxy.setProperties(RequestContext.getEvent()
562: .getEndpoint().getProperties());
563: engine.invoke(msgContext);
564: if (logger.isDebugEnabled()) {
565: logger.debug("Return from Axis Engine.");
566: }
567: if (RequestContext.getExceptionPayload() instanceof Exception) {
568: throw (Exception) RequestContext.getExceptionPayload()
569: .getException();
570: }
571: // remove temporary file used for soap message with attachment
572: if (request instanceof File) {
573: ((File) request).delete();
574: }
575: responseMsg = msgContext.getResponseMessage();
576: if (responseMsg == null) {
577: throw new Exception(Messages.getMessage("noResponse01"));
578: }
579: } catch (AxisFault fault) {
580: logger.error(fault.toString() + " target service is: "
581: + msgContext.getTargetService()
582: + ". MuleEvent is: " + context.toString(), fault);
583: processAxisFault(fault);
584: configureResponseFromAxisFault(response, fault);
585: responseMsg = msgContext.getResponseMessage();
586: if (responseMsg == null) {
587: responseMsg = new Message(fault);
588: }
589: } catch (Exception e) {
590: responseMsg = msgContext.getResponseMessage();
591: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY,
592: "500");
593: responseMsg = convertExceptionToAxisFault(e, responseMsg);
594: }
595:
596: contentType = responseMsg.getContentType(msgContext
597: .getSOAPConstants());
598:
599: sendResponse(contentType, response, responseMsg);
600:
601: if (logger.isDebugEnabled()) {
602: logger.debug("Response sent.");
603: }
604: }
605:
606: private EndpointURI getEndpoint(MuleEventContext context)
607: throws EndpointException {
608: String endpoint = context.getEndpointURI().getAddress();
609: String request = context.getMessage().getStringProperty(
610: HttpConnector.HTTP_REQUEST_PROPERTY, null);
611: if (request != null) {
612: int i = endpoint.indexOf("/", endpoint.indexOf("://") + 3);
613: if (i > -1) {
614: endpoint = endpoint.substring(0, i);
615: }
616: endpoint += request;
617: return new MuleEndpointURI(endpoint);
618: }
619: return context.getEndpointURI();
620: }
621:
622: private void configureResponseFromAxisFault(
623: WriterMessageAdapter response, AxisFault fault) {
624: int status = getHttpResponseStatus(fault);
625: if (status == 401) {
626: response.setProperty(HttpConstants.HEADER_WWW_AUTHENTICATE,
627: "Basic realm=\"AXIS\"");
628: }
629: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY, String
630: .valueOf(status));
631: }
632:
633: private Message convertExceptionToAxisFault(Exception exception,
634: Message responseMsg) {
635: logger.error(exception.getMessage(), exception);
636: if (responseMsg == null) {
637: AxisFault fault = AxisFault.makeFault(exception);
638: processAxisFault(fault);
639: responseMsg = new Message(fault);
640: }
641: return responseMsg;
642: }
643:
644: protected int getHttpResponseStatus(AxisFault af) {
645: return af.getFaultCode().getLocalPart().startsWith(
646: "Server.Unauth") ? 401 : '\u01F4';
647: }
648:
649: private void sendResponse(String contentType,
650: WriterMessageAdapter response, Message responseMsg)
651: throws Exception {
652: if (responseMsg == null) {
653: response.setProperty(HttpConnector.HTTP_STATUS_PROPERTY,
654: "204");
655: if (logger.isDebugEnabled()) {
656: logger.debug("NO AXIS MESSAGE TO RETURN!");
657: }
658: } else {
659: if (logger.isDebugEnabled()) {
660: logger.debug("Returned Content-Type:" + contentType);
661: }
662: response.setProperty(HttpConstants.HEADER_CONTENT_TYPE,
663: contentType);
664: ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
665: responseMsg.writeTo(baos);
666: response.write(baos.toString());
667: }
668: }
669:
670: private void populateMessageContext(MessageContext msgContext,
671: MuleEventContext context, EndpointURI endpointUri)
672: throws AxisFault, ConfigurationException {
673: MuleMessage msg = context.getMessage();
674:
675: if (logger.isDebugEnabled()) {
676: logger.debug("MessageContext:" + msgContext);
677: logger.debug("HEADER_CONTENT_TYPE:"
678: + msg.getStringProperty(
679: HttpConstants.HEADER_CONTENT_TYPE, null));
680: logger
681: .debug("HEADER_CONTENT_LOCATION:"
682: + msg
683: .getStringProperty(
684: HttpConstants.HEADER_CONTENT_LOCATION,
685: null));
686: logger.debug("Constants.MC_HOME_DIR:"
687: + String.valueOf(getHomeDir()));
688: logger.debug("Constants.MC_RELATIVE_PATH:"
689: + endpointUri.getPath());
690: logger.debug("HTTPConstants.HEADER_AUTHORIZATION:"
691: + msg.getStringProperty("Authorization", null));
692: logger.debug("Constants.MC_REMOTE_ADDR:"
693: + endpointUri.getHost());
694: }
695:
696: msgContext.setTransportName(transportName);
697: msgContext.setProperty("home.dir", getHomeDir());
698: msgContext.setProperty("path", endpointUri.getPath());
699: msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this );
700: msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION,
701: endpointUri.getPath());
702: // determine service name
703: String serviceName = getServiceName(context, endpointUri);
704: // Validate Service path against request path
705: SOAPService service = msgContext.getAxisEngine().getConfig()
706: .getService(new QName(serviceName.substring(1)));
707:
708: // if using jms or vm we can skip this
709: if (!("vm".equalsIgnoreCase(endpointUri.getScheme()) || "jms"
710: .equalsIgnoreCase(endpointUri.getScheme()))) {
711: // Component Name is set by Mule so if its null we can skip this check
712: if (service
713: .getOption(AxisConnector.SERVICE_PROPERTY_COMPONENT_NAME) != null) {
714: String servicePath = (String) service
715: .getOption("servicePath");
716: if (StringUtils.isEmpty(endpointUri.getPath())) {
717: if (!("/" + endpointUri.getAddress())
718: .startsWith(servicePath + serviceName)) {
719: throw new AxisFault("Failed to find service: "
720: + "/" + endpointUri.getAddress());
721: }
722: } else if (!endpointUri.getPath().startsWith(
723: servicePath + serviceName)) {
724: throw new AxisFault("Failed to find service: "
725: + endpointUri.getPath());
726: }
727: }
728: }
729:
730: msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO,
731: serviceName);
732: msgContext.setProperty("serviceName", serviceName);
733:
734: msgContext.setProperty("Authorization", msg.getStringProperty(
735: "Authorization", null));
736: msgContext.setProperty("remoteaddr", endpointUri.getHost());
737: ServletEndpointContextImpl sec = new ServletEndpointContextImpl();
738: msgContext.setProperty("servletEndpointContext", sec);
739: }
740:
741: private String getSoapAction(MuleEventContext context)
742: throws AxisFault {
743: String soapAction = context.getMessage().getStringProperty(
744: SoapConstants.SOAP_ACTION_PROPERTY_CAPS, null);
745: if (logger.isDebugEnabled()) {
746: logger.debug("Header Soap Action:" + soapAction);
747: }
748:
749: if (StringUtils.isEmpty(soapAction)) {
750: soapAction = context.getEndpointURI().getAddress();
751: }
752: return soapAction;
753: }
754:
755: protected String getServiceName(MuleEventContext context,
756: EndpointURI endpointUri) throws AxisFault {
757: String serviceName = endpointUri.getPath();
758: if (StringUtils.isEmpty(serviceName)) {
759: serviceName = getSoapAction(context);
760: serviceName = serviceName.replaceAll("\"", "");
761: int i = serviceName.indexOf("/", serviceName.indexOf("//"));
762: if (i < -1) {
763: serviceName = serviceName.substring(i + 2);
764: }
765:
766: }
767:
768: int i = serviceName.lastIndexOf('/');
769: if (i > -1) {
770: serviceName = serviceName.substring(i);
771: }
772: i = serviceName.lastIndexOf('?');
773: if (i > -1) {
774: serviceName = serviceName.substring(0, i);
775: }
776: return serviceName;
777: }
778:
779: public String getTransportName() {
780: return transportName;
781: }
782:
783: public void setTransportName(String transportName) {
784: this .transportName = transportName;
785: }
786:
787: public boolean isEnableList() {
788: return enableList;
789: }
790:
791: public void setEnableList(boolean enableList) {
792: this .enableList = enableList;
793: }
794:
795: public String getHomeDir() {
796: if (homeDir == null) {
797: //TODO fix homeDir = RegistryContext.getConfiguration().getWorkingDirectory() + DEFAULT_AXIS_HOME;
798: homeDir = DEFAULT_AXIS_HOME;
799: }
800: return homeDir;
801: }
802:
803: public void setHomeDir(String homeDir) {
804: this .homeDir = homeDir;
805: }
806:
807: public AxisServer getAxis() {
808: return axis;
809: }
810:
811: public void setAxis(AxisServer axisServer) {
812: this.axis = axisServer;
813: }
814: }
|