You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-dev@axis.apache.org by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com> on 2007/07/23 12:06:38 UTC

RE: measuring Axix 1.4 overhead

Any help regarding the below please? any suggestions on how to measure
the overhead Axis adds?

________________________________

From: Firas Khasawneh (fkhasawn) 
Sent: Sunday, July 22, 2007 11:50 PM
To: 'axis-user@ws.apache.org'
Subject: measuring Axix 1.4 overhead


Hi all,
 
Anybody knows how to measure the overhead Axis 1.4 adds to response
time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
 
Regards,
Firas Khasawneh

Re: measuring Axix 1.4 overhead

Posted by Deepal Jayasinghe <de...@opensource.lk>.
As I know in WSO2 WSAS you can deploy Axis1 services inside Axis2
without having any pain. So that you do not need to re-write anything to
use Axis2 , if you are an Axis1 user.

Thanks
Deepal
> Please see this
> http://ws.apache.org/axis2/1_2/migration.html
> -jaliya
>
>     ----- Original Message -----
>     *From:* Firas Khasawneh (fkhasawn) <ma...@cisco.com>
>     *To:* Jaliya Ekanayake <ma...@apache.org>
>     *Cc:* axis-dev@ws.apache.org <ma...@ws.apache.org>
>     *Sent:* Tuesday, July 24, 2007 12:22 PM
>     *Subject:* RE: measuring Axix 1.4 overhead
>
>     Hi Jaliya,
>      
>     To use Axis2 do  I need to change anything in my service code or
>     rebuild it or can I just replace the library jars?
>      
>     Thanks,
>     Firas
>
>     ------------------------------------------------------------------------
>     *From:* Jaliya Ekanayake [mailto:jnekanayake@gmail.com]
>     *Sent:* Tuesday, July 24, 2007 10:44 AM
>     *To:* Firas Khasawneh (fkhasawn)
>     *Cc:* axis-dev@ws.apache.org <ma...@ws.apache.org>
>     *Subject:* Re: measuring Axix 1.4 overhead
>
>     Hi Firas,
>      
>     Did you try Axis2 http://ws.apache.org/axis2/ ?
>     In axis2 processing starts without fully building the soap envelope.
>     And the performance figures for Axis2 is
>     http://www.wso2.org/library/588
>      
>     Thanks,
>     -jaliya
>      
>
>         ----- Original Message -----
>         *From:* Firas Khasawneh (fkhasawn) <ma...@cisco.com>
>         *To:* Jaliya Ekanayake <ma...@apache.org>
>         *Sent:* Tuesday, July 24, 2007 8:48 AM
>         *Subject:* RE: measuring Axix 1.4 overhead
>
>         Hi Jaliya,
>          
>         I tested with small size messages and 1 mb messages and there
>         is big difference, looks like Axis takes long time to process
>         large messages, but t4-t0 should give the processing time and
>         not the transport time. Also invoke time t3-t0 should give
>         only Axis engine overhead.
>          
>         Thanks,
>         Firas
>
>         ------------------------------------------------------------------------
>         *From:* Jaliya Ekanayake [mailto:jnekanayake@gmail.com]
>         *Sent:* Monday, July 23, 2007 4:34 PM
>         *To:* Firas Khasawneh (fkhasawn)
>         *Subject:* Re: measuring Axix 1.4 overhead
>
>         Hi Firas,
>          
>         Yes, t4-t0 should give you the results.
>         However the problem is that you use large message size.
>         My guess is that the processing happens before the total
>         retrieval of the message and hence it include the time it
>         takes to transfer the message as well.
>         Did you try with a small message sizes?
>          
>



---------------------------------------------------------------------
To unsubscribe, e-mail: axis-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: axis-dev-help@ws.apache.org


Re: measuring Axix 1.4 overhead

Posted by Jaliya Ekanayake <jn...@gmail.com>.
Please see this
http://ws.apache.org/axis2/1_2/migration.html
-jaliya
  ----- Original Message ----- 
  From: Firas Khasawneh (fkhasawn) 
  To: Jaliya Ekanayake 
  Cc: axis-dev@ws.apache.org 
  Sent: Tuesday, July 24, 2007 12:22 PM
  Subject: RE: measuring Axix 1.4 overhead


  Hi Jaliya,

  To use Axis2 do  I need to change anything in my service code or rebuild it or can I just replace the library jars?

  Thanks,
  Firas



------------------------------------------------------------------------------
  From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
  Sent: Tuesday, July 24, 2007 10:44 AM
  To: Firas Khasawneh (fkhasawn)
  Cc: axis-dev@ws.apache.org
  Subject: Re: measuring Axix 1.4 overhead


  Hi Firas,

  Did you try Axis2 http://ws.apache.org/axis2/ ?
  In axis2 processing starts without fully building the soap envelope.
  And the performance figures for Axis2 is http://www.wso2.org/library/588

  Thanks,
  -jaliya

    ----- Original Message ----- 
    From: Firas Khasawneh (fkhasawn) 
    To: Jaliya Ekanayake 
    Sent: Tuesday, July 24, 2007 8:48 AM
    Subject: RE: measuring Axix 1.4 overhead


    Hi Jaliya,

    I tested with small size messages and 1 mb messages and there is big difference, looks like Axis takes long time to process large messages, but t4-t0 should give the processing time and not the transport time. Also invoke time t3-t0 should give only Axis engine overhead.

    Thanks,
    Firas



----------------------------------------------------------------------------
    From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
    Sent: Monday, July 23, 2007 4:34 PM
    To: Firas Khasawneh (fkhasawn)
    Subject: Re: measuring Axix 1.4 overhead


    Hi Firas,

    Yes, t4-t0 should give you the results.
    However the problem is that you use large message size.
    My guess is that the processing happens before the total retrieval of the message and hence it include the time it takes to transfer the message as well.
    Did you try with a small message sizes?

    Thanks,
    -jaliya
      ----- Original Message ----- 
      From: Firas Khasawneh (fkhasawn) 
      To: Jaliya Ekanayake ; axis-user@ws.apache.org 
      Sent: Monday, July 23, 2007 3:49 PM
      Subject: RE: measuring Axix 1.4 overhead


      Hi Jaliya,

      I am attaching the AxisServlet.java after adding benchmark times, if you look at line 791 in the doPost method, the invoke shoudl calculate the invokation time for the Axis engine without the network time but for some reason it looks like it is including this time in the invokation time which does not make any sense. I am testing with 1 MB size files so I am not sure. below is AxisServlet.java, sorry for cuttin and pasting it here but I was not sure if this email list allows attachments:

      /*

      * Copyright 2001-2004 The Apache Software Foundation.

      *

      * Licensed under the Apache License, Version 2.0 (the "License");

      * you may not use this file except in compliance with the License.

      * You may obtain a copy of the License at

      *

      * http://www.apache.org/licenses/LICENSE-2.0

      *

      * Unless required by applicable law or agreed to in writing, software

      * distributed under the License is distributed on an "AS IS" BASIS,

      * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

      * See the License for the specific language governing permissions and

      * limitations under the License.

      */


      package org.apache.axis.transport.http;


      import java.io.File;

      import java.io.IOException;

      import java.io.PrintWriter;

      import java.lang.reflect.Method;

      import java.lang.reflect.InvocationTargetException;

      import java.net.HttpURLConnection;

      import java.util.ArrayList;

      import java.util.Enumeration;

      import java.util.Iterator;


      import javax.servlet.ServletContext;

      import javax.servlet.ServletException;

      import javax.servlet.http.HttpServletRequest;

      import javax.servlet.http.HttpServletResponse;

      import javax.servlet.http.HttpUtils;

      import javax.xml.soap.MimeHeader;

      import javax.xml.soap.MimeHeaders;

      import javax.xml.soap.SOAPException;

      import javax.xml.soap.SOAPMessage;


      import org.apache.axis.AxisEngine;

      import org.apache.axis.AxisFault;

      import org.apache.axis.ConfigurationException;

      import org.apache.axis.Constants;

      import org.apache.axis.Handler;

      import org.apache.axis.Message;

      import org.apache.axis.MessageContext;

      import org.apache.axis.SimpleTargetedChain;

      import org.apache.axis.client.Service;

      import org.apache.axis.management.ServiceAdmin;

      import org.apache.axis.components.logger.LogFactory;

      import org.apache.axis.description.OperationDesc;

      import org.apache.axis.description.ServiceDesc;

      import org.apache.axis.handlers.soap.SOAPService;

      import org.apache.axis.security.servlet.ServletSecurityProvider;

      import org.apache.axis.utils.JavaUtils;

      import org.apache.axis.utils.Messages;

      import org.apache.axis.utils.XMLUtils;

      import org.apache.commons.logging.Log;

      import org.w3c.dom.Element;


      /**

      *

      * @author Doug Davis (dug@us.ibm.com)

      * @author Steve Loughran

      * xdoclet tags are not active yet; keep web.xml in sync.

      * To change the location of the services, change url-pattern in web.xml and

      * set parameter axis.servicesPath in server-config.wsdd. For more information see

      * <a href="http://ws.apache.org/axis/java/reference.html">Axis Reference Guide</a>.

      *

      * @web.servlet name="AxisServlet" display-name="Apache-Axis Servlet"

      * @web.servlet-mapping url-pattern="/servlet/AxisServlet"

      * @web.servlet-mapping url-pattern="*.jws"

      * @web.servlet-mapping url-pattern="/services/*"

      */

      public class AxisServlet extends AxisServletBase {

      protected static Log log =

      LogFactory.getLog(AxisServlet.class.getName());


      /**

      * this log is for timing

      */

      private static Log tlog =

      LogFactory.getLog(Constants.TIME_LOG_CATEGORY);


      /**

      * a separate log for exceptions lets users route them

      * differently from general low level debug info

      */

      private static Log exceptionLog =

      LogFactory.getLog(Constants.EXCEPTION_LOG_CATEGORY);


      public static final String INIT_PROPERTY_TRANSPORT_NAME =

      "transport.name";


      public static final String INIT_PROPERTY_USE_SECURITY =

      "use-servlet-security";

      public static final String INIT_PROPERTY_ENABLE_LIST =

      "axis.enableListQuery";


      public static final String INIT_PROPERTY_JWS_CLASS_DIR =

      "axis.jws.servletClassDir";


      // This will turn off the list of available services

      public static final String INIT_PROPERTY_DISABLE_SERVICES_LIST =

      "axis.disableServiceList";


      // Location of the services as defined by the servlet-mapping in web.xml

      public static final String INIT_PROPERTY_SERVICES_PATH =

      "axis.servicesPath";


      // These have default values.

      private String transportName;


      private Handler transport;


      private ServletSecurityProvider securityProvider = null;


      private String servicesPath;


      /**

      * cache of logging debug option; only evaluated at init time.

      * So no dynamic switching of logging options with this servlet.

      */

      private static boolean isDebug = false;


      /**

      * Should we enable the "?list" functionality on GETs? (off by

      * default because deployment information is a potential security

      * hole)

      */

      private boolean enableList = false;


      /**

      * Should we turn off the list of services when we receive a GET

      * at the servlet root?

      */

      private boolean disableServicesList = false;


      /**

      * Cached path to JWS output directory

      */

      private String jwsClassDir = null;

      protected String getJWSClassDir() {return jwsClassDir;

      }




      /**

      * create a new servlet instance

      */

      public AxisServlet() {

      }


      /**

      * Initialization method.

      */

      public void init() throws javax.servlet.ServletException {

      super.init();

      ServletContext context = getServletConfig().getServletContext();


      isDebug = log.isDebugEnabled();

      if (isDebug) {

      log.debug("In servlet init");

      }

      transportName = getOption(context,

      INIT_PROPERTY_TRANSPORT_NAME,

      HTTPTransport.DEFAULT_TRANSPORT_NAME);


      if (JavaUtils.isTrueExplicitly(getOption(context,

      INIT_PROPERTY_USE_SECURITY, null))) {

      securityProvider = new ServletSecurityProvider();

      }


      enableList =

      JavaUtils.isTrueExplicitly(getOption(context,

      INIT_PROPERTY_ENABLE_LIST, null));


      jwsClassDir = getOption(context, INIT_PROPERTY_JWS_CLASS_DIR, null);


      // Should we list services?

      disableServicesList = JavaUtils.isTrue(getOption(context,

      INIT_PROPERTY_DISABLE_SERVICES_LIST, "false"));


      servicesPath = getOption(context, INIT_PROPERTY_SERVICES_PATH,

      "/services/");


      /**

      * There are DEFINATE problems here if

      * getHomeDir and/or getDefaultJWSClassDir return null

      * (as they could with WebLogic).

      * This needs to be reexamined in the future, but this

      * should fix any NPE's in the mean time.

      */

      if (jwsClassDir != null) {

      if (getHomeDir() != null) {

      jwsClassDir = getHomeDir() + jwsClassDir;

      }

      } else {

      jwsClassDir = getDefaultJWSClassDir();

      }


      initQueryStringHandlers();


      // Setup the service admin

      try {

      ServiceAdmin.setEngine(this.getEngine(), context.getServerInfo());

      } catch (AxisFault af) {

      exceptionLog.info("Exception setting AxisEngine on ServiceAdmin " +

      af);

      }

      }




      /**

      * Process GET requests. This includes handoff of pseudo-SOAP requests

      *

      * @param request request in

      * @param response request out

      * @throws ServletException

      * @throws IOException

      */

      public void doGet(HttpServletRequest request, HttpServletResponse response) throws

      ServletException, IOException {

      if (isDebug) {

      log.debug("Enter: doGet()");


      }

      PrintWriter writer = new FilterPrintWriter(response);


      try {

      AxisEngine engine = getEngine();

      ServletContext servletContext =

      getServletConfig().getServletContext();


      String pathInfo = request.getPathInfo();

      String realpath = servletContext.getRealPath(request.getServletPath());

      if (realpath == null) {

      realpath = request.getServletPath();

      }


      //JWS pages are special; they are the servlet path and there

      //is no pathinfo...we map the pathinfo to the servlet path to keep

      //it happy

      boolean isJWSPage = request.getRequestURI().endsWith(".jws");

      if (isJWSPage) {

      pathInfo = request.getServletPath();

      }


      // Try to execute a query string plugin and return upon success.


      if (processQuery(request, response, writer) == true) {

      long reqout = System.currentTimeMillis();

      return;

      }


      boolean hasNoPath = (pathInfo == null || pathInfo.equals(""));

      if (!disableServicesList) {

      if(hasNoPath) {

      // If the user requested the servlet (i.e. /axis/servlet/AxisServlet)

      // with no service name, present the user with a list of deployed

      // services to be helpful

      // Don't do this if has been turned off

      reportAvailableServices(response, writer, request);

      } else if (realpath != null) {

      // We have a pathname, so now we perform WSDL or list operations


      // get message context w/ various properties set

      MessageContext msgContext = createMessageContext(engine,

      request, response);


      // NOTE: HttpUtils.getRequestURL has been deprecated.

      // This line SHOULD be:

      // String url = req.getRequestURL().toString()

      // HOWEVER!!!! DON'T REPLACE IT! There's a bug in

      // req.getRequestURL that is not in HttpUtils.getRequestURL

      // req.getRequestURL returns "localhost" in the remote

      // scenario rather than the actual host name.

      //

      // But more importantly, getRequestURL() is a servlet 2.3

      // API and to support servlet 2.2 (aka WebSphere 4)

      // we need to leave this in for a while longer. tomj 10/14/2004

      //

      String url = HttpUtils.getRequestURL(request).toString();


      msgContext.setProperty(MessageContext.TRANS_URL, url);


      // See if we can locate the desired service. If we

      // can't, return a 404 Not Found. Otherwise, just

      // print the placeholder message.


      String serviceName;

      if (pathInfo.startsWith("/")) {

      serviceName = pathInfo.substring(1);

      } else {

      serviceName = pathInfo;

      }


      SOAPService s = engine.getService(serviceName);

      if (s == null) {

      //no service: report it

      if (isJWSPage) {

      reportCantGetJWSService(request, response, writer);

      } else {

      reportCantGetAxisService(request, response, writer);

      }


      } else {

      //print a snippet of service info.

      reportServiceInfo(response, writer, s, serviceName);

      }

      }

      } else {

      // We didn't have a real path in the request, so just

      // print a message informing the user that they reached

      // the servlet.


      response.setContentType("text/html; charset=utf-8");

      writer.println("<html><h1>Axis HTTP Servlet</h1>");

      writer.println(Messages.getMessage("reachedServlet00"));


      writer.println("<p>" +

      Messages.getMessage("transportName00",

      "<b>" + transportName + "</b>"));

      writer.println("</html>");

      }

      } catch (AxisFault fault) {

      reportTroubleInGet(fault, response, writer);

      } catch (Exception e) {

      reportTroubleInGet(e, response, writer);

      } finally {

      writer.close();

      if (isDebug) {

      log.debug("Exit: doGet()");

      }

      }

      }


      /**

      * when we get an exception or an axis fault in a GET, we handle

      * it almost identically: we go 'something went wrong', set the response

      * code to 500 and then dump info. But we dump different info for an axis fault

      * or subclass thereof.

      * @param exception what went wrong

      * @param response current response

      * @param writer open writer to response

      */

      private void reportTroubleInGet(Throwable exception,

      HttpServletResponse response,

      PrintWriter writer) {

      response.setContentType("text/html; charset=utf-8");

      response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

      writer.println("<h2>" +

      Messages.getMessage("error00") +

      "</h2>");

      writer.println("<p>" +

      Messages.getMessage("somethingWrong00") +

      "</p>");

      if (exception instanceof AxisFault) {

      AxisFault fault = (AxisFault) exception;

      processAxisFault(fault);

      writeFault(writer, fault);

      } else {

      logException(exception);

      writer.println("<pre>Exception - " + exception + "<br>");

      //dev systems only give fault dumps

      if (isDevelopment()) {

      writer.println(JavaUtils.stackToString(exception));

      }

      writer.println("</pre>");

      }

      }


      /**

      * routine called whenever an axis fault is caught; where they

      * are logged and any other business. The method may modify the fault

      * in the process

      * @param fault what went wrong.

      */

      protected void processAxisFault(AxisFault fault) {

      //log the fault

      Element runtimeException = fault.lookupFaultDetail(

      Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

      if (runtimeException != null) {

      exceptionLog.info(Messages.getMessage("axisFault00"), fault);

      //strip runtime details

      fault.removeFaultDetail(Constants.

      QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

      } else if (exceptionLog.isDebugEnabled()) {

      exceptionLog.debug(Messages.getMessage("axisFault00"), fault);

      }

      //dev systems only give fault dumps

      if (!isDevelopment()) {

      //strip out the stack trace

      fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE);

      }

      }


      /**

      * log any exception to our output log, at our chosen level

      * @param e what went wrong

      */

      protected void logException(Throwable e) {

      exceptionLog.info(Messages.getMessage("exception00"), e);

      }


      /**

      * this method writes a fault out to an HTML stream. This includes

      * escaping the strings to defend against cross-site scripting attacks

      * @param writer

      * @param axisFault

      */

      private void writeFault(PrintWriter writer, AxisFault axisFault) {

      String localizedMessage = XMLUtils.xmlEncodeString(axisFault.

      getLocalizedMessage());

      writer.println("<pre>Fault - " + localizedMessage + "<br>");

      writer.println(axisFault.dumpToString());

      writer.println("</pre>");

      }


      /**

      * print a snippet of service info.

      * @param service service

      * @param writer output channel

      * @param serviceName where to put stuff

      */


      protected void reportServiceInfo(HttpServletResponse response,

      PrintWriter writer, SOAPService service,

      String serviceName) {

      response.setContentType("text/html; charset=utf-8");


      writer.println("<h1>"

      + service.getName()

      + "</h1>");

      writer.println(

      "<p>" +

      Messages.getMessage("axisService00") +

      "</p>");

      writer.println(

      "<i>" +

      Messages.getMessage("perhaps00") +

      "</i>");

      }


      /**

      * report that we have no WSDL

      *

      * This method was moved to the querystring handler QSWSDLHandler. The

      * method reportNoWSDL in AxisServlet is never called. Perhaps the method

      * is overwritten in subclasses of AxisServlet so the method wasn't

      * removed. See the discussion in

      *

      * http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23845

      *

      * @param res

      * @param writer

      * @param moreDetailCode optional name of a message to provide more detail

      * @param axisFault optional fault string, for extra info at debug time only

      */

      protected void reportNoWSDL(HttpServletResponse res, PrintWriter writer,

      String moreDetailCode, AxisFault axisFault) {

      }




      /**

      * This method lists the available services; it is called when there is

      * nothing to execute on a GET

      * @param response

      * @param writer

      * @param request

      * @throws ConfigurationException

      * @throws AxisFault

      */

      protected void reportAvailableServices(HttpServletResponse response,

      PrintWriter writer,

      HttpServletRequest request) throws

      ConfigurationException, AxisFault {

      AxisEngine engine = getEngine();


      response.setContentType("text/html; charset=utf-8");

      writer.println("<h2>And now... Some Services</h2>");


      Iterator i;

      try {

      i = engine.getConfig().getDeployedServices();

      } catch (ConfigurationException configException) {

      //turn any internal configuration exceptions back into axis faults

      //if that is what they are

      if (configException.getContainedException() instanceof AxisFault) {

      throw (AxisFault) configException.getContainedException();

      } else {

      throw configException;

      }

      }

      // baseURL may change if <endpointURL> tag is used for

      // custom deployment at a different location

      String defaultBaseURL = getWebappBase(request) + servicesPath;

      writer.println("<ul>");

      while (i.hasNext()) {

      ServiceDesc sd = (ServiceDesc) i.next();

      StringBuffer sb = new StringBuffer();

      sb.append("<li>");

      String name = sd.getName();

      sb.append(name);

      sb.append(" <a href=\"");

      String endpointURL = sd.getEndpointURL();

      String baseURL = (endpointURL == null) ? defaultBaseURL :

      endpointURL;

      sb.append(baseURL);

      sb.append(name);

      sb.append("?wsdl\"><i>(wsdl)</i></a></li>");

      writer.println(sb.toString());

      ArrayList operations = sd.getOperations();

      if (!operations.isEmpty()) {

      writer.println("<ul>");

      for (Iterator it = operations.iterator(); it.hasNext(); ) {

      OperationDesc desc = (OperationDesc) it.next();

      writer.println("<li>" + desc.getName());

      }

      writer.println("</ul>");

      }

      }

      writer.println("</ul>");

      }


      /**

      * generate the error response to indicate that there is apparently no endpoint there

      * @param request the request that didnt have an edpoint

      * @param response response we are generating

      * @param writer open writer for the request

      */

      protected void reportCantGetAxisService(HttpServletRequest request,

      HttpServletResponse response,

      PrintWriter writer) {

      // no such service....

      response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

      response.setContentType("text/html; charset=utf-8");

      writer.println("<h2>" +

      Messages.getMessage("error00") + "</h2>");

      writer.println("<p>" +

      Messages.getMessage("noService06") +

      "</p>");

      }


      /**

      * probe for a JWS page and report 'no service' if one is not found there

      * @param request the request that didnt have an edpoint

      * @param response response we are generating

      * @param writer open writer for the request

      */

      protected void reportCantGetJWSService(HttpServletRequest request,

      HttpServletResponse response,

      PrintWriter writer) {

      // first look to see if there is a service

      // requestPath is a work around to support serving .jws web services

      // from services URL - see AXIS-843 for more information

      String requestPath = request.getServletPath() + ((request.getPathInfo() != null) ?

      request.getPathInfo() : "");

      String realpath = getServletConfig().getServletContext()

      .getRealPath(requestPath);

      log.debug("JWS real path: " + realpath);

      boolean foundJWSFile = (new File(realpath).exists()) &&

      (realpath.endsWith(Constants.

      JWS_DEFAULT_FILE_EXTENSION));

      response.setContentType("text/html; charset=utf-8");

      if (foundJWSFile) {

      response.setStatus(HttpURLConnection.HTTP_OK);

      writer.println(Messages.getMessage("foundJWS00") + "<p>");

      String url = request.getRequestURI();

      String urltext = Messages.getMessage("foundJWS01");

      writer.println("<a href='" + url + "?wsdl'>" + urltext + "</a>");

      } else {

      response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

      writer.println(Messages.getMessage("noService06"));

      }

      }




      /**

      * Process a POST to the servlet by handing it off to the Axis Engine.

      * Here is where SOAP messages are received

      * @param req posted request

      * @param res respose

      * @throws ServletException trouble

      * @throws IOException different trouble

      */

      public void doPost(HttpServletRequest req, HttpServletResponse res) throws

      ServletException, IOException {

      long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;

      String soapAction = null;

      MessageContext msgContext = null;

      if (isDebug) {

      log.debug("Enter: doPost()");

      }

      t0 = System.currentTimeMillis();

      if (tlog.isDebugEnabled()) {

      t0 = System.currentTimeMillis();

      }


      Message responseMsg = null;

      String contentType = null;


      try {

      AxisEngine engine = getEngine();


      if (engine == null) {

      // !!! should return a SOAP fault...

      ServletException se =

      new ServletException(Messages.getMessage("noEngine00"));

      log.debug("No Engine!", se);

      throw se;

      }


      res.setBufferSize(1024 * 8); // provide performance boost.


      /** get message context w/ various properties set

      */

      msgContext = createMessageContext(engine, req, res);


      // ? OK to move this to 'getMessageContext',

      // ? where it would also be picked up for 'doGet()' ?

      if (securityProvider != null) {

      if (isDebug) {

      log.debug("securityProvider:" + securityProvider);

      }

      msgContext.setProperty(MessageContext.SECURITY_PROVIDER,

      securityProvider);

      }


      /* Get request message

      */

      Message requestMsg =

      new Message(req.getInputStream(),

      false,

      req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE),

      req.getHeader(HTTPConstants.

      HEADER_CONTENT_LOCATION));

      // Transfer HTTP headers to MIME headers for request message.

      MimeHeaders requestMimeHeaders = requestMsg.getMimeHeaders();

      for (Enumeration e = req.getHeaderNames(); e.hasMoreElements(); ) {

      String headerName = (String) e.nextElement();

      for (Enumeration f = req.getHeaders(headerName);

      f.hasMoreElements(); ) {

      String headerValue = (String) f.nextElement();

      requestMimeHeaders.addHeader(headerName, headerValue);

      }

      }


      if (isDebug) {

      log.debug("Request Message:" + requestMsg);


      /* Set the request(incoming) message field in the context */

      /**********************************************************/

      }

      msgContext.setRequestMessage(requestMsg);

      String url = HttpUtils.getRequestURL(req).toString();

      msgContext.setProperty(MessageContext.TRANS_URL, url);

      // put character encoding of request to message context

      // in order to reuse it during the whole process.

      String requestEncoding;

      try {

      requestEncoding = (String) requestMsg.getProperty(SOAPMessage.

      CHARACTER_SET_ENCODING);

      if (requestEncoding != null) {

      msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

      requestEncoding);

      }

      } catch (SOAPException e1) {

      }


      try {

      /**

      * Save the SOAPAction header in the MessageContext bag.

      * This will be used to tell the Axis Engine which service

      * is being invoked. This will save us the trouble of

      * having to parse the Request message - although we will

      * need to double-check later on that the SOAPAction header

      * does in fact match the URI in the body.

      */

      // (is this last stmt true??? (I don't think so - Glen))

      /********************************************************/

      soapAction = getSoapAction(req);


      if (soapAction != null) {

      msgContext.setUseSOAPAction(true);

      msgContext.setSOAPActionURI(soapAction);

      }


      // Create a Session wrapper for the HTTP session.

      // These can/should be pooled at some point.

      // (Sam is Watching! :-)

      msgContext.setSession(new AxisHttpSession(req));

      t1 = System.currentTimeMillis();

      if (tlog.isDebugEnabled()) {

      t1 = System.currentTimeMillis();

      }

      /* Invoke the Axis engine... */

      /*****************************/

      if (isDebug) {

      log.debug("Invoking Axis Engine.");

      //here we run the message by the engine

      }

      engine.invoke(msgContext);

      if (isDebug) {

      log.debug("Return from Axis Engine.");

      }

      t2 = System.currentTimeMillis();

      if (tlog.isDebugEnabled()) {

      t2 = System.currentTimeMillis();

      }

      responseMsg = msgContext.getResponseMessage();


      // We used to throw exceptions on null response messages.

      // They are actually OK in certain situations (asynchronous

      // services), so fall through here and return an ACCEPTED

      // status code below. Might want to install a configurable

      // error check for this later.

      } catch (AxisFault fault) {

      //log and sanitize

      processAxisFault(fault);

      configureResponseFromAxisFault(res, fault);

      responseMsg = msgContext.getResponseMessage();

      if (responseMsg == null) {

      responseMsg = new Message(fault);

      ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

      getMessage().setMessageContext(msgContext);

      }

      } catch (Exception e) {

      //other exceptions are internal trouble

      responseMsg = msgContext.getResponseMessage();

      res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

      responseMsg = convertExceptionToAxisFault(e, responseMsg);

      ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

      getMessage().setMessageContext(msgContext);

      } catch (Throwable t) {

      logException(t);

      //other exceptions are internal trouble

      responseMsg = msgContext.getResponseMessage();

      res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

      responseMsg = new Message(new AxisFault(t.toString(),t));

      ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

      getMessage().setMessageContext(msgContext);

      }

      } catch (AxisFault fault) {

      processAxisFault(fault);

      configureResponseFromAxisFault(res, fault);

      responseMsg = msgContext.getResponseMessage();

      if (responseMsg == null) {

      responseMsg = new Message(fault);

      ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

      getMessage().setMessageContext(msgContext);

      }

      }

      t3 = System.currentTimeMillis();

      if (tlog.isDebugEnabled()) {

      t3 = System.currentTimeMillis();

      }


      /* Send response back along the wire... */

      /***********************************/

      if (responseMsg != null) {

      // Transfer MIME headers to HTTP headers for response message.

      MimeHeaders responseMimeHeaders = responseMsg.getMimeHeaders();

      for (Iterator i = responseMimeHeaders.getAllHeaders(); i.hasNext(); ) {

      MimeHeader responseMimeHeader = (MimeHeader) i.next();

      res.addHeader(responseMimeHeader.getName(),

      responseMimeHeader.getValue());

      }

      // synchronize the character encoding of request and response

      String responseEncoding = (String) msgContext.getProperty(

      SOAPMessage.CHARACTER_SET_ENCODING);

      if (responseEncoding != null) {

      try {

      responseMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

      responseEncoding);

      } catch (SOAPException e) {

      }

      }

      //determine content type from message response

      contentType = responseMsg.getContentType(msgContext.

      getSOAPConstants());

      sendResponse(contentType, res, responseMsg);

      } else {

      // No content, so just indicate accepted

      res.setStatus(202);

      }


      if (isDebug) {

      log.debug("Response sent.");

      log.debug("Exit: doPost()");

      }

      t4 = System.currentTimeMillis();

      System.out.println("Axis stats: " +

      " pre=" + (t1 - t0) +

      " invoke=" + (t2 - t1) +

      " post=" + (t3 - t2) +

      " send=" + (t4 - t3) +

      " total=" + (t4 - t0));

      if (tlog.isDebugEnabled()) {

      t4 = System.currentTimeMillis();

      tlog.debug("axisServlet.doPost: " + soapAction +

      " pre=" + (t1 - t0) +

      " invoke=" + (t2 - t1) +

      " post=" + (t3 - t2) +

      " send=" + (t4 - t3) +

      " " + msgContext.getTargetService() + "." +

      ((msgContext.getOperation() == null) ?

      "" : msgContext.getOperation().getName()));

      }


      }


      /**

      * Configure the servlet response status code and maybe other headers

      * from the fault info.

      * @param response response to configure

      * @param fault what went wrong

      */

      private void configureResponseFromAxisFault(HttpServletResponse response,

      AxisFault fault) {

      // then get the status code

      // It's been suggested that a lack of SOAPAction

      // should produce some other error code (in the 400s)...

      int status = getHttpServletResponseStatus(fault);

      if (status == HttpServletResponse.SC_UNAUTHORIZED) {

      // unauth access results in authentication request

      // TODO: less generic realm choice?

      response.setHeader("WWW-Authenticate", "Basic realm=\"AXIS\"");

      }

      response.setStatus(status);

      }


      /**

      * turn any Exception into an AxisFault, log it, set the response

      * status code according to what the specifications say and

      * return a response message for posting. This will be the response

      * message passed in if non-null; one generated from the fault otherwise.

      *

      * @param exception what went wrong

      * @param responseMsg what response we have (if any)

      * @return a response message to send to the user

      */

      private Message convertExceptionToAxisFault(Exception exception,

      Message responseMsg) {

      logException(exception);

      if (responseMsg == null) {

      AxisFault fault = AxisFault.makeFault(exception);

      processAxisFault(fault);

      responseMsg = new Message(fault);

      }

      return responseMsg;

      }


      /**

      * Extract information from AxisFault and map it to a HTTP Status code.

      *

      * @param af Axis Fault

      * @return HTTP Status code.

      */

      protected int getHttpServletResponseStatus(AxisFault af) {

      // TODO: Should really be doing this with explicit AxisFault

      // subclasses... --Glen

      return af.getFaultCode().getLocalPart().startsWith("Server.Unauth")

      ? HttpServletResponse.SC_UNAUTHORIZED

      : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

      // This will raise a 401 for both

      // "Unauthenticated" & "Unauthorized"...

      }


      /**

      * write a message to the response, set appropriate headers for content

      * type..etc.

      * @param res response

      * @param responseMsg message to write

      * @throws AxisFault

      * @throws IOException if the response stream can not be written to

      */

      private void sendResponse(String contentType,

      HttpServletResponse res,

      Message responseMsg) throws AxisFault,

      IOException {

      if (responseMsg == null) {

      res.setStatus(HttpServletResponse.SC_NO_CONTENT);

      if (isDebug) {

      log.debug("NO AXIS MESSAGE TO RETURN!");

      //String resp = Messages.getMessage("noData00");

      //res.setContentLength((int) resp.getBytes().length);

      //res.getWriter().print(resp);

      }

      } else {

      if (isDebug) {

      log.debug("Returned Content-Type:" +

      contentType);

      // log.debug("Returned Content-Length:" +

      // responseMsg.getContentLength());

      }


      try {

      res.setContentType(contentType);


      /* My understand of Content-Length

      * HTTP 1.0

      * -Required for requests, but optional for responses.

      * HTTP 1.1

      * - Either Content-Length or HTTP Chunking is required.

      * Most servlet engines will do chunking if content-length is not specified.

      *

      *

      */


      //if(clientVersion == HTTPConstants.HEADER_PROTOCOL_V10) //do chunking if necessary.

      // res.setContentLength(responseMsg.getContentLength());


      responseMsg.writeTo(res.getOutputStream());

      } catch (SOAPException e) {

      logException(e);

      }

      }


      if (!res.isCommitted()) {

      res.flushBuffer(); // Force it right now.

      }

      }


      /**

      * Place the Request message in the MessagContext object - notice

      * that we just leave it as a 'ServletRequest' object and let the

      * Message processing routine convert it - we don't do it since we

      * don't know how it's going to be used - perhaps it might not

      * even need to be parsed.

      * @return a message context

      */

      private MessageContext createMessageContext(AxisEngine engine,

      HttpServletRequest req,

      HttpServletResponse res) {

      MessageContext msgContext = new MessageContext(engine);


      String requestPath = getRequestPath(req);


      if (isDebug) {

      log.debug("MessageContext:" + msgContext);

      log.debug("HEADER_CONTENT_TYPE:" +

      req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE));

      log.debug("HEADER_CONTENT_LOCATION:" +

      req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION));

      log.debug("Constants.MC_HOME_DIR:" + String.valueOf(getHomeDir()));

      log.debug("Constants.MC_RELATIVE_PATH:" + requestPath);

      log.debug("HTTPConstants.MC_HTTP_SERVLETLOCATION:" +

      String.valueOf(getWebInfPath()));

      log.debug("HTTPConstants.MC_HTTP_SERVLETPATHINFO:" +

      req.getPathInfo());

      log.debug("HTTPConstants.HEADER_AUTHORIZATION:" +

      req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

      log.debug("Constants.MC_REMOTE_ADDR:" + req.getRemoteAddr());

      log.debug("configPath:" + String.valueOf(getWebInfPath()));

      }


      /* Set the Transport */

      /*********************/

      msgContext.setTransportName(transportName);


      /* Save some HTTP specific info in the bag in case someone needs it */

      /********************************************************************/

      msgContext.setProperty(Constants.MC_JWS_CLASSDIR, jwsClassDir);

      msgContext.setProperty(Constants.MC_HOME_DIR, getHomeDir());

      msgContext.setProperty(Constants.MC_RELATIVE_PATH, requestPath);

      msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this);

      msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, req);

      msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, res);

      msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION,

      getWebInfPath());

      msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO,

      req.getPathInfo());

      msgContext.setProperty(HTTPConstants.HEADER_AUTHORIZATION,

      req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

      msgContext.setProperty(Constants.MC_REMOTE_ADDR, req.getRemoteAddr());


      // Set up a javax.xml.rpc.server.ServletEndpointContext

      ServletEndpointContextImpl sec = new ServletEndpointContextImpl();


      msgContext.setProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT, sec);

      /* Save the real path */

      /**********************/

      String realpath = getServletConfig().getServletContext()

      .getRealPath(requestPath);


      if (realpath != null) {

      msgContext.setProperty(Constants.MC_REALPATH, realpath);

      }


      msgContext.setProperty(Constants.MC_CONFIGPATH, getWebInfPath());


      return msgContext;

      }


      /**

      * Extract the SOAPAction header.

      * if SOAPAction is null then we'll we be forced to scan the body for it.

      * if SOAPAction is "" then use the URL

      * @param req incoming request

      * @return the action

      * @throws AxisFault

      */

      private String getSoapAction(HttpServletRequest req) throws AxisFault {

      String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);

      if (soapAction == null) {

      String contentType = req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);

      if(contentType != null) {

      int index = contentType.indexOf("action");

      if(index != -1){

      soapAction = contentType.substring(index + 7);

      }

      }

      }


      if (isDebug) {

      log.debug("HEADER_SOAP_ACTION:" + soapAction);


      /**

      * Technically, if we don't find this header, we should probably fault.

      * It's required in the SOAP HTTP binding.

      */

      }

      if (soapAction == null) {

      AxisFault af = new AxisFault("Client.NoSOAPAction",

      Messages.getMessage("noHeader00",

      "SOAPAction"),

      null, null);


      exceptionLog.error(Messages.getMessage("genFault00"), af);


      throw af;

      }

      // the SOAP 1.1 spec & WS-I 1.0 says:

      // soapaction = "SOAPAction" ":" [ <"> URI-reference <"> ]

      // some implementations leave off the quotes

      // we strip them if they are present

      if (soapAction.startsWith("\"") && soapAction.endsWith("\"")

      && soapAction.length() >= 2) {

      int end = soapAction.length() - 1;

      soapAction = soapAction.substring(1, end);

      }


      if (soapAction.length() == 0) {

      soapAction = req.getContextPath(); // Is this right?


      }

      return soapAction;

      }


      /**

      * Provided to allow overload of default JWSClassDir

      * by derived class.

      * @return directory for JWS files

      */

      protected String getDefaultJWSClassDir() {

      return (getWebInfPath() == null)

      ? null // ??? what is a good FINAL default for WebLogic?

      : getWebInfPath() + File.separator + "jwsClasses";

      }


      /**

      * Initialize a Handler for the transport defined in the Axis server config.

      * This includes optionally filling in query string handlers.

      */


      public void initQueryStringHandlers() {

      try {

      this.transport = getEngine().getTransport(this.transportName);


      if (this.transport == null) {

      // No transport by this name is defined. Therefore, fill in default

      // query string handlers.


      this.transport = new SimpleTargetedChain();


      this.transport.setOption("qs.list",

      "org.apache.axis.transport.http.QSListHandler");

      this.transport.setOption("qs.method",

      "org.apache.axis.transport.http.QSMethodHandler");

      this.transport.setOption("qs.wsdl",

      "org.apache.axis.transport.http.QSWSDLHandler");


      return;

      }


      else {

      // See if we should use the default query string handlers.

      // By default, set this to true (for backwards compatibility).


      boolean defaultQueryStrings = true;

      String useDefaults = (String)this.transport.getOption(

      "useDefaultQueryStrings");


      if ((useDefaults != null) &&

      useDefaults.toLowerCase().equals("false")) {

      defaultQueryStrings = false;

      }


      if (defaultQueryStrings == true) {

      // We should use defaults, so fill them in.


      this.transport.setOption("qs.list",

      "org.apache.axis.transport.http.QSListHandler");

      this.transport.setOption("qs.method",

      "org.apache.axis.transport.http.QSMethodHandler");

      this.transport.setOption("qs.wsdl",

      "org.apache.axis.transport.http.QSWSDLHandler");

      }

      }

      }


      catch (AxisFault e) {

      // Some sort of problem occurred, let's just make a default transport.


      this.transport = new SimpleTargetedChain();


      this.transport.setOption("qs.list",

      "org.apache.axis.transport.http.QSListHandler");

      this.transport.setOption("qs.method",

      "org.apache.axis.transport.http.QSMethodHandler");

      this.transport.setOption("qs.wsdl",

      "org.apache.axis.transport.http.QSWSDLHandler");


      return;

      }

      }


      /**

      * Attempts to invoke a plugin for the query string supplied in the URL.

      *

      * @param request the servlet's HttpServletRequest object.

      * @param response the servlet's HttpServletResponse object.

      * @param writer the servlet's PrintWriter object.

      */


      private boolean processQuery(HttpServletRequest request,

      HttpServletResponse response,

      PrintWriter writer) throws AxisFault {

      // Attempt to instantiate a plug-in handler class for the query string

      // handler classes defined in the HTTP transport.


      String path = request.getServletPath();

      String queryString = request.getQueryString();

      String serviceName;

      AxisEngine engine = getEngine();

      Iterator i = this.transport.getOptions().keySet().iterator();


      if (queryString == null) {

      return false;

      }


      String servletURI = request.getContextPath() + path;

      String reqURI = request.getRequestURI();

      // chop off '/'.

      if (servletURI.length() + 1 < reqURI.length()) {

      serviceName = reqURI.substring(servletURI.length() + 1);

      } else {

      serviceName = "";

      } while (i.hasNext() == true) {

      String queryHandler = (String) i.next();


      if (queryHandler.startsWith("qs.") == true) {

      // Only attempt to match the query string with transport

      // parameters prefixed with "qs:".


      String handlerName = queryHandler.substring

      (queryHandler.indexOf(".") + 1).

      toLowerCase();


      // Determine the name of the plugin to invoke by using all text

      // in the query string up to the first occurence of &, =, or the

      // whole string if neither is present.


      int length = 0;

      boolean firstParamFound = false;


      while (firstParamFound == false && length < queryString.length()) {

      char ch = queryString.charAt(length++);


      if (ch == '&' || ch == '=') {

      firstParamFound = true;


      --length;

      }

      }


      if (length < queryString.length()) {

      queryString = queryString.substring(0, length);

      }


      if (queryString.toLowerCase().equals(handlerName) == true) {

      // Query string matches a defined query string handler name.


      // If the defined class name for this query string handler is blank,

      // just return (the handler is "turned off" in effect).


      if (this.transport.getOption(queryHandler).equals("")) {

      return false;

      }


      try {

      // Attempt to dynamically load the query string handler

      // and its "invoke" method.


      MessageContext msgContext = createMessageContext(engine,

      request, response);

      Class plugin = Class.forName((String)this.transport.

      getOption(queryHandler));

      Method pluginMethod = plugin.getDeclaredMethod("invoke",

      new Class[] {msgContext.getClass()});

      String url = HttpUtils.getRequestURL(request).toString();


      // Place various useful servlet-related objects in

      // the MessageContext object being delivered to the

      // plugin.

      msgContext.setProperty(MessageContext.TRANS_URL, url);

      msgContext.setProperty(HTTPConstants.

      PLUGIN_SERVICE_NAME, serviceName);

      msgContext.setProperty(HTTPConstants.PLUGIN_NAME,

      handlerName);

      msgContext.setProperty(HTTPConstants.

      PLUGIN_IS_DEVELOPMENT,

      new Boolean(isDevelopment()));

      msgContext.setProperty(HTTPConstants.PLUGIN_ENABLE_LIST,

      new Boolean(enableList));

      msgContext.setProperty(HTTPConstants.PLUGIN_ENGINE,

      engine);

      msgContext.setProperty(HTTPConstants.PLUGIN_WRITER,

      writer);

      msgContext.setProperty(HTTPConstants.PLUGIN_LOG, log);

      msgContext.setProperty(HTTPConstants.

      PLUGIN_EXCEPTION_LOG,

      exceptionLog);


      // Invoke the plugin.


      pluginMethod.invoke(plugin.newInstance(),

      new Object[] {msgContext});


      writer.close();


      return true;

      } catch (InvocationTargetException ie) {

      reportTroubleInGet(ie.getTargetException(), response,

      writer);

      // return true to prevent any further processing

      return true;

      } catch (Exception e) {

      reportTroubleInGet(e, response, writer);

      // return true to prevent any further processing

      return true;

      }

      }

      }

      }


      return false;

      }


      /**

      * getRequestPath a returns request path for web service padded with

      * request.getPathInfo for web services served from /services directory.

      * This is a required to support serving .jws web services from /services

      * URL. See AXIS-843 for more information.

      *

      * @param request HttpServletRequest

      * @return String

      */

      private static String getRequestPath(HttpServletRequest request) {

      return request.getServletPath() + ((request.getPathInfo() != null) ?

      request.getPathInfo() : "");

      }

      }

       



--------------------------------------------------------------------------
      From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
      Sent: Monday, July 23, 2007 12:36 PM
      To: Firas Khasawneh (fkhasawn); axis-user@ws.apache.org
      Subject: Re: measuring Axix 1.4 overhead


      Hi Firas,

      The order of  processing in the case of HTTP is;

      AxisServlet->AxisEngine->HandlerChain->MessageProcessor->Service and come back.

      If you placed the server in a different machine, then your RTT should definitely include the network time so it should be larger than the processing time.

      Thanks,
      -jaliya

        ----- Original Message ----- 
        From: Firas Khasawneh (fkhasawn) 
        To: Jaliya Ekanayake ; axis-dev@ws.apache.org ; axis-user@ws.apache.org 
        Sent: Monday, July 23, 2007 11:27 AM
        Subject: RE: measuring Axix 1.4 overhead


        Hi Jaliya,

        Do you know if response coming back from transport handler after the request is processed in the Axis engine also hits AxisServlet and uses doGet?

        Thanks,
        Firas


------------------------------------------------------------------------
        From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
        Sent: Monday, July 23, 2007 9:42 AM
        To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh (fkhasawn)
        Subject: Re: measuring Axix 1.4 overhead


        Hi Firas,

        Are you trying both axis server and the client in a same machine? If you put the handler in transport section, then what you will measure is the time it takes inside the engine from transport handlers ->service -> transport handlers. One other possibility is to keep track of the time in AxisServlet. Measure the time in AxisServlet before it calls AxisEngine's invoke(..) method and after it is returned and you will get the time for the total invocation.

        Thanks,
        -jaliya
          ----- Original Message ----- 
          From: Firas Khasawneh (fkhasawn) 
          To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
          Sent: Monday, July 23, 2007 6:06 AM
          Subject: RE: measuring Axix 1.4 overhead


          Any help regarding the below please? any suggestions on how to measure the overhead Axis adds?



----------------------------------------------------------------------
          From: Firas Khasawneh (fkhasawn) 
          Sent: Sunday, July 22, 2007 11:50 PM
          To: 'axis-user@ws.apache.org'
          Subject: measuring Axix 1.4 overhead


          Hi all,

          Anybody knows how to measure the overhead Axis 1.4 adds to response time? I created a handler in the requestFlow to  store System.currentTimeMillis in messageContext and another handler in the responseFlow that retrieved this value and subtracts it from System.currentTimeMillis(), when I use these classes in the global conf or transport (server side) I am getting values that correspond to the response time the client is getting so it looks like it is not calculating the Axix overhead on the server side, when I put these handlers in the requestFlow and responseFlow in the service section in server-conf.wsdd it gives differnt time which seem right but I am nti sure if this is the Axix engine overhead? Any suggestions? other ways to do this? please reply back to me or CC me if you are sending to the list since I am not yet a member in this list.

          Regards,
          Firas Khasawneh

RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
To use Axis2 do  I need to change anything in my service code or rebuild
it or can I just replace the library jars?
 
Thanks,
Firas

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Tuesday, July 24, 2007 10:44 AM
To: Firas Khasawneh (fkhasawn)
Cc: axis-dev@ws.apache.org
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,
 
Did you try Axis2 http://ws.apache.org/axis2/ ?
In axis2 processing starts without fully building the soap envelope.
And the performance figures for Axis2 is http://www.wso2.org/library/588
 
Thanks,
-jaliya
 

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: Jaliya Ekanayake <ma...@apache.org>  
	Sent: Tuesday, July 24, 2007 8:48 AM
	Subject: RE: measuring Axix 1.4 overhead

	Hi Jaliya,
	 
	I tested with small size messages and 1 mb messages and there is
big difference, looks like Axis takes long time to process large
messages, but t4-t0 should give the processing time and not the
transport time. Also invoke time t3-t0 should give only Axis engine
overhead.
	 
	Thanks,
	Firas

________________________________

	From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
	Sent: Monday, July 23, 2007 4:34 PM
	To: Firas Khasawneh (fkhasawn)
	Subject: Re: measuring Axix 1.4 overhead
	
	
	Hi Firas,
	 
	Yes, t4-t0 should give you the results.
	However the problem is that you use large message size.
	My guess is that the processing happens before the total
retrieval of the message and hence it include the time it takes to
transfer the message as well.
	Did you try with a small message sizes?
	 
	Thanks,
	-jaliya

		----- Original Message ----- 
		From: Firas Khasawneh (fkhasawn)
<ma...@cisco.com>  
		To: Jaliya Ekanayake <ma...@apache.org>  ;
axis-user@ws.apache.org 
		Sent: Monday, July 23, 2007 3:49 PM
		Subject: RE: measuring Axix 1.4 overhead

		Hi Jaliya,
		 
		I am attaching the AxisServlet.java after adding
benchmark times, if you look at line 791 in the doPost method, the
invoke shoudl calculate the invokation time for the Axis engine without
the network time but for some reason it looks like it is including this
time in the invokation time which does not make any sense. I am testing
with 1 MB size files so I am not sure. below is AxisServlet.java, sorry
for cuttin and pasting it here but I was not sure if this email list
allows attachments:
		 
		/*

		* Copyright 2001-2004 The Apache Software Foundation.

		*

		* Licensed under the Apache License, Version 2.0 (the
"License");

		* you may not use this file except in compliance with
the License.

		* You may obtain a copy of the License at

		*

		* http://www.apache.org/licenses/LICENSE-2.0

		*

		* Unless required by applicable law or agreed to in
writing, software

		* distributed under the License is distributed on an "AS
IS" BASIS,

		* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
express or implied.

		* See the License for the specific language governing
permissions and

		* limitations under the License.

		*/

		

		package org.apache.axis.transport.http;

		

		import java.io.File;

		import java.io.IOException;

		import java.io.PrintWriter;

		import java.lang.reflect.Method;

		import java.lang.reflect.InvocationTargetException;

		import java.net.HttpURLConnection;

		import java.util.ArrayList;

		import java.util.Enumeration;

		import java.util.Iterator;

		

		import javax.servlet.ServletContext;

		import javax.servlet.ServletException;

		import javax.servlet.http.HttpServletRequest;

		import javax.servlet.http.HttpServletResponse;

		import javax.servlet.http.HttpUtils;

		import javax.xml.soap.MimeHeader;

		import javax.xml.soap.MimeHeaders;

		import javax.xml.soap.SOAPException;

		import javax.xml.soap.SOAPMessage;

		

		import org.apache.axis.AxisEngine;

		import org.apache.axis.AxisFault;

		import org.apache.axis.ConfigurationException;

		import org.apache.axis.Constants;

		import org.apache.axis.Handler;

		import org.apache.axis.Message;

		import org.apache.axis.MessageContext;

		import org.apache.axis.SimpleTargetedChain;

		import org.apache.axis.client.Service;

		import org.apache.axis.management.ServiceAdmin;

		import org.apache.axis.components.logger.LogFactory;

		import org.apache.axis.description.OperationDesc;

		import org.apache.axis.description.ServiceDesc;

		import org.apache.axis.handlers.soap.SOAPService;

		import
org.apache.axis.security.servlet.ServletSecurityProvider;

		import org.apache.axis.utils.JavaUtils;

		import org.apache.axis.utils.Messages;

		import org.apache.axis.utils.XMLUtils;

		import org.apache.commons.logging.Log;

		import org.w3c.dom.Element;

		

		/**

		*

		* @author Doug Davis (dug@us.ibm.com)

		* @author Steve Loughran

		* xdoclet tags are not active yet; keep web.xml in sync.

		* To change the location of the services, change
url-pattern in web.xml and

		* set parameter axis.servicesPath in server-config.wsdd.
For more information see

		* <a
href="http://ws.apache.org/axis/java/reference.html">Axis Reference
Guide</a>.

		*

		* @web.servlet name="AxisServlet"
display-name="Apache-Axis Servlet"

		* @web.servlet-mapping
url-pattern="/servlet/AxisServlet"

		* @web.servlet-mapping url-pattern="*.jws"

		* @web.servlet-mapping url-pattern="/services/*"

		*/

		public class AxisServlet extends AxisServletBase {

		protected static Log log =

		LogFactory.getLog(AxisServlet.class.getName());

		

		/**

		* this log is for timing

		*/

		private static Log tlog =

		LogFactory.getLog(Constants.TIME_LOG_CATEGORY);

		

		/**

		* a separate log for exceptions lets users route them

		* differently from general low level debug info

		*/

		private static Log exceptionLog =

		LogFactory.getLog(Constants.EXCEPTION_LOG_CATEGORY);

		

		public static final String INIT_PROPERTY_TRANSPORT_NAME
=

		"transport.name";

		

		public static final String INIT_PROPERTY_USE_SECURITY =

		"use-servlet-security";

		public static final String INIT_PROPERTY_ENABLE_LIST =

		"axis.enableListQuery";

		

		public static final String INIT_PROPERTY_JWS_CLASS_DIR =

		"axis.jws.servletClassDir";

		

		// This will turn off the list of available services

		public static final String
INIT_PROPERTY_DISABLE_SERVICES_LIST =

		"axis.disableServiceList";

		

		// Location of the services as defined by the
servlet-mapping in web.xml

		public static final String INIT_PROPERTY_SERVICES_PATH =

		"axis.servicesPath";

		

		// These have default values.

		private String transportName;

		

		private Handler transport;

		

		private ServletSecurityProvider securityProvider = null;

		

		private String servicesPath;

		

		/**

		* cache of logging debug option; only evaluated at init
time.

		* So no dynamic switching of logging options with this
servlet.

		*/

		private static boolean isDebug = false;

		

		/**

		* Should we enable the "?list" functionality on GETs?
(off by

		* default because deployment information is a potential
security

		* hole)

		*/

		private boolean enableList = false;

		

		/**

		* Should we turn off the list of services when we
receive a GET

		* at the servlet root?

		*/

		private boolean disableServicesList = false;

		

		/**

		* Cached path to JWS output directory

		*/

		private String jwsClassDir = null;

		protected String getJWSClassDir() {return jwsClassDir;

		}

		

		 

		/**

		* create a new servlet instance

		*/

		public AxisServlet() {

		}

		

		/**

		* Initialization method.

		*/

		public void init() throws javax.servlet.ServletException
{

		super.init();

		ServletContext context =
getServletConfig().getServletContext();

		

		isDebug = log.isDebugEnabled();

		if (isDebug) {

		log.debug("In servlet init");

		}

		transportName = getOption(context,

		INIT_PROPERTY_TRANSPORT_NAME,

		HTTPTransport.DEFAULT_TRANSPORT_NAME);

		

		if (JavaUtils.isTrueExplicitly(getOption(context,

		INIT_PROPERTY_USE_SECURITY, null))) {

		securityProvider = new ServletSecurityProvider();

		}

		

		enableList =

		JavaUtils.isTrueExplicitly(getOption(context,

		INIT_PROPERTY_ENABLE_LIST, null));

		

		jwsClassDir = getOption(context,
INIT_PROPERTY_JWS_CLASS_DIR, null);

		

		// Should we list services?

		disableServicesList =
JavaUtils.isTrue(getOption(context,

		INIT_PROPERTY_DISABLE_SERVICES_LIST, "false"));

		

		servicesPath = getOption(context,
INIT_PROPERTY_SERVICES_PATH,

		"/services/");

		

		/**

		* There are DEFINATE problems here if

		* getHomeDir and/or getDefaultJWSClassDir return null

		* (as they could with WebLogic).

		* This needs to be reexamined in the future, but this

		* should fix any NPE's in the mean time.

		*/

		if (jwsClassDir != null) {

		if (getHomeDir() != null) {

		jwsClassDir = getHomeDir() + jwsClassDir;

		}

		} else {

		jwsClassDir = getDefaultJWSClassDir();

		}

		

		initQueryStringHandlers();

		

		// Setup the service admin

		try {

		ServiceAdmin.setEngine(this.getEngine(),
context.getServerInfo());

		} catch (AxisFault af) {

		exceptionLog.info("Exception setting AxisEngine on
ServiceAdmin " +

		af);

		}

		}

		

		 

		/**

		* Process GET requests. This includes handoff of
pseudo-SOAP requests

		*

		* @param request request in

		* @param response request out

		* @throws ServletException

		* @throws IOException

		*/

		public void doGet(HttpServletRequest request,
HttpServletResponse response) throws

		ServletException, IOException {

		if (isDebug) {

		log.debug("Enter: doGet()");

		

		}

		PrintWriter writer = new FilterPrintWriter(response);

		

		try {

		AxisEngine engine = getEngine();

		ServletContext servletContext =

		getServletConfig().getServletContext();

		

		String pathInfo = request.getPathInfo();

		String realpath =
servletContext.getRealPath(request.getServletPath());

		if (realpath == null) {

		realpath = request.getServletPath();

		}

		

		//JWS pages are special; they are the servlet path and
there

		//is no pathinfo...we map the pathinfo to the servlet
path to keep

		//it happy

		boolean isJWSPage =
request.getRequestURI().endsWith(".jws");

		if (isJWSPage) {

		pathInfo = request.getServletPath();

		}

		

		// Try to execute a query string plugin and return upon
success.

		

		if (processQuery(request, response, writer) == true) {

		long reqout = System.currentTimeMillis();

		return;

		}

		

		boolean hasNoPath = (pathInfo == null ||
pathInfo.equals(""));

		if (!disableServicesList) {

		if(hasNoPath) {

		// If the user requested the servlet (i.e.
/axis/servlet/AxisServlet)

		// with no service name, present the user with a list of
deployed

		// services to be helpful

		// Don't do this if has been turned off

		reportAvailableServices(response, writer, request);

		} else if (realpath != null) {

		// We have a pathname, so now we perform WSDL or list
operations

		

		// get message context w/ various properties set

		MessageContext msgContext = createMessageContext(engine,

		request, response);

		

		// NOTE: HttpUtils.getRequestURL has been deprecated.

		// This line SHOULD be:

		// String url = req.getRequestURL().toString()

		// HOWEVER!!!! DON'T REPLACE IT! There's a bug in

		// req.getRequestURL that is not in
HttpUtils.getRequestURL

		// req.getRequestURL returns "localhost" in the remote

		// scenario rather than the actual host name.

		//

		// But more importantly, getRequestURL() is a servlet
2.3

		// API and to support servlet 2.2 (aka WebSphere 4)

		// we need to leave this in for a while longer. tomj
10/14/2004

		//

		String url =
HttpUtils.getRequestURL(request).toString();

		

		msgContext.setProperty(MessageContext.TRANS_URL, url);

		

		// See if we can locate the desired service. If we

		// can't, return a 404 Not Found. Otherwise, just

		// print the placeholder message.

		

		String serviceName;

		if (pathInfo.startsWith("/")) {

		serviceName = pathInfo.substring(1);

		} else {

		serviceName = pathInfo;

		}

		

		SOAPService s = engine.getService(serviceName);

		if (s == null) {

		//no service: report it

		if (isJWSPage) {

		reportCantGetJWSService(request, response, writer);

		} else {

		reportCantGetAxisService(request, response, writer);

		}

		

		} else {

		//print a snippet of service info.

		reportServiceInfo(response, writer, s, serviceName);

		}

		}

		} else {

		// We didn't have a real path in the request, so just

		// print a message informing the user that they reached

		// the servlet.

		

		response.setContentType("text/html; charset=utf-8");

		writer.println("<html><h1>Axis HTTP Servlet</h1>");

		writer.println(Messages.getMessage("reachedServlet00"));

		

		writer.println("<p>" +

		Messages.getMessage("transportName00",

		"<b>" + transportName + "</b>"));

		writer.println("</html>");

		}

		} catch (AxisFault fault) {

		reportTroubleInGet(fault, response, writer);

		} catch (Exception e) {

		reportTroubleInGet(e, response, writer);

		} finally {

		writer.close();

		if (isDebug) {

		log.debug("Exit: doGet()");

		}

		}

		}

		

		/**

		* when we get an exception or an axis fault in a GET, we
handle

		* it almost identically: we go 'something went wrong',
set the response

		* code to 500 and then dump info. But we dump different
info for an axis fault

		* or subclass thereof.

		* @param exception what went wrong

		* @param response current response

		* @param writer open writer to response

		*/

		private void reportTroubleInGet(Throwable exception,

		HttpServletResponse response,

		PrintWriter writer) {

		response.setContentType("text/html; charset=utf-8");

	
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

		writer.println("<h2>" +

		Messages.getMessage("error00") +

		"</h2>");

		writer.println("<p>" +

		Messages.getMessage("somethingWrong00") +

		"</p>");

		if (exception instanceof AxisFault) {

		AxisFault fault = (AxisFault) exception;

		processAxisFault(fault);

		writeFault(writer, fault);

		} else {

		logException(exception);

		writer.println("<pre>Exception - " + exception +
"<br>");

		//dev systems only give fault dumps

		if (isDevelopment()) {

		writer.println(JavaUtils.stackToString(exception));

		}

		writer.println("</pre>");

		}

		}

		

		/**

		* routine called whenever an axis fault is caught; where
they

		* are logged and any other business. The method may
modify the fault

		* in the process

		* @param fault what went wrong.

		*/

		protected void processAxisFault(AxisFault fault) {

		//log the fault

		Element runtimeException = fault.lookupFaultDetail(

		Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

		if (runtimeException != null) {

		exceptionLog.info(Messages.getMessage("axisFault00"),
fault);

		//strip runtime details

		fault.removeFaultDetail(Constants.

		QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

		} else if (exceptionLog.isDebugEnabled()) {

		exceptionLog.debug(Messages.getMessage("axisFault00"),
fault);

		}

		//dev systems only give fault dumps

		if (!isDevelopment()) {

		//strip out the stack trace

	
fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE);

		}

		}

		

		/**

		* log any exception to our output log, at our chosen
level

		* @param e what went wrong

		*/

		protected void logException(Throwable e) {

		exceptionLog.info(Messages.getMessage("exception00"),
e);

		}

		

		/**

		* this method writes a fault out to an HTML stream. This
includes

		* escaping the strings to defend against cross-site
scripting attacks

		* @param writer

		* @param axisFault

		*/

		private void writeFault(PrintWriter writer, AxisFault
axisFault) {

		String localizedMessage =
XMLUtils.xmlEncodeString(axisFault.

		getLocalizedMessage());

		writer.println("<pre>Fault - " + localizedMessage +
"<br>");

		writer.println(axisFault.dumpToString());

		writer.println("</pre>");

		}

		

		/**

		* print a snippet of service info.

		* @param service service

		* @param writer output channel

		* @param serviceName where to put stuff

		*/

		

		protected void reportServiceInfo(HttpServletResponse
response,

		PrintWriter writer, SOAPService service,

		String serviceName) {

		response.setContentType("text/html; charset=utf-8");

		

		writer.println("<h1>"

		+ service.getName()

		+ "</h1>");

		writer.println(

		"<p>" +

		Messages.getMessage("axisService00") +

		"</p>");

		writer.println(

		"<i>" +

		Messages.getMessage("perhaps00") +

		"</i>");

		}

		

		/**

		* report that we have no WSDL

		*

		* This method was moved to the querystring handler
QSWSDLHandler. The

		* method reportNoWSDL in AxisServlet is never called.
Perhaps the method

		* is overwritten in subclasses of AxisServlet so the
method wasn't

		* removed. See the discussion in

		*

		*
http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23845

		*

		* @param res

		* @param writer

		* @param moreDetailCode optional name of a message to
provide more detail

		* @param axisFault optional fault string, for extra info
at debug time only

		*/

		protected void reportNoWSDL(HttpServletResponse res,
PrintWriter writer,

		String moreDetailCode, AxisFault axisFault) {

		}

		

		 

		/**

		* This method lists the available services; it is called
when there is

		* nothing to execute on a GET

		* @param response

		* @param writer

		* @param request

		* @throws ConfigurationException

		* @throws AxisFault

		*/

		protected void
reportAvailableServices(HttpServletResponse response,

		PrintWriter writer,

		HttpServletRequest request) throws

		ConfigurationException, AxisFault {

		AxisEngine engine = getEngine();

		

		response.setContentType("text/html; charset=utf-8");

		writer.println("<h2>And now... Some Services</h2>");

		

		Iterator i;

		try {

		i = engine.getConfig().getDeployedServices();

		} catch (ConfigurationException configException) {

		//turn any internal configuration exceptions back into
axis faults

		//if that is what they are

		if (configException.getContainedException() instanceof
AxisFault) {

		throw (AxisFault)
configException.getContainedException();

		} else {

		throw configException;

		}

		}

		// baseURL may change if <endpointURL> tag is used for

		// custom deployment at a different location

		String defaultBaseURL = getWebappBase(request) +
servicesPath;

		writer.println("<ul>");

		while (i.hasNext()) {

		ServiceDesc sd = (ServiceDesc) i.next();

		StringBuffer sb = new StringBuffer();

		sb.append("<li>");

		String name = sd.getName();

		sb.append(name);

		sb.append(" <a href=\"");

		String endpointURL = sd.getEndpointURL();

		String baseURL = (endpointURL == null) ? defaultBaseURL
:

		endpointURL;

		sb.append(baseURL);

		sb.append(name);

		sb.append("?wsdl\"><i>(wsdl)</i></a></li>");

		writer.println(sb.toString());

		ArrayList operations = sd.getOperations();

		if (!operations.isEmpty()) {

		writer.println("<ul>");

		for (Iterator it = operations.iterator(); it.hasNext();
) {

		OperationDesc desc = (OperationDesc) it.next();

		writer.println("<li>" + desc.getName());

		}

		writer.println("</ul>");

		}

		}

		writer.println("</ul>");

		}

		

		/**

		* generate the error response to indicate that there is
apparently no endpoint there

		* @param request the request that didnt have an edpoint

		* @param response response we are generating

		* @param writer open writer for the request

		*/

		protected void
reportCantGetAxisService(HttpServletRequest request,

		HttpServletResponse response,

		PrintWriter writer) {

		// no such service....

		response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

		response.setContentType("text/html; charset=utf-8");

		writer.println("<h2>" +

		Messages.getMessage("error00") + "</h2>");

		writer.println("<p>" +

		Messages.getMessage("noService06") +

		"</p>");

		}

		

		/**

		* probe for a JWS page and report 'no service' if one is
not found there

		* @param request the request that didnt have an edpoint

		* @param response response we are generating

		* @param writer open writer for the request

		*/

		protected void
reportCantGetJWSService(HttpServletRequest request,

		HttpServletResponse response,

		PrintWriter writer) {

		// first look to see if there is a service

		// requestPath is a work around to support serving .jws
web services

		// from services URL - see AXIS-843 for more information

		String requestPath = request.getServletPath() +
((request.getPathInfo() != null) ?

		request.getPathInfo() : "");

		String realpath = getServletConfig().getServletContext()

		.getRealPath(requestPath);

		log.debug("JWS real path: " + realpath);

		boolean foundJWSFile = (new File(realpath).exists()) &&

		(realpath.endsWith(Constants.

		JWS_DEFAULT_FILE_EXTENSION));

		response.setContentType("text/html; charset=utf-8");

		if (foundJWSFile) {

		response.setStatus(HttpURLConnection.HTTP_OK);

		writer.println(Messages.getMessage("foundJWS00") +
"<p>");

		String url = request.getRequestURI();

		String urltext = Messages.getMessage("foundJWS01");

		writer.println("<a href='" + url + "?wsdl'>" + urltext +
"</a>");

		} else {

		response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

		writer.println(Messages.getMessage("noService06"));

		}

		}

		

		 

		/**

		* Process a POST to the servlet by handing it off to the
Axis Engine.

		* Here is where SOAP messages are received

		* @param req posted request

		* @param res respose

		* @throws ServletException trouble

		* @throws IOException different trouble

		*/

		public void doPost(HttpServletRequest req,
HttpServletResponse res) throws

		ServletException, IOException {

		long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;

		String soapAction = null;

		MessageContext msgContext = null;

		if (isDebug) {

		log.debug("Enter: doPost()");

		}

		t0 = System.currentTimeMillis();

		if (tlog.isDebugEnabled()) {

		t0 = System.currentTimeMillis();

		}

		

		Message responseMsg = null;

		String contentType = null;

		

		try {

		AxisEngine engine = getEngine();

		

		if (engine == null) {

		// !!! should return a SOAP fault...

		ServletException se =

		new ServletException(Messages.getMessage("noEngine00"));

		log.debug("No Engine!", se);

		throw se;

		}

		

		res.setBufferSize(1024 * 8); // provide performance
boost.

		

		/** get message context w/ various properties set

		*/

		msgContext = createMessageContext(engine, req, res);

		

		// ? OK to move this to 'getMessageContext',

		// ? where it would also be picked up for 'doGet()' ?

		if (securityProvider != null) {

		if (isDebug) {

		log.debug("securityProvider:" + securityProvider);

		}

		msgContext.setProperty(MessageContext.SECURITY_PROVIDER,

		securityProvider);

		}

		

		/* Get request message

		*/

		Message requestMsg =

		new Message(req.getInputStream(),

		false,

		req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE),

		req.getHeader(HTTPConstants.

		HEADER_CONTENT_LOCATION));

		// Transfer HTTP headers to MIME headers for request
message.

		MimeHeaders requestMimeHeaders =
requestMsg.getMimeHeaders();

		for (Enumeration e = req.getHeaderNames();
e.hasMoreElements(); ) {

		String headerName = (String) e.nextElement();

		for (Enumeration f = req.getHeaders(headerName);

		f.hasMoreElements(); ) {

		String headerValue = (String) f.nextElement();

		requestMimeHeaders.addHeader(headerName, headerValue);

		}

		}

		

		if (isDebug) {

		log.debug("Request Message:" + requestMsg);

		

		/* Set the request(incoming) message field in the
context */

	
/**********************************************************/

		}

		msgContext.setRequestMessage(requestMsg);

		String url = HttpUtils.getRequestURL(req).toString();

		msgContext.setProperty(MessageContext.TRANS_URL, url);

		// put character encoding of request to message context

		// in order to reuse it during the whole process.

		String requestEncoding;

		try {

		requestEncoding = (String)
requestMsg.getProperty(SOAPMessage.

		CHARACTER_SET_ENCODING);

		if (requestEncoding != null) {

	
msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

		requestEncoding);

		}

		} catch (SOAPException e1) {

		}

		

		try {

		/**

		* Save the SOAPAction header in the MessageContext bag.

		* This will be used to tell the Axis Engine which
service

		* is being invoked. This will save us the trouble of

		* having to parse the Request message - although we will

		* need to double-check later on that the SOAPAction
header

		* does in fact match the URI in the body.

		*/

		// (is this last stmt true??? (I don't think so - Glen))

	
/********************************************************/

		soapAction = getSoapAction(req);

		

		if (soapAction != null) {

		msgContext.setUseSOAPAction(true);

		msgContext.setSOAPActionURI(soapAction);

		}

		

		// Create a Session wrapper for the HTTP session.

		// These can/should be pooled at some point.

		// (Sam is Watching! :-)

		msgContext.setSession(new AxisHttpSession(req));

		t1 = System.currentTimeMillis();

		if (tlog.isDebugEnabled()) {

		t1 = System.currentTimeMillis();

		}

		/* Invoke the Axis engine... */

		/*****************************/

		if (isDebug) {

		log.debug("Invoking Axis Engine.");

		//here we run the message by the engine

		}

		engine.invoke(msgContext);

		if (isDebug) {

		log.debug("Return from Axis Engine.");

		}

		t2 = System.currentTimeMillis();

		if (tlog.isDebugEnabled()) {

		t2 = System.currentTimeMillis();

		}

		responseMsg = msgContext.getResponseMessage();

		

		// We used to throw exceptions on null response
messages.

		// They are actually OK in certain situations
(asynchronous

		// services), so fall through here and return an
ACCEPTED

		// status code below. Might want to install a
configurable

		// error check for this later.

		} catch (AxisFault fault) {

		//log and sanitize

		processAxisFault(fault);

		configureResponseFromAxisFault(res, fault);

		responseMsg = msgContext.getResponseMessage();

		if (responseMsg == null) {

		responseMsg = new Message(fault);

		((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

		getMessage().setMessageContext(msgContext);

		}

		} catch (Exception e) {

		//other exceptions are internal trouble

		responseMsg = msgContext.getResponseMessage();

	
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

		responseMsg = convertExceptionToAxisFault(e,
responseMsg);

		((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

		getMessage().setMessageContext(msgContext);

		} catch (Throwable t) {

		logException(t);

		//other exceptions are internal trouble

		responseMsg = msgContext.getResponseMessage();

	
res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

		responseMsg = new Message(new
AxisFault(t.toString(),t));

		((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

		getMessage().setMessageContext(msgContext);

		}

		} catch (AxisFault fault) {

		processAxisFault(fault);

		configureResponseFromAxisFault(res, fault);

		responseMsg = msgContext.getResponseMessage();

		if (responseMsg == null) {

		responseMsg = new Message(fault);

		((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

		getMessage().setMessageContext(msgContext);

		}

		}

		t3 = System.currentTimeMillis();

		if (tlog.isDebugEnabled()) {

		t3 = System.currentTimeMillis();

		}

		

		/* Send response back along the wire... */

		/***********************************/

		if (responseMsg != null) {

		// Transfer MIME headers to HTTP headers for response
message.

		MimeHeaders responseMimeHeaders =
responseMsg.getMimeHeaders();

		for (Iterator i = responseMimeHeaders.getAllHeaders();
i.hasNext(); ) {

		MimeHeader responseMimeHeader = (MimeHeader) i.next();

		res.addHeader(responseMimeHeader.getName(),

		responseMimeHeader.getValue());

		}

		// synchronize the character encoding of request and
response

		String responseEncoding = (String)
msgContext.getProperty(

		SOAPMessage.CHARACTER_SET_ENCODING);

		if (responseEncoding != null) {

		try {

	
responseMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

		responseEncoding);

		} catch (SOAPException e) {

		}

		}

		//determine content type from message response

		contentType = responseMsg.getContentType(msgContext.

		getSOAPConstants());

		sendResponse(contentType, res, responseMsg);

		} else {

		// No content, so just indicate accepted

		res.setStatus(202);

		}

		

		if (isDebug) {

		log.debug("Response sent.");

		log.debug("Exit: doPost()");

		}

		t4 = System.currentTimeMillis();

		System.out.println("Axis stats: " +

		" pre=" + (t1 - t0) +

		" invoke=" + (t2 - t1) +

		" post=" + (t3 - t2) +

		" send=" + (t4 - t3) +

		" total=" + (t4 - t0));

		if (tlog.isDebugEnabled()) {

		t4 = System.currentTimeMillis();

		tlog.debug("axisServlet.doPost: " + soapAction +

		" pre=" + (t1 - t0) +

		" invoke=" + (t2 - t1) +

		" post=" + (t3 - t2) +

		" send=" + (t4 - t3) +

		" " + msgContext.getTargetService() + "." +

		((msgContext.getOperation() == null) ?

		"" : msgContext.getOperation().getName()));

		}

		

		}

		

		/**

		* Configure the servlet response status code and maybe
other headers

		* from the fault info.

		* @param response response to configure

		* @param fault what went wrong

		*/

		private void
configureResponseFromAxisFault(HttpServletResponse response,

		AxisFault fault) {

		// then get the status code

		// It's been suggested that a lack of SOAPAction

		// should produce some other error code (in the 400s)...

		int status = getHttpServletResponseStatus(fault);

		if (status == HttpServletResponse.SC_UNAUTHORIZED) {

		// unauth access results in authentication request

		// TODO: less generic realm choice?

		response.setHeader("WWW-Authenticate", "Basic
realm=\"AXIS\"");

		}

		response.setStatus(status);

		}

		

		/**

		* turn any Exception into an AxisFault, log it, set the
response

		* status code according to what the specifications say
and

		* return a response message for posting. This will be
the response

		* message passed in if non-null; one generated from the
fault otherwise.

		*

		* @param exception what went wrong

		* @param responseMsg what response we have (if any)

		* @return a response message to send to the user

		*/

		private Message convertExceptionToAxisFault(Exception
exception,

		Message responseMsg) {

		logException(exception);

		if (responseMsg == null) {

		AxisFault fault = AxisFault.makeFault(exception);

		processAxisFault(fault);

		responseMsg = new Message(fault);

		}

		return responseMsg;

		}

		

		/**

		* Extract information from AxisFault and map it to a
HTTP Status code.

		*

		* @param af Axis Fault

		* @return HTTP Status code.

		*/

		protected int getHttpServletResponseStatus(AxisFault af)
{

		// TODO: Should really be doing this with explicit
AxisFault

		// subclasses... --Glen

		return
af.getFaultCode().getLocalPart().startsWith("Server.Unauth")

		? HttpServletResponse.SC_UNAUTHORIZED

		: HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

		// This will raise a 401 for both

		// "Unauthenticated" & "Unauthorized"...

		}

		

		/**

		* write a message to the response, set appropriate
headers for content

		* type..etc.

		* @param res response

		* @param responseMsg message to write

		* @throws AxisFault

		* @throws IOException if the response stream can not be
written to

		*/

		private void sendResponse(String contentType,

		HttpServletResponse res,

		Message responseMsg) throws AxisFault,

		IOException {

		if (responseMsg == null) {

		res.setStatus(HttpServletResponse.SC_NO_CONTENT);

		if (isDebug) {

		log.debug("NO AXIS MESSAGE TO RETURN!");

		//String resp = Messages.getMessage("noData00");

		//res.setContentLength((int) resp.getBytes().length);

		//res.getWriter().print(resp);

		}

		} else {

		if (isDebug) {

		log.debug("Returned Content-Type:" +

		contentType);

		// log.debug("Returned Content-Length:" +

		// responseMsg.getContentLength());

		}

		

		try {

		res.setContentType(contentType);

		

		/* My understand of Content-Length

		* HTTP 1.0

		* -Required for requests, but optional for responses.

		* HTTP 1.1

		* - Either Content-Length or HTTP Chunking is required.

		* Most servlet engines will do chunking if
content-length is not specified.

		*

		*

		*/

		

		//if(clientVersion == HTTPConstants.HEADER_PROTOCOL_V10)
//do chunking if necessary.

		// res.setContentLength(responseMsg.getContentLength());

		

		responseMsg.writeTo(res.getOutputStream());

		} catch (SOAPException e) {

		logException(e);

		}

		}

		

		if (!res.isCommitted()) {

		res.flushBuffer(); // Force it right now.

		}

		}

		

		/**

		* Place the Request message in the MessagContext object
- notice

		* that we just leave it as a 'ServletRequest' object and
let the

		* Message processing routine convert it - we don't do it
since we

		* don't know how it's going to be used - perhaps it
might not

		* even need to be parsed.

		* @return a message context

		*/

		private MessageContext createMessageContext(AxisEngine
engine,

		HttpServletRequest req,

		HttpServletResponse res) {

		MessageContext msgContext = new MessageContext(engine);

		

		String requestPath = getRequestPath(req);

		

		if (isDebug) {

		log.debug("MessageContext:" + msgContext);

		log.debug("HEADER_CONTENT_TYPE:" +

		req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE));

		log.debug("HEADER_CONTENT_LOCATION:" +

		req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION));

		log.debug("Constants.MC_HOME_DIR:" +
String.valueOf(getHomeDir()));

		log.debug("Constants.MC_RELATIVE_PATH:" + requestPath);

		log.debug("HTTPConstants.MC_HTTP_SERVLETLOCATION:" +

		String.valueOf(getWebInfPath()));

		log.debug("HTTPConstants.MC_HTTP_SERVLETPATHINFO:" +

		req.getPathInfo());

		log.debug("HTTPConstants.HEADER_AUTHORIZATION:" +

		req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

		log.debug("Constants.MC_REMOTE_ADDR:" +
req.getRemoteAddr());

		log.debug("configPath:" +
String.valueOf(getWebInfPath()));

		}

		

		/* Set the Transport */

		/*********************/

		msgContext.setTransportName(transportName);

		

		/* Save some HTTP specific info in the bag in case
someone needs it */

	
/********************************************************************/

		msgContext.setProperty(Constants.MC_JWS_CLASSDIR,
jwsClassDir);

		msgContext.setProperty(Constants.MC_HOME_DIR,
getHomeDir());

		msgContext.setProperty(Constants.MC_RELATIVE_PATH,
requestPath);

		msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET,
this);

	
msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, req);

	
msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, res);

	
msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION,

		getWebInfPath());

	
msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO,

		req.getPathInfo());

	
msgContext.setProperty(HTTPConstants.HEADER_AUTHORIZATION,

		req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

		msgContext.setProperty(Constants.MC_REMOTE_ADDR,
req.getRemoteAddr());

		

		// Set up a javax.xml.rpc.server.ServletEndpointContext

		ServletEndpointContextImpl sec = new
ServletEndpointContextImpl();

		

	
msgContext.setProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT, sec);

		/* Save the real path */

		/**********************/

		String realpath = getServletConfig().getServletContext()

		.getRealPath(requestPath);

		

		if (realpath != null) {

		msgContext.setProperty(Constants.MC_REALPATH, realpath);

		}

		

		msgContext.setProperty(Constants.MC_CONFIGPATH,
getWebInfPath());

		

		return msgContext;

		}

		

		/**

		* Extract the SOAPAction header.

		* if SOAPAction is null then we'll we be forced to scan
the body for it.

		* if SOAPAction is "" then use the URL

		* @param req incoming request

		* @return the action

		* @throws AxisFault

		*/

		private String getSoapAction(HttpServletRequest req)
throws AxisFault {

		String soapAction =
req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);

		if (soapAction == null) {

		String contentType =
req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);

		if(contentType != null) {

		int index = contentType.indexOf("action");

		if(index != -1){

		soapAction = contentType.substring(index + 7);

		}

		}

		}

		

		if (isDebug) {

		log.debug("HEADER_SOAP_ACTION:" + soapAction);

		

		/**

		* Technically, if we don't find this header, we should
probably fault.

		* It's required in the SOAP HTTP binding.

		*/

		}

		if (soapAction == null) {

		AxisFault af = new AxisFault("Client.NoSOAPAction",

		Messages.getMessage("noHeader00",

		"SOAPAction"),

		null, null);

		

		exceptionLog.error(Messages.getMessage("genFault00"),
af);

		

		throw af;

		}

		// the SOAP 1.1 spec & WS-I 1.0 says:

		// soapaction = "SOAPAction" ":" [ <"> URI-reference <">
]

		// some implementations leave off the quotes

		// we strip them if they are present

		if (soapAction.startsWith("\"") &&
soapAction.endsWith("\"")

		&& soapAction.length() >= 2) {

		int end = soapAction.length() - 1;

		soapAction = soapAction.substring(1, end);

		}

		

		if (soapAction.length() == 0) {

		soapAction = req.getContextPath(); // Is this right?

		

		}

		return soapAction;

		}

		

		/**

		* Provided to allow overload of default JWSClassDir

		* by derived class.

		* @return directory for JWS files

		*/

		protected String getDefaultJWSClassDir() {

		return (getWebInfPath() == null)

		? null // ??? what is a good FINAL default for WebLogic?

		: getWebInfPath() + File.separator + "jwsClasses";

		}

		

		/**

		* Initialize a Handler for the transport defined in the
Axis server config.

		* This includes optionally filling in query string
handlers.

		*/

		

		public void initQueryStringHandlers() {

		try {

		this.transport =
getEngine().getTransport(this.transportName);

		

		if (this.transport == null) {

		// No transport by this name is defined. Therefore, fill
in default

		// query string handlers.

		

		this.transport = new SimpleTargetedChain();

		

		this.transport.setOption("qs.list",

		"org.apache.axis.transport.http.QSListHandler");

		this.transport.setOption("qs.method",

		"org.apache.axis.transport.http.QSMethodHandler");

		this.transport.setOption("qs.wsdl",

		"org.apache.axis.transport.http.QSWSDLHandler");

		

		return;

		}

		

		else {

		// See if we should use the default query string
handlers.

		// By default, set this to true (for backwards
compatibility).

		

		boolean defaultQueryStrings = true;

		String useDefaults = (String)this.transport.getOption(

		"useDefaultQueryStrings");

		

		if ((useDefaults != null) &&

		useDefaults.toLowerCase().equals("false")) {

		defaultQueryStrings = false;

		}

		

		if (defaultQueryStrings == true) {

		// We should use defaults, so fill them in.

		

		this.transport.setOption("qs.list",

		"org.apache.axis.transport.http.QSListHandler");

		this.transport.setOption("qs.method",

		"org.apache.axis.transport.http.QSMethodHandler");

		this.transport.setOption("qs.wsdl",

		"org.apache.axis.transport.http.QSWSDLHandler");

		}

		}

		}

		

		catch (AxisFault e) {

		// Some sort of problem occurred, let's just make a
default transport.

		

		this.transport = new SimpleTargetedChain();

		

		this.transport.setOption("qs.list",

		"org.apache.axis.transport.http.QSListHandler");

		this.transport.setOption("qs.method",

		"org.apache.axis.transport.http.QSMethodHandler");

		this.transport.setOption("qs.wsdl",

		"org.apache.axis.transport.http.QSWSDLHandler");

		

		return;

		}

		}

		

		/**

		* Attempts to invoke a plugin for the query string
supplied in the URL.

		*

		* @param request the servlet's HttpServletRequest
object.

		* @param response the servlet's HttpServletResponse
object.

		* @param writer the servlet's PrintWriter object.

		*/

		

		private boolean processQuery(HttpServletRequest request,

		HttpServletResponse response,

		PrintWriter writer) throws AxisFault {

		// Attempt to instantiate a plug-in handler class for
the query string

		// handler classes defined in the HTTP transport.

		

		String path = request.getServletPath();

		String queryString = request.getQueryString();

		String serviceName;

		AxisEngine engine = getEngine();

		Iterator i =
this.transport.getOptions().keySet().iterator();

		

		if (queryString == null) {

		return false;

		}

		

		String servletURI = request.getContextPath() + path;

		String reqURI = request.getRequestURI();

		// chop off '/'.

		if (servletURI.length() + 1 < reqURI.length()) {

		serviceName = reqURI.substring(servletURI.length() + 1);

		} else {

		serviceName = "";

		} while (i.hasNext() == true) {

		String queryHandler = (String) i.next();

		

		if (queryHandler.startsWith("qs.") == true) {

		// Only attempt to match the query string with transport

		// parameters prefixed with "qs:".

		

		String handlerName = queryHandler.substring

		(queryHandler.indexOf(".") + 1).

		toLowerCase();

		

		// Determine the name of the plugin to invoke by using
all text

		// in the query string up to the first occurence of &,
=, or the

		// whole string if neither is present.

		

		int length = 0;

		boolean firstParamFound = false;

		

		while (firstParamFound == false && length <
queryString.length()) {

		char ch = queryString.charAt(length++);

		

		if (ch == '&' || ch == '=') {

		firstParamFound = true;

		

		--length;

		}

		}

		

		if (length < queryString.length()) {

		queryString = queryString.substring(0, length);

		}

		

		if (queryString.toLowerCase().equals(handlerName) ==
true) {

		// Query string matches a defined query string handler
name.

		

		// If the defined class name for this query string
handler is blank,

		// just return (the handler is "turned off" in effect).

		

		if (this.transport.getOption(queryHandler).equals("")) {

		return false;

		}

		

		try {

		// Attempt to dynamically load the query string handler

		// and its "invoke" method.

		

		MessageContext msgContext = createMessageContext(engine,

		request, response);

		Class plugin = Class.forName((String)this.transport.

		getOption(queryHandler));

		Method pluginMethod = plugin.getDeclaredMethod("invoke",

		new Class[] {msgContext.getClass()});

		String url =
HttpUtils.getRequestURL(request).toString();

		

		// Place various useful servlet-related objects in

		// the MessageContext object being delivered to the

		// plugin.

		msgContext.setProperty(MessageContext.TRANS_URL, url);

		msgContext.setProperty(HTTPConstants.

		PLUGIN_SERVICE_NAME, serviceName);

		msgContext.setProperty(HTTPConstants.PLUGIN_NAME,

		handlerName);

		msgContext.setProperty(HTTPConstants.

		PLUGIN_IS_DEVELOPMENT,

		new Boolean(isDevelopment()));

		msgContext.setProperty(HTTPConstants.PLUGIN_ENABLE_LIST,

		new Boolean(enableList));

		msgContext.setProperty(HTTPConstants.PLUGIN_ENGINE,

		engine);

		msgContext.setProperty(HTTPConstants.PLUGIN_WRITER,

		writer);

		msgContext.setProperty(HTTPConstants.PLUGIN_LOG, log);

		msgContext.setProperty(HTTPConstants.

		PLUGIN_EXCEPTION_LOG,

		exceptionLog);

		

		// Invoke the plugin.

		

		pluginMethod.invoke(plugin.newInstance(),

		new Object[] {msgContext});

		

		writer.close();

		

		return true;

		} catch (InvocationTargetException ie) {

		reportTroubleInGet(ie.getTargetException(), response,

		writer);

		// return true to prevent any further processing

		return true;

		} catch (Exception e) {

		reportTroubleInGet(e, response, writer);

		// return true to prevent any further processing

		return true;

		}

		}

		}

		}

		

		return false;

		}

		

		/**

		* getRequestPath a returns request path for web service
padded with

		* request.getPathInfo for web services served from
/services directory.

		* This is a required to support serving .jws web
services from /services

		* URL. See AXIS-843 for more information.

		*

		* @param request HttpServletRequest

		* @return String

		*/

		private static String getRequestPath(HttpServletRequest
request) {

		return request.getServletPath() +
((request.getPathInfo() != null) ?

		request.getPathInfo() : "");

		}

		}

		 

________________________________

		From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
		Sent: Monday, July 23, 2007 12:36 PM
		To: Firas Khasawneh (fkhasawn); axis-user@ws.apache.org
		Subject: Re: measuring Axix 1.4 overhead
		
		
		Hi Firas,
		

		The order of  processing in the case of HTTP is;

	
AxisServlet->AxisEngine->HandlerChain->MessageProcessor->Service and
come back.
		 
		If you placed the server in a different machine, then
your RTT should definitely include the network time so it should be
larger than the processing time.
		 
		Thanks,
		-jaliya
		 

			----- Original Message ----- 
			From: Firas Khasawneh (fkhasawn)
<ma...@cisco.com>  
			To: Jaliya Ekanayake <ma...@apache.org>
; axis-dev@ws.apache.org ; axis-user@ws.apache.org 
			Sent: Monday, July 23, 2007 11:27 AM
			Subject: RE: measuring Axix 1.4 overhead

			Hi Jaliya,
			 
			Do you know if response coming back from
transport handler after the request is processed in the Axis engine also
hits AxisServlet and uses doGet?
			 
			Thanks,
			Firas
			
________________________________

			From: Jaliya Ekanayake
[mailto:jnekanayake@gmail.com] 
			Sent: Monday, July 23, 2007 9:42 AM
			To: axis-dev@ws.apache.org;
axis-user@ws.apache.org; Firas Khasawneh (fkhasawn)
			Subject: Re: measuring Axix 1.4 overhead
			
			
			Hi Firas,
			 
			Are you trying both axis server and the client
in a same machine? If you put the handler in transport section, then
what you will measure is the time it takes inside the engine from
transport handlers ->service -> transport handlers. One other
possibility is to keep track of the time in AxisServlet. Measure the
time in AxisServlet before it calls AxisEngine's invoke(..) method and
after it is returned and you will get the time for the total invocation.
			 
			Thanks,
			-jaliya

				----- Original Message ----- 
				From: Firas Khasawneh (fkhasawn)
<ma...@cisco.com>  
				To: axis-user@ws.apache.org ;
axis-dev@ws.apache.org 
				Sent: Monday, July 23, 2007 6:06 AM
				Subject: RE: measuring Axix 1.4 overhead

				Any help regarding the below please? any
suggestions on how to measure the overhead Axis adds?

________________________________

				From: Firas Khasawneh (fkhasawn) 
				Sent: Sunday, July 22, 2007 11:50 PM
				To: 'axis-user@ws.apache.org'
				Subject: measuring Axix 1.4 overhead
				
				
				
				
				Hi all,
				 
				Anybody knows how to measure the
overhead Axis 1.4 adds to response time? I created a handler in the
requestFlow to  store System.currentTimeMillis in messageContext and
another handler in the responseFlow that retrieved this value and
subtracts it from System.currentTimeMillis(), when I use these classes
in the global conf or transport (server side) I am getting values that
correspond to the response time the client is getting so it looks like
it is not calculating the Axix overhead on the server side, when I put
these handlers in the requestFlow and responseFlow in the service
section in server-conf.wsdd it gives differnt time which seem right but
I am nti sure if this is the Axix engine overhead? Any suggestions?
other ways to do this? please reply back to me or CC me if you are
sending to the list since I am not yet a member in this list.
				 
				Regards,
				Firas Khasawneh


Re: measuring Axix 1.4 overhead

Posted by Jaliya Ekanayake <jn...@gmail.com>.
Hi Firas,

Did you try Axis2 http://ws.apache.org/axis2/ ?
In axis2 processing starts without fully building the soap envelope.
And the performance figures for Axis2 is http://www.wso2.org/library/588

Thanks,
-jaliya

  ----- Original Message ----- 
  From: Firas Khasawneh (fkhasawn) 
  To: Jaliya Ekanayake 
  Sent: Tuesday, July 24, 2007 8:48 AM
  Subject: RE: measuring Axix 1.4 overhead


  Hi Jaliya,

  I tested with small size messages and 1 mb messages and there is big difference, looks like Axis takes long time to process large messages, but t4-t0 should give the processing time and not the transport time. Also invoke time t3-t0 should give only Axis engine overhead.

  Thanks,
  Firas



------------------------------------------------------------------------------
  From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
  Sent: Monday, July 23, 2007 4:34 PM
  To: Firas Khasawneh (fkhasawn)
  Subject: Re: measuring Axix 1.4 overhead


  Hi Firas,

  Yes, t4-t0 should give you the results.
  However the problem is that you use large message size.
  My guess is that the processing happens before the total retrieval of the message and hence it include the time it takes to transfer the message as well.
  Did you try with a small message sizes?

  Thanks,
  -jaliya
    ----- Original Message ----- 
    From: Firas Khasawneh (fkhasawn) 
    To: Jaliya Ekanayake ; axis-user@ws.apache.org 
    Sent: Monday, July 23, 2007 3:49 PM
    Subject: RE: measuring Axix 1.4 overhead


    Hi Jaliya,

    I am attaching the AxisServlet.java after adding benchmark times, if you look at line 791 in the doPost method, the invoke shoudl calculate the invokation time for the Axis engine without the network time but for some reason it looks like it is including this time in the invokation time which does not make any sense. I am testing with 1 MB size files so I am not sure. below is AxisServlet.java, sorry for cuttin and pasting it here but I was not sure if this email list allows attachments:

    /*

    * Copyright 2001-2004 The Apache Software Foundation.

    *

    * Licensed under the Apache License, Version 2.0 (the "License");

    * you may not use this file except in compliance with the License.

    * You may obtain a copy of the License at

    *

    * http://www.apache.org/licenses/LICENSE-2.0

    *

    * Unless required by applicable law or agreed to in writing, software

    * distributed under the License is distributed on an "AS IS" BASIS,

    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

    * See the License for the specific language governing permissions and

    * limitations under the License.

    */


    package org.apache.axis.transport.http;


    import java.io.File;

    import java.io.IOException;

    import java.io.PrintWriter;

    import java.lang.reflect.Method;

    import java.lang.reflect.InvocationTargetException;

    import java.net.HttpURLConnection;

    import java.util.ArrayList;

    import java.util.Enumeration;

    import java.util.Iterator;


    import javax.servlet.ServletContext;

    import javax.servlet.ServletException;

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

    import javax.servlet.http.HttpUtils;

    import javax.xml.soap.MimeHeader;

    import javax.xml.soap.MimeHeaders;

    import javax.xml.soap.SOAPException;

    import javax.xml.soap.SOAPMessage;


    import org.apache.axis.AxisEngine;

    import org.apache.axis.AxisFault;

    import org.apache.axis.ConfigurationException;

    import org.apache.axis.Constants;

    import org.apache.axis.Handler;

    import org.apache.axis.Message;

    import org.apache.axis.MessageContext;

    import org.apache.axis.SimpleTargetedChain;

    import org.apache.axis.client.Service;

    import org.apache.axis.management.ServiceAdmin;

    import org.apache.axis.components.logger.LogFactory;

    import org.apache.axis.description.OperationDesc;

    import org.apache.axis.description.ServiceDesc;

    import org.apache.axis.handlers.soap.SOAPService;

    import org.apache.axis.security.servlet.ServletSecurityProvider;

    import org.apache.axis.utils.JavaUtils;

    import org.apache.axis.utils.Messages;

    import org.apache.axis.utils.XMLUtils;

    import org.apache.commons.logging.Log;

    import org.w3c.dom.Element;


    /**

    *

    * @author Doug Davis (dug@us.ibm.com)

    * @author Steve Loughran

    * xdoclet tags are not active yet; keep web.xml in sync.

    * To change the location of the services, change url-pattern in web.xml and

    * set parameter axis.servicesPath in server-config.wsdd. For more information see

    * <a href="http://ws.apache.org/axis/java/reference.html">Axis Reference Guide</a>.

    *

    * @web.servlet name="AxisServlet" display-name="Apache-Axis Servlet"

    * @web.servlet-mapping url-pattern="/servlet/AxisServlet"

    * @web.servlet-mapping url-pattern="*.jws"

    * @web.servlet-mapping url-pattern="/services/*"

    */

    public class AxisServlet extends AxisServletBase {

    protected static Log log =

    LogFactory.getLog(AxisServlet.class.getName());


    /**

    * this log is for timing

    */

    private static Log tlog =

    LogFactory.getLog(Constants.TIME_LOG_CATEGORY);


    /**

    * a separate log for exceptions lets users route them

    * differently from general low level debug info

    */

    private static Log exceptionLog =

    LogFactory.getLog(Constants.EXCEPTION_LOG_CATEGORY);


    public static final String INIT_PROPERTY_TRANSPORT_NAME =

    "transport.name";


    public static final String INIT_PROPERTY_USE_SECURITY =

    "use-servlet-security";

    public static final String INIT_PROPERTY_ENABLE_LIST =

    "axis.enableListQuery";


    public static final String INIT_PROPERTY_JWS_CLASS_DIR =

    "axis.jws.servletClassDir";


    // This will turn off the list of available services

    public static final String INIT_PROPERTY_DISABLE_SERVICES_LIST =

    "axis.disableServiceList";


    // Location of the services as defined by the servlet-mapping in web.xml

    public static final String INIT_PROPERTY_SERVICES_PATH =

    "axis.servicesPath";


    // These have default values.

    private String transportName;


    private Handler transport;


    private ServletSecurityProvider securityProvider = null;


    private String servicesPath;


    /**

    * cache of logging debug option; only evaluated at init time.

    * So no dynamic switching of logging options with this servlet.

    */

    private static boolean isDebug = false;


    /**

    * Should we enable the "?list" functionality on GETs? (off by

    * default because deployment information is a potential security

    * hole)

    */

    private boolean enableList = false;


    /**

    * Should we turn off the list of services when we receive a GET

    * at the servlet root?

    */

    private boolean disableServicesList = false;


    /**

    * Cached path to JWS output directory

    */

    private String jwsClassDir = null;

    protected String getJWSClassDir() {return jwsClassDir;

    }




    /**

    * create a new servlet instance

    */

    public AxisServlet() {

    }


    /**

    * Initialization method.

    */

    public void init() throws javax.servlet.ServletException {

    super.init();

    ServletContext context = getServletConfig().getServletContext();


    isDebug = log.isDebugEnabled();

    if (isDebug) {

    log.debug("In servlet init");

    }

    transportName = getOption(context,

    INIT_PROPERTY_TRANSPORT_NAME,

    HTTPTransport.DEFAULT_TRANSPORT_NAME);


    if (JavaUtils.isTrueExplicitly(getOption(context,

    INIT_PROPERTY_USE_SECURITY, null))) {

    securityProvider = new ServletSecurityProvider();

    }


    enableList =

    JavaUtils.isTrueExplicitly(getOption(context,

    INIT_PROPERTY_ENABLE_LIST, null));


    jwsClassDir = getOption(context, INIT_PROPERTY_JWS_CLASS_DIR, null);


    // Should we list services?

    disableServicesList = JavaUtils.isTrue(getOption(context,

    INIT_PROPERTY_DISABLE_SERVICES_LIST, "false"));


    servicesPath = getOption(context, INIT_PROPERTY_SERVICES_PATH,

    "/services/");


    /**

    * There are DEFINATE problems here if

    * getHomeDir and/or getDefaultJWSClassDir return null

    * (as they could with WebLogic).

    * This needs to be reexamined in the future, but this

    * should fix any NPE's in the mean time.

    */

    if (jwsClassDir != null) {

    if (getHomeDir() != null) {

    jwsClassDir = getHomeDir() + jwsClassDir;

    }

    } else {

    jwsClassDir = getDefaultJWSClassDir();

    }


    initQueryStringHandlers();


    // Setup the service admin

    try {

    ServiceAdmin.setEngine(this.getEngine(), context.getServerInfo());

    } catch (AxisFault af) {

    exceptionLog.info("Exception setting AxisEngine on ServiceAdmin " +

    af);

    }

    }




    /**

    * Process GET requests. This includes handoff of pseudo-SOAP requests

    *

    * @param request request in

    * @param response request out

    * @throws ServletException

    * @throws IOException

    */

    public void doGet(HttpServletRequest request, HttpServletResponse response) throws

    ServletException, IOException {

    if (isDebug) {

    log.debug("Enter: doGet()");


    }

    PrintWriter writer = new FilterPrintWriter(response);


    try {

    AxisEngine engine = getEngine();

    ServletContext servletContext =

    getServletConfig().getServletContext();


    String pathInfo = request.getPathInfo();

    String realpath = servletContext.getRealPath(request.getServletPath());

    if (realpath == null) {

    realpath = request.getServletPath();

    }


    //JWS pages are special; they are the servlet path and there

    //is no pathinfo...we map the pathinfo to the servlet path to keep

    //it happy

    boolean isJWSPage = request.getRequestURI().endsWith(".jws");

    if (isJWSPage) {

    pathInfo = request.getServletPath();

    }


    // Try to execute a query string plugin and return upon success.


    if (processQuery(request, response, writer) == true) {

    long reqout = System.currentTimeMillis();

    return;

    }


    boolean hasNoPath = (pathInfo == null || pathInfo.equals(""));

    if (!disableServicesList) {

    if(hasNoPath) {

    // If the user requested the servlet (i.e. /axis/servlet/AxisServlet)

    // with no service name, present the user with a list of deployed

    // services to be helpful

    // Don't do this if has been turned off

    reportAvailableServices(response, writer, request);

    } else if (realpath != null) {

    // We have a pathname, so now we perform WSDL or list operations


    // get message context w/ various properties set

    MessageContext msgContext = createMessageContext(engine,

    request, response);


    // NOTE: HttpUtils.getRequestURL has been deprecated.

    // This line SHOULD be:

    // String url = req.getRequestURL().toString()

    // HOWEVER!!!! DON'T REPLACE IT! There's a bug in

    // req.getRequestURL that is not in HttpUtils.getRequestURL

    // req.getRequestURL returns "localhost" in the remote

    // scenario rather than the actual host name.

    //

    // But more importantly, getRequestURL() is a servlet 2.3

    // API and to support servlet 2.2 (aka WebSphere 4)

    // we need to leave this in for a while longer. tomj 10/14/2004

    //

    String url = HttpUtils.getRequestURL(request).toString();


    msgContext.setProperty(MessageContext.TRANS_URL, url);


    // See if we can locate the desired service. If we

    // can't, return a 404 Not Found. Otherwise, just

    // print the placeholder message.


    String serviceName;

    if (pathInfo.startsWith("/")) {

    serviceName = pathInfo.substring(1);

    } else {

    serviceName = pathInfo;

    }


    SOAPService s = engine.getService(serviceName);

    if (s == null) {

    //no service: report it

    if (isJWSPage) {

    reportCantGetJWSService(request, response, writer);

    } else {

    reportCantGetAxisService(request, response, writer);

    }


    } else {

    //print a snippet of service info.

    reportServiceInfo(response, writer, s, serviceName);

    }

    }

    } else {

    // We didn't have a real path in the request, so just

    // print a message informing the user that they reached

    // the servlet.


    response.setContentType("text/html; charset=utf-8");

    writer.println("<html><h1>Axis HTTP Servlet</h1>");

    writer.println(Messages.getMessage("reachedServlet00"));


    writer.println("<p>" +

    Messages.getMessage("transportName00",

    "<b>" + transportName + "</b>"));

    writer.println("</html>");

    }

    } catch (AxisFault fault) {

    reportTroubleInGet(fault, response, writer);

    } catch (Exception e) {

    reportTroubleInGet(e, response, writer);

    } finally {

    writer.close();

    if (isDebug) {

    log.debug("Exit: doGet()");

    }

    }

    }


    /**

    * when we get an exception or an axis fault in a GET, we handle

    * it almost identically: we go 'something went wrong', set the response

    * code to 500 and then dump info. But we dump different info for an axis fault

    * or subclass thereof.

    * @param exception what went wrong

    * @param response current response

    * @param writer open writer to response

    */

    private void reportTroubleInGet(Throwable exception,

    HttpServletResponse response,

    PrintWriter writer) {

    response.setContentType("text/html; charset=utf-8");

    response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

    writer.println("<h2>" +

    Messages.getMessage("error00") +

    "</h2>");

    writer.println("<p>" +

    Messages.getMessage("somethingWrong00") +

    "</p>");

    if (exception instanceof AxisFault) {

    AxisFault fault = (AxisFault) exception;

    processAxisFault(fault);

    writeFault(writer, fault);

    } else {

    logException(exception);

    writer.println("<pre>Exception - " + exception + "<br>");

    //dev systems only give fault dumps

    if (isDevelopment()) {

    writer.println(JavaUtils.stackToString(exception));

    }

    writer.println("</pre>");

    }

    }


    /**

    * routine called whenever an axis fault is caught; where they

    * are logged and any other business. The method may modify the fault

    * in the process

    * @param fault what went wrong.

    */

    protected void processAxisFault(AxisFault fault) {

    //log the fault

    Element runtimeException = fault.lookupFaultDetail(

    Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

    if (runtimeException != null) {

    exceptionLog.info(Messages.getMessage("axisFault00"), fault);

    //strip runtime details

    fault.removeFaultDetail(Constants.

    QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

    } else if (exceptionLog.isDebugEnabled()) {

    exceptionLog.debug(Messages.getMessage("axisFault00"), fault);

    }

    //dev systems only give fault dumps

    if (!isDevelopment()) {

    //strip out the stack trace

    fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE);

    }

    }


    /**

    * log any exception to our output log, at our chosen level

    * @param e what went wrong

    */

    protected void logException(Throwable e) {

    exceptionLog.info(Messages.getMessage("exception00"), e);

    }


    /**

    * this method writes a fault out to an HTML stream. This includes

    * escaping the strings to defend against cross-site scripting attacks

    * @param writer

    * @param axisFault

    */

    private void writeFault(PrintWriter writer, AxisFault axisFault) {

    String localizedMessage = XMLUtils.xmlEncodeString(axisFault.

    getLocalizedMessage());

    writer.println("<pre>Fault - " + localizedMessage + "<br>");

    writer.println(axisFault.dumpToString());

    writer.println("</pre>");

    }


    /**

    * print a snippet of service info.

    * @param service service

    * @param writer output channel

    * @param serviceName where to put stuff

    */


    protected void reportServiceInfo(HttpServletResponse response,

    PrintWriter writer, SOAPService service,

    String serviceName) {

    response.setContentType("text/html; charset=utf-8");


    writer.println("<h1>"

    + service.getName()

    + "</h1>");

    writer.println(

    "<p>" +

    Messages.getMessage("axisService00") +

    "</p>");

    writer.println(

    "<i>" +

    Messages.getMessage("perhaps00") +

    "</i>");

    }


    /**

    * report that we have no WSDL

    *

    * This method was moved to the querystring handler QSWSDLHandler. The

    * method reportNoWSDL in AxisServlet is never called. Perhaps the method

    * is overwritten in subclasses of AxisServlet so the method wasn't

    * removed. See the discussion in

    *

    * http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23845

    *

    * @param res

    * @param writer

    * @param moreDetailCode optional name of a message to provide more detail

    * @param axisFault optional fault string, for extra info at debug time only

    */

    protected void reportNoWSDL(HttpServletResponse res, PrintWriter writer,

    String moreDetailCode, AxisFault axisFault) {

    }




    /**

    * This method lists the available services; it is called when there is

    * nothing to execute on a GET

    * @param response

    * @param writer

    * @param request

    * @throws ConfigurationException

    * @throws AxisFault

    */

    protected void reportAvailableServices(HttpServletResponse response,

    PrintWriter writer,

    HttpServletRequest request) throws

    ConfigurationException, AxisFault {

    AxisEngine engine = getEngine();


    response.setContentType("text/html; charset=utf-8");

    writer.println("<h2>And now... Some Services</h2>");


    Iterator i;

    try {

    i = engine.getConfig().getDeployedServices();

    } catch (ConfigurationException configException) {

    //turn any internal configuration exceptions back into axis faults

    //if that is what they are

    if (configException.getContainedException() instanceof AxisFault) {

    throw (AxisFault) configException.getContainedException();

    } else {

    throw configException;

    }

    }

    // baseURL may change if <endpointURL> tag is used for

    // custom deployment at a different location

    String defaultBaseURL = getWebappBase(request) + servicesPath;

    writer.println("<ul>");

    while (i.hasNext()) {

    ServiceDesc sd = (ServiceDesc) i.next();

    StringBuffer sb = new StringBuffer();

    sb.append("<li>");

    String name = sd.getName();

    sb.append(name);

    sb.append(" <a href=\"");

    String endpointURL = sd.getEndpointURL();

    String baseURL = (endpointURL == null) ? defaultBaseURL :

    endpointURL;

    sb.append(baseURL);

    sb.append(name);

    sb.append("?wsdl\"><i>(wsdl)</i></a></li>");

    writer.println(sb.toString());

    ArrayList operations = sd.getOperations();

    if (!operations.isEmpty()) {

    writer.println("<ul>");

    for (Iterator it = operations.iterator(); it.hasNext(); ) {

    OperationDesc desc = (OperationDesc) it.next();

    writer.println("<li>" + desc.getName());

    }

    writer.println("</ul>");

    }

    }

    writer.println("</ul>");

    }


    /**

    * generate the error response to indicate that there is apparently no endpoint there

    * @param request the request that didnt have an edpoint

    * @param response response we are generating

    * @param writer open writer for the request

    */

    protected void reportCantGetAxisService(HttpServletRequest request,

    HttpServletResponse response,

    PrintWriter writer) {

    // no such service....

    response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

    response.setContentType("text/html; charset=utf-8");

    writer.println("<h2>" +

    Messages.getMessage("error00") + "</h2>");

    writer.println("<p>" +

    Messages.getMessage("noService06") +

    "</p>");

    }


    /**

    * probe for a JWS page and report 'no service' if one is not found there

    * @param request the request that didnt have an edpoint

    * @param response response we are generating

    * @param writer open writer for the request

    */

    protected void reportCantGetJWSService(HttpServletRequest request,

    HttpServletResponse response,

    PrintWriter writer) {

    // first look to see if there is a service

    // requestPath is a work around to support serving .jws web services

    // from services URL - see AXIS-843 for more information

    String requestPath = request.getServletPath() + ((request.getPathInfo() != null) ?

    request.getPathInfo() : "");

    String realpath = getServletConfig().getServletContext()

    .getRealPath(requestPath);

    log.debug("JWS real path: " + realpath);

    boolean foundJWSFile = (new File(realpath).exists()) &&

    (realpath.endsWith(Constants.

    JWS_DEFAULT_FILE_EXTENSION));

    response.setContentType("text/html; charset=utf-8");

    if (foundJWSFile) {

    response.setStatus(HttpURLConnection.HTTP_OK);

    writer.println(Messages.getMessage("foundJWS00") + "<p>");

    String url = request.getRequestURI();

    String urltext = Messages.getMessage("foundJWS01");

    writer.println("<a href='" + url + "?wsdl'>" + urltext + "</a>");

    } else {

    response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

    writer.println(Messages.getMessage("noService06"));

    }

    }




    /**

    * Process a POST to the servlet by handing it off to the Axis Engine.

    * Here is where SOAP messages are received

    * @param req posted request

    * @param res respose

    * @throws ServletException trouble

    * @throws IOException different trouble

    */

    public void doPost(HttpServletRequest req, HttpServletResponse res) throws

    ServletException, IOException {

    long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;

    String soapAction = null;

    MessageContext msgContext = null;

    if (isDebug) {

    log.debug("Enter: doPost()");

    }

    t0 = System.currentTimeMillis();

    if (tlog.isDebugEnabled()) {

    t0 = System.currentTimeMillis();

    }


    Message responseMsg = null;

    String contentType = null;


    try {

    AxisEngine engine = getEngine();


    if (engine == null) {

    // !!! should return a SOAP fault...

    ServletException se =

    new ServletException(Messages.getMessage("noEngine00"));

    log.debug("No Engine!", se);

    throw se;

    }


    res.setBufferSize(1024 * 8); // provide performance boost.


    /** get message context w/ various properties set

    */

    msgContext = createMessageContext(engine, req, res);


    // ? OK to move this to 'getMessageContext',

    // ? where it would also be picked up for 'doGet()' ?

    if (securityProvider != null) {

    if (isDebug) {

    log.debug("securityProvider:" + securityProvider);

    }

    msgContext.setProperty(MessageContext.SECURITY_PROVIDER,

    securityProvider);

    }


    /* Get request message

    */

    Message requestMsg =

    new Message(req.getInputStream(),

    false,

    req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE),

    req.getHeader(HTTPConstants.

    HEADER_CONTENT_LOCATION));

    // Transfer HTTP headers to MIME headers for request message.

    MimeHeaders requestMimeHeaders = requestMsg.getMimeHeaders();

    for (Enumeration e = req.getHeaderNames(); e.hasMoreElements(); ) {

    String headerName = (String) e.nextElement();

    for (Enumeration f = req.getHeaders(headerName);

    f.hasMoreElements(); ) {

    String headerValue = (String) f.nextElement();

    requestMimeHeaders.addHeader(headerName, headerValue);

    }

    }


    if (isDebug) {

    log.debug("Request Message:" + requestMsg);


    /* Set the request(incoming) message field in the context */

    /**********************************************************/

    }

    msgContext.setRequestMessage(requestMsg);

    String url = HttpUtils.getRequestURL(req).toString();

    msgContext.setProperty(MessageContext.TRANS_URL, url);

    // put character encoding of request to message context

    // in order to reuse it during the whole process.

    String requestEncoding;

    try {

    requestEncoding = (String) requestMsg.getProperty(SOAPMessage.

    CHARACTER_SET_ENCODING);

    if (requestEncoding != null) {

    msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

    requestEncoding);

    }

    } catch (SOAPException e1) {

    }


    try {

    /**

    * Save the SOAPAction header in the MessageContext bag.

    * This will be used to tell the Axis Engine which service

    * is being invoked. This will save us the trouble of

    * having to parse the Request message - although we will

    * need to double-check later on that the SOAPAction header

    * does in fact match the URI in the body.

    */

    // (is this last stmt true??? (I don't think so - Glen))

    /********************************************************/

    soapAction = getSoapAction(req);


    if (soapAction != null) {

    msgContext.setUseSOAPAction(true);

    msgContext.setSOAPActionURI(soapAction);

    }


    // Create a Session wrapper for the HTTP session.

    // These can/should be pooled at some point.

    // (Sam is Watching! :-)

    msgContext.setSession(new AxisHttpSession(req));

    t1 = System.currentTimeMillis();

    if (tlog.isDebugEnabled()) {

    t1 = System.currentTimeMillis();

    }

    /* Invoke the Axis engine... */

    /*****************************/

    if (isDebug) {

    log.debug("Invoking Axis Engine.");

    //here we run the message by the engine

    }

    engine.invoke(msgContext);

    if (isDebug) {

    log.debug("Return from Axis Engine.");

    }

    t2 = System.currentTimeMillis();

    if (tlog.isDebugEnabled()) {

    t2 = System.currentTimeMillis();

    }

    responseMsg = msgContext.getResponseMessage();


    // We used to throw exceptions on null response messages.

    // They are actually OK in certain situations (asynchronous

    // services), so fall through here and return an ACCEPTED

    // status code below. Might want to install a configurable

    // error check for this later.

    } catch (AxisFault fault) {

    //log and sanitize

    processAxisFault(fault);

    configureResponseFromAxisFault(res, fault);

    responseMsg = msgContext.getResponseMessage();

    if (responseMsg == null) {

    responseMsg = new Message(fault);

    ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

    getMessage().setMessageContext(msgContext);

    }

    } catch (Exception e) {

    //other exceptions are internal trouble

    responseMsg = msgContext.getResponseMessage();

    res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

    responseMsg = convertExceptionToAxisFault(e, responseMsg);

    ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

    getMessage().setMessageContext(msgContext);

    } catch (Throwable t) {

    logException(t);

    //other exceptions are internal trouble

    responseMsg = msgContext.getResponseMessage();

    res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

    responseMsg = new Message(new AxisFault(t.toString(),t));

    ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

    getMessage().setMessageContext(msgContext);

    }

    } catch (AxisFault fault) {

    processAxisFault(fault);

    configureResponseFromAxisFault(res, fault);

    responseMsg = msgContext.getResponseMessage();

    if (responseMsg == null) {

    responseMsg = new Message(fault);

    ((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

    getMessage().setMessageContext(msgContext);

    }

    }

    t3 = System.currentTimeMillis();

    if (tlog.isDebugEnabled()) {

    t3 = System.currentTimeMillis();

    }


    /* Send response back along the wire... */

    /***********************************/

    if (responseMsg != null) {

    // Transfer MIME headers to HTTP headers for response message.

    MimeHeaders responseMimeHeaders = responseMsg.getMimeHeaders();

    for (Iterator i = responseMimeHeaders.getAllHeaders(); i.hasNext(); ) {

    MimeHeader responseMimeHeader = (MimeHeader) i.next();

    res.addHeader(responseMimeHeader.getName(),

    responseMimeHeader.getValue());

    }

    // synchronize the character encoding of request and response

    String responseEncoding = (String) msgContext.getProperty(

    SOAPMessage.CHARACTER_SET_ENCODING);

    if (responseEncoding != null) {

    try {

    responseMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

    responseEncoding);

    } catch (SOAPException e) {

    }

    }

    //determine content type from message response

    contentType = responseMsg.getContentType(msgContext.

    getSOAPConstants());

    sendResponse(contentType, res, responseMsg);

    } else {

    // No content, so just indicate accepted

    res.setStatus(202);

    }


    if (isDebug) {

    log.debug("Response sent.");

    log.debug("Exit: doPost()");

    }

    t4 = System.currentTimeMillis();

    System.out.println("Axis stats: " +

    " pre=" + (t1 - t0) +

    " invoke=" + (t2 - t1) +

    " post=" + (t3 - t2) +

    " send=" + (t4 - t3) +

    " total=" + (t4 - t0));

    if (tlog.isDebugEnabled()) {

    t4 = System.currentTimeMillis();

    tlog.debug("axisServlet.doPost: " + soapAction +

    " pre=" + (t1 - t0) +

    " invoke=" + (t2 - t1) +

    " post=" + (t3 - t2) +

    " send=" + (t4 - t3) +

    " " + msgContext.getTargetService() + "." +

    ((msgContext.getOperation() == null) ?

    "" : msgContext.getOperation().getName()));

    }


    }


    /**

    * Configure the servlet response status code and maybe other headers

    * from the fault info.

    * @param response response to configure

    * @param fault what went wrong

    */

    private void configureResponseFromAxisFault(HttpServletResponse response,

    AxisFault fault) {

    // then get the status code

    // It's been suggested that a lack of SOAPAction

    // should produce some other error code (in the 400s)...

    int status = getHttpServletResponseStatus(fault);

    if (status == HttpServletResponse.SC_UNAUTHORIZED) {

    // unauth access results in authentication request

    // TODO: less generic realm choice?

    response.setHeader("WWW-Authenticate", "Basic realm=\"AXIS\"");

    }

    response.setStatus(status);

    }


    /**

    * turn any Exception into an AxisFault, log it, set the response

    * status code according to what the specifications say and

    * return a response message for posting. This will be the response

    * message passed in if non-null; one generated from the fault otherwise.

    *

    * @param exception what went wrong

    * @param responseMsg what response we have (if any)

    * @return a response message to send to the user

    */

    private Message convertExceptionToAxisFault(Exception exception,

    Message responseMsg) {

    logException(exception);

    if (responseMsg == null) {

    AxisFault fault = AxisFault.makeFault(exception);

    processAxisFault(fault);

    responseMsg = new Message(fault);

    }

    return responseMsg;

    }


    /**

    * Extract information from AxisFault and map it to a HTTP Status code.

    *

    * @param af Axis Fault

    * @return HTTP Status code.

    */

    protected int getHttpServletResponseStatus(AxisFault af) {

    // TODO: Should really be doing this with explicit AxisFault

    // subclasses... --Glen

    return af.getFaultCode().getLocalPart().startsWith("Server.Unauth")

    ? HttpServletResponse.SC_UNAUTHORIZED

    : HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

    // This will raise a 401 for both

    // "Unauthenticated" & "Unauthorized"...

    }


    /**

    * write a message to the response, set appropriate headers for content

    * type..etc.

    * @param res response

    * @param responseMsg message to write

    * @throws AxisFault

    * @throws IOException if the response stream can not be written to

    */

    private void sendResponse(String contentType,

    HttpServletResponse res,

    Message responseMsg) throws AxisFault,

    IOException {

    if (responseMsg == null) {

    res.setStatus(HttpServletResponse.SC_NO_CONTENT);

    if (isDebug) {

    log.debug("NO AXIS MESSAGE TO RETURN!");

    //String resp = Messages.getMessage("noData00");

    //res.setContentLength((int) resp.getBytes().length);

    //res.getWriter().print(resp);

    }

    } else {

    if (isDebug) {

    log.debug("Returned Content-Type:" +

    contentType);

    // log.debug("Returned Content-Length:" +

    // responseMsg.getContentLength());

    }


    try {

    res.setContentType(contentType);


    /* My understand of Content-Length

    * HTTP 1.0

    * -Required for requests, but optional for responses.

    * HTTP 1.1

    * - Either Content-Length or HTTP Chunking is required.

    * Most servlet engines will do chunking if content-length is not specified.

    *

    *

    */


    //if(clientVersion == HTTPConstants.HEADER_PROTOCOL_V10) //do chunking if necessary.

    // res.setContentLength(responseMsg.getContentLength());


    responseMsg.writeTo(res.getOutputStream());

    } catch (SOAPException e) {

    logException(e);

    }

    }


    if (!res.isCommitted()) {

    res.flushBuffer(); // Force it right now.

    }

    }


    /**

    * Place the Request message in the MessagContext object - notice

    * that we just leave it as a 'ServletRequest' object and let the

    * Message processing routine convert it - we don't do it since we

    * don't know how it's going to be used - perhaps it might not

    * even need to be parsed.

    * @return a message context

    */

    private MessageContext createMessageContext(AxisEngine engine,

    HttpServletRequest req,

    HttpServletResponse res) {

    MessageContext msgContext = new MessageContext(engine);


    String requestPath = getRequestPath(req);


    if (isDebug) {

    log.debug("MessageContext:" + msgContext);

    log.debug("HEADER_CONTENT_TYPE:" +

    req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE));

    log.debug("HEADER_CONTENT_LOCATION:" +

    req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION));

    log.debug("Constants.MC_HOME_DIR:" + String.valueOf(getHomeDir()));

    log.debug("Constants.MC_RELATIVE_PATH:" + requestPath);

    log.debug("HTTPConstants.MC_HTTP_SERVLETLOCATION:" +

    String.valueOf(getWebInfPath()));

    log.debug("HTTPConstants.MC_HTTP_SERVLETPATHINFO:" +

    req.getPathInfo());

    log.debug("HTTPConstants.HEADER_AUTHORIZATION:" +

    req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

    log.debug("Constants.MC_REMOTE_ADDR:" + req.getRemoteAddr());

    log.debug("configPath:" + String.valueOf(getWebInfPath()));

    }


    /* Set the Transport */

    /*********************/

    msgContext.setTransportName(transportName);


    /* Save some HTTP specific info in the bag in case someone needs it */

    /********************************************************************/

    msgContext.setProperty(Constants.MC_JWS_CLASSDIR, jwsClassDir);

    msgContext.setProperty(Constants.MC_HOME_DIR, getHomeDir());

    msgContext.setProperty(Constants.MC_RELATIVE_PATH, requestPath);

    msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this);

    msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, req);

    msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, res);

    msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION,

    getWebInfPath());

    msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO,

    req.getPathInfo());

    msgContext.setProperty(HTTPConstants.HEADER_AUTHORIZATION,

    req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

    msgContext.setProperty(Constants.MC_REMOTE_ADDR, req.getRemoteAddr());


    // Set up a javax.xml.rpc.server.ServletEndpointContext

    ServletEndpointContextImpl sec = new ServletEndpointContextImpl();


    msgContext.setProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT, sec);

    /* Save the real path */

    /**********************/

    String realpath = getServletConfig().getServletContext()

    .getRealPath(requestPath);


    if (realpath != null) {

    msgContext.setProperty(Constants.MC_REALPATH, realpath);

    }


    msgContext.setProperty(Constants.MC_CONFIGPATH, getWebInfPath());


    return msgContext;

    }


    /**

    * Extract the SOAPAction header.

    * if SOAPAction is null then we'll we be forced to scan the body for it.

    * if SOAPAction is "" then use the URL

    * @param req incoming request

    * @return the action

    * @throws AxisFault

    */

    private String getSoapAction(HttpServletRequest req) throws AxisFault {

    String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);

    if (soapAction == null) {

    String contentType = req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);

    if(contentType != null) {

    int index = contentType.indexOf("action");

    if(index != -1){

    soapAction = contentType.substring(index + 7);

    }

    }

    }


    if (isDebug) {

    log.debug("HEADER_SOAP_ACTION:" + soapAction);


    /**

    * Technically, if we don't find this header, we should probably fault.

    * It's required in the SOAP HTTP binding.

    */

    }

    if (soapAction == null) {

    AxisFault af = new AxisFault("Client.NoSOAPAction",

    Messages.getMessage("noHeader00",

    "SOAPAction"),

    null, null);


    exceptionLog.error(Messages.getMessage("genFault00"), af);


    throw af;

    }

    // the SOAP 1.1 spec & WS-I 1.0 says:

    // soapaction = "SOAPAction" ":" [ <"> URI-reference <"> ]

    // some implementations leave off the quotes

    // we strip them if they are present

    if (soapAction.startsWith("\"") && soapAction.endsWith("\"")

    && soapAction.length() >= 2) {

    int end = soapAction.length() - 1;

    soapAction = soapAction.substring(1, end);

    }


    if (soapAction.length() == 0) {

    soapAction = req.getContextPath(); // Is this right?


    }

    return soapAction;

    }


    /**

    * Provided to allow overload of default JWSClassDir

    * by derived class.

    * @return directory for JWS files

    */

    protected String getDefaultJWSClassDir() {

    return (getWebInfPath() == null)

    ? null // ??? what is a good FINAL default for WebLogic?

    : getWebInfPath() + File.separator + "jwsClasses";

    }


    /**

    * Initialize a Handler for the transport defined in the Axis server config.

    * This includes optionally filling in query string handlers.

    */


    public void initQueryStringHandlers() {

    try {

    this.transport = getEngine().getTransport(this.transportName);


    if (this.transport == null) {

    // No transport by this name is defined. Therefore, fill in default

    // query string handlers.


    this.transport = new SimpleTargetedChain();


    this.transport.setOption("qs.list",

    "org.apache.axis.transport.http.QSListHandler");

    this.transport.setOption("qs.method",

    "org.apache.axis.transport.http.QSMethodHandler");

    this.transport.setOption("qs.wsdl",

    "org.apache.axis.transport.http.QSWSDLHandler");


    return;

    }


    else {

    // See if we should use the default query string handlers.

    // By default, set this to true (for backwards compatibility).


    boolean defaultQueryStrings = true;

    String useDefaults = (String)this.transport.getOption(

    "useDefaultQueryStrings");


    if ((useDefaults != null) &&

    useDefaults.toLowerCase().equals("false")) {

    defaultQueryStrings = false;

    }


    if (defaultQueryStrings == true) {

    // We should use defaults, so fill them in.


    this.transport.setOption("qs.list",

    "org.apache.axis.transport.http.QSListHandler");

    this.transport.setOption("qs.method",

    "org.apache.axis.transport.http.QSMethodHandler");

    this.transport.setOption("qs.wsdl",

    "org.apache.axis.transport.http.QSWSDLHandler");

    }

    }

    }


    catch (AxisFault e) {

    // Some sort of problem occurred, let's just make a default transport.


    this.transport = new SimpleTargetedChain();


    this.transport.setOption("qs.list",

    "org.apache.axis.transport.http.QSListHandler");

    this.transport.setOption("qs.method",

    "org.apache.axis.transport.http.QSMethodHandler");

    this.transport.setOption("qs.wsdl",

    "org.apache.axis.transport.http.QSWSDLHandler");


    return;

    }

    }


    /**

    * Attempts to invoke a plugin for the query string supplied in the URL.

    *

    * @param request the servlet's HttpServletRequest object.

    * @param response the servlet's HttpServletResponse object.

    * @param writer the servlet's PrintWriter object.

    */


    private boolean processQuery(HttpServletRequest request,

    HttpServletResponse response,

    PrintWriter writer) throws AxisFault {

    // Attempt to instantiate a plug-in handler class for the query string

    // handler classes defined in the HTTP transport.


    String path = request.getServletPath();

    String queryString = request.getQueryString();

    String serviceName;

    AxisEngine engine = getEngine();

    Iterator i = this.transport.getOptions().keySet().iterator();


    if (queryString == null) {

    return false;

    }


    String servletURI = request.getContextPath() + path;

    String reqURI = request.getRequestURI();

    // chop off '/'.

    if (servletURI.length() + 1 < reqURI.length()) {

    serviceName = reqURI.substring(servletURI.length() + 1);

    } else {

    serviceName = "";

    } while (i.hasNext() == true) {

    String queryHandler = (String) i.next();


    if (queryHandler.startsWith("qs.") == true) {

    // Only attempt to match the query string with transport

    // parameters prefixed with "qs:".


    String handlerName = queryHandler.substring

    (queryHandler.indexOf(".") + 1).

    toLowerCase();


    // Determine the name of the plugin to invoke by using all text

    // in the query string up to the first occurence of &, =, or the

    // whole string if neither is present.


    int length = 0;

    boolean firstParamFound = false;


    while (firstParamFound == false && length < queryString.length()) {

    char ch = queryString.charAt(length++);


    if (ch == '&' || ch == '=') {

    firstParamFound = true;


    --length;

    }

    }


    if (length < queryString.length()) {

    queryString = queryString.substring(0, length);

    }


    if (queryString.toLowerCase().equals(handlerName) == true) {

    // Query string matches a defined query string handler name.


    // If the defined class name for this query string handler is blank,

    // just return (the handler is "turned off" in effect).


    if (this.transport.getOption(queryHandler).equals("")) {

    return false;

    }


    try {

    // Attempt to dynamically load the query string handler

    // and its "invoke" method.


    MessageContext msgContext = createMessageContext(engine,

    request, response);

    Class plugin = Class.forName((String)this.transport.

    getOption(queryHandler));

    Method pluginMethod = plugin.getDeclaredMethod("invoke",

    new Class[] {msgContext.getClass()});

    String url = HttpUtils.getRequestURL(request).toString();


    // Place various useful servlet-related objects in

    // the MessageContext object being delivered to the

    // plugin.

    msgContext.setProperty(MessageContext.TRANS_URL, url);

    msgContext.setProperty(HTTPConstants.

    PLUGIN_SERVICE_NAME, serviceName);

    msgContext.setProperty(HTTPConstants.PLUGIN_NAME,

    handlerName);

    msgContext.setProperty(HTTPConstants.

    PLUGIN_IS_DEVELOPMENT,

    new Boolean(isDevelopment()));

    msgContext.setProperty(HTTPConstants.PLUGIN_ENABLE_LIST,

    new Boolean(enableList));

    msgContext.setProperty(HTTPConstants.PLUGIN_ENGINE,

    engine);

    msgContext.setProperty(HTTPConstants.PLUGIN_WRITER,

    writer);

    msgContext.setProperty(HTTPConstants.PLUGIN_LOG, log);

    msgContext.setProperty(HTTPConstants.

    PLUGIN_EXCEPTION_LOG,

    exceptionLog);


    // Invoke the plugin.


    pluginMethod.invoke(plugin.newInstance(),

    new Object[] {msgContext});


    writer.close();


    return true;

    } catch (InvocationTargetException ie) {

    reportTroubleInGet(ie.getTargetException(), response,

    writer);

    // return true to prevent any further processing

    return true;

    } catch (Exception e) {

    reportTroubleInGet(e, response, writer);

    // return true to prevent any further processing

    return true;

    }

    }

    }

    }


    return false;

    }


    /**

    * getRequestPath a returns request path for web service padded with

    * request.getPathInfo for web services served from /services directory.

    * This is a required to support serving .jws web services from /services

    * URL. See AXIS-843 for more information.

    *

    * @param request HttpServletRequest

    * @return String

    */

    private static String getRequestPath(HttpServletRequest request) {

    return request.getServletPath() + ((request.getPathInfo() != null) ?

    request.getPathInfo() : "");

    }

    }

     



----------------------------------------------------------------------------
    From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
    Sent: Monday, July 23, 2007 12:36 PM
    To: Firas Khasawneh (fkhasawn); axis-user@ws.apache.org
    Subject: Re: measuring Axix 1.4 overhead


    Hi Firas,

    The order of  processing in the case of HTTP is;

    AxisServlet->AxisEngine->HandlerChain->MessageProcessor->Service and come back.

    If you placed the server in a different machine, then your RTT should definitely include the network time so it should be larger than the processing time.

    Thanks,
    -jaliya

      ----- Original Message ----- 
      From: Firas Khasawneh (fkhasawn) 
      To: Jaliya Ekanayake ; axis-dev@ws.apache.org ; axis-user@ws.apache.org 
      Sent: Monday, July 23, 2007 11:27 AM
      Subject: RE: measuring Axix 1.4 overhead


      Hi Jaliya,

      Do you know if response coming back from transport handler after the request is processed in the Axis engine also hits AxisServlet and uses doGet?

      Thanks,
      Firas


--------------------------------------------------------------------------
      From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
      Sent: Monday, July 23, 2007 9:42 AM
      To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh (fkhasawn)
      Subject: Re: measuring Axix 1.4 overhead


      Hi Firas,

      Are you trying both axis server and the client in a same machine? If you put the handler in transport section, then what you will measure is the time it takes inside the engine from transport handlers ->service -> transport handlers. One other possibility is to keep track of the time in AxisServlet. Measure the time in AxisServlet before it calls AxisEngine's invoke(..) method and after it is returned and you will get the time for the total invocation.

      Thanks,
      -jaliya
        ----- Original Message ----- 
        From: Firas Khasawneh (fkhasawn) 
        To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
        Sent: Monday, July 23, 2007 6:06 AM
        Subject: RE: measuring Axix 1.4 overhead


        Any help regarding the below please? any suggestions on how to measure the overhead Axis adds?



------------------------------------------------------------------------
        From: Firas Khasawneh (fkhasawn) 
        Sent: Sunday, July 22, 2007 11:50 PM
        To: 'axis-user@ws.apache.org'
        Subject: measuring Axix 1.4 overhead


        Hi all,

        Anybody knows how to measure the overhead Axis 1.4 adds to response time? I created a handler in the requestFlow to  store System.currentTimeMillis in messageContext and another handler in the responseFlow that retrieved this value and subtracts it from System.currentTimeMillis(), when I use these classes in the global conf or transport (server side) I am getting values that correspond to the response time the client is getting so it looks like it is not calculating the Axix overhead on the server side, when I put these handlers in the requestFlow and responseFlow in the service section in server-conf.wsdd it gives differnt time which seem right but I am nti sure if this is the Axix engine overhead? Any suggestions? other ways to do this? please reply back to me or CC me if you are sending to the list since I am not yet a member in this list.

        Regards,
        Firas Khasawneh

RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
I am attaching the AxisServlet.java after adding benchmark times, if you
look at line 791 in the doPost method, the invoke shoudl calculate the
invokation time for the Axis engine without the network time but for
some reason it looks like it is including this time in the invokation
time which does not make any sense. I am testing with 1 MB size files so
I am not sure. below is AxisServlet.java, sorry for cuttin and pasting
it here but I was not sure if this email list allows attachments:
 
/*

* Copyright 2001-2004 The Apache Software Foundation.

*

* Licensed under the Apache License, Version 2.0 (the "License");

* you may not use this file except in compliance with the License.

* You may obtain a copy of the License at

*

* http://www.apache.org/licenses/LICENSE-2.0

*

* Unless required by applicable law or agreed to in writing, software

* distributed under the License is distributed on an "AS IS" BASIS,

* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied.

* See the License for the specific language governing permissions and

* limitations under the License.

*/

package org.apache.axis.transport.http;

import java.io.File;

import java.io.IOException;

import java.io.PrintWriter;

import java.lang.reflect.Method;

import java.lang.reflect.InvocationTargetException;

import java.net.HttpURLConnection;

import java.util.ArrayList;

import java.util.Enumeration;

import java.util.Iterator;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import javax.servlet.http.HttpUtils;

import javax.xml.soap.MimeHeader;

import javax.xml.soap.MimeHeaders;

import javax.xml.soap.SOAPException;

import javax.xml.soap.SOAPMessage;

import org.apache.axis.AxisEngine;

import org.apache.axis.AxisFault;

import org.apache.axis.ConfigurationException;

import org.apache.axis.Constants;

import org.apache.axis.Handler;

import org.apache.axis.Message;

import org.apache.axis.MessageContext;

import org.apache.axis.SimpleTargetedChain;

import org.apache.axis.client.Service;

import org.apache.axis.management.ServiceAdmin;

import org.apache.axis.components.logger.LogFactory;

import org.apache.axis.description.OperationDesc;

import org.apache.axis.description.ServiceDesc;

import org.apache.axis.handlers.soap.SOAPService;

import org.apache.axis.security.servlet.ServletSecurityProvider;

import org.apache.axis.utils.JavaUtils;

import org.apache.axis.utils.Messages;

import org.apache.axis.utils.XMLUtils;

import org.apache.commons.logging.Log;

import org.w3c.dom.Element;

/**

*

* @author Doug Davis (dug@us.ibm.com)

* @author Steve Loughran

* xdoclet tags are not active yet; keep web.xml in sync.

* To change the location of the services, change url-pattern in web.xml
and

* set parameter axis.servicesPath in server-config.wsdd. For more
information see

* <a href="http://ws.apache.org/axis/java/reference.html">Axis Reference
Guide</a>.

*

* @web.servlet name="AxisServlet" display-name="Apache-Axis Servlet"

* @web.servlet-mapping url-pattern="/servlet/AxisServlet"

* @web.servlet-mapping url-pattern="*.jws"

* @web.servlet-mapping url-pattern="/services/*"

*/

public class AxisServlet extends AxisServletBase {

protected static Log log =

LogFactory.getLog(AxisServlet.class.getName());

/**

* this log is for timing

*/

private static Log tlog =

LogFactory.getLog(Constants.TIME_LOG_CATEGORY);

/**

* a separate log for exceptions lets users route them

* differently from general low level debug info

*/

private static Log exceptionLog =

LogFactory.getLog(Constants.EXCEPTION_LOG_CATEGORY);

public static final String INIT_PROPERTY_TRANSPORT_NAME =

"transport.name";

public static final String INIT_PROPERTY_USE_SECURITY =

"use-servlet-security";

public static final String INIT_PROPERTY_ENABLE_LIST =

"axis.enableListQuery";

public static final String INIT_PROPERTY_JWS_CLASS_DIR =

"axis.jws.servletClassDir";

// This will turn off the list of available services

public static final String INIT_PROPERTY_DISABLE_SERVICES_LIST =

"axis.disableServiceList";

// Location of the services as defined by the servlet-mapping in web.xml

public static final String INIT_PROPERTY_SERVICES_PATH =

"axis.servicesPath";

// These have default values.

private String transportName;

private Handler transport;

private ServletSecurityProvider securityProvider = null;

private String servicesPath;

/**

* cache of logging debug option; only evaluated at init time.

* So no dynamic switching of logging options with this servlet.

*/

private static boolean isDebug = false;

/**

* Should we enable the "?list" functionality on GETs? (off by

* default because deployment information is a potential security

* hole)

*/

private boolean enableList = false;

/**

* Should we turn off the list of services when we receive a GET

* at the servlet root?

*/

private boolean disableServicesList = false;

/**

* Cached path to JWS output directory

*/

private String jwsClassDir = null;

protected String getJWSClassDir() {return jwsClassDir;

}

 

/**

* create a new servlet instance

*/

public AxisServlet() {

}

/**

* Initialization method.

*/

public void init() throws javax.servlet.ServletException {

super.init();

ServletContext context = getServletConfig().getServletContext();

isDebug = log.isDebugEnabled();

if (isDebug) {

log.debug("In servlet init");

}

transportName = getOption(context,

INIT_PROPERTY_TRANSPORT_NAME,

HTTPTransport.DEFAULT_TRANSPORT_NAME);

if (JavaUtils.isTrueExplicitly(getOption(context,

INIT_PROPERTY_USE_SECURITY, null))) {

securityProvider = new ServletSecurityProvider();

}

enableList =

JavaUtils.isTrueExplicitly(getOption(context,

INIT_PROPERTY_ENABLE_LIST, null));

jwsClassDir = getOption(context, INIT_PROPERTY_JWS_CLASS_DIR, null);

// Should we list services?

disableServicesList = JavaUtils.isTrue(getOption(context,

INIT_PROPERTY_DISABLE_SERVICES_LIST, "false"));

servicesPath = getOption(context, INIT_PROPERTY_SERVICES_PATH,

"/services/");

/**

* There are DEFINATE problems here if

* getHomeDir and/or getDefaultJWSClassDir return null

* (as they could with WebLogic).

* This needs to be reexamined in the future, but this

* should fix any NPE's in the mean time.

*/

if (jwsClassDir != null) {

if (getHomeDir() != null) {

jwsClassDir = getHomeDir() + jwsClassDir;

}

} else {

jwsClassDir = getDefaultJWSClassDir();

}

initQueryStringHandlers();

// Setup the service admin

try {

ServiceAdmin.setEngine(this.getEngine(), context.getServerInfo());

} catch (AxisFault af) {

exceptionLog.info("Exception setting AxisEngine on ServiceAdmin " +

af);

}

}

 

/**

* Process GET requests. This includes handoff of pseudo-SOAP requests

*

* @param request request in

* @param response request out

* @throws ServletException

* @throws IOException

*/

public void doGet(HttpServletRequest request, HttpServletResponse
response) throws

ServletException, IOException {

if (isDebug) {

log.debug("Enter: doGet()");

}

PrintWriter writer = new FilterPrintWriter(response);

try {

AxisEngine engine = getEngine();

ServletContext servletContext =

getServletConfig().getServletContext();

String pathInfo = request.getPathInfo();

String realpath = servletContext.getRealPath(request.getServletPath());

if (realpath == null) {

realpath = request.getServletPath();

}

//JWS pages are special; they are the servlet path and there

//is no pathinfo...we map the pathinfo to the servlet path to keep

//it happy

boolean isJWSPage = request.getRequestURI().endsWith(".jws");

if (isJWSPage) {

pathInfo = request.getServletPath();

}

// Try to execute a query string plugin and return upon success.

if (processQuery(request, response, writer) == true) {

long reqout = System.currentTimeMillis();

return;

}

boolean hasNoPath = (pathInfo == null || pathInfo.equals(""));

if (!disableServicesList) {

if(hasNoPath) {

// If the user requested the servlet (i.e. /axis/servlet/AxisServlet)

// with no service name, present the user with a list of deployed

// services to be helpful

// Don't do this if has been turned off

reportAvailableServices(response, writer, request);

} else if (realpath != null) {

// We have a pathname, so now we perform WSDL or list operations

// get message context w/ various properties set

MessageContext msgContext = createMessageContext(engine,

request, response);

// NOTE: HttpUtils.getRequestURL has been deprecated.

// This line SHOULD be:

// String url = req.getRequestURL().toString()

// HOWEVER!!!! DON'T REPLACE IT! There's a bug in

// req.getRequestURL that is not in HttpUtils.getRequestURL

// req.getRequestURL returns "localhost" in the remote

// scenario rather than the actual host name.

//

// But more importantly, getRequestURL() is a servlet 2.3

// API and to support servlet 2.2 (aka WebSphere 4)

// we need to leave this in for a while longer. tomj 10/14/2004

//

String url = HttpUtils.getRequestURL(request).toString();

msgContext.setProperty(MessageContext.TRANS_URL, url);

// See if we can locate the desired service. If we

// can't, return a 404 Not Found. Otherwise, just

// print the placeholder message.

String serviceName;

if (pathInfo.startsWith("/")) {

serviceName = pathInfo.substring(1);

} else {

serviceName = pathInfo;

}

SOAPService s = engine.getService(serviceName);

if (s == null) {

//no service: report it

if (isJWSPage) {

reportCantGetJWSService(request, response, writer);

} else {

reportCantGetAxisService(request, response, writer);

}

} else {

//print a snippet of service info.

reportServiceInfo(response, writer, s, serviceName);

}

}

} else {

// We didn't have a real path in the request, so just

// print a message informing the user that they reached

// the servlet.

response.setContentType("text/html; charset=utf-8");

writer.println("<html><h1>Axis HTTP Servlet</h1>");

writer.println(Messages.getMessage("reachedServlet00"));

writer.println("<p>" +

Messages.getMessage("transportName00",

"<b>" + transportName + "</b>"));

writer.println("</html>");

}

} catch (AxisFault fault) {

reportTroubleInGet(fault, response, writer);

} catch (Exception e) {

reportTroubleInGet(e, response, writer);

} finally {

writer.close();

if (isDebug) {

log.debug("Exit: doGet()");

}

}

}

/**

* when we get an exception or an axis fault in a GET, we handle

* it almost identically: we go 'something went wrong', set the response

* code to 500 and then dump info. But we dump different info for an axis
fault

* or subclass thereof.

* @param exception what went wrong

* @param response current response

* @param writer open writer to response

*/

private void reportTroubleInGet(Throwable exception,

HttpServletResponse response,

PrintWriter writer) {

response.setContentType("text/html; charset=utf-8");

response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

writer.println("<h2>" +

Messages.getMessage("error00") +

"</h2>");

writer.println("<p>" +

Messages.getMessage("somethingWrong00") +

"</p>");

if (exception instanceof AxisFault) {

AxisFault fault = (AxisFault) exception;

processAxisFault(fault);

writeFault(writer, fault);

} else {

logException(exception);

writer.println("<pre>Exception - " + exception + "<br>");

//dev systems only give fault dumps

if (isDevelopment()) {

writer.println(JavaUtils.stackToString(exception));

}

writer.println("</pre>");

}

}

/**

* routine called whenever an axis fault is caught; where they

* are logged and any other business. The method may modify the fault

* in the process

* @param fault what went wrong.

*/

protected void processAxisFault(AxisFault fault) {

//log the fault

Element runtimeException = fault.lookupFaultDetail(

Constants.QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

if (runtimeException != null) {

exceptionLog.info(Messages.getMessage("axisFault00"), fault);

//strip runtime details

fault.removeFaultDetail(Constants.

QNAME_FAULTDETAIL_RUNTIMEEXCEPTION);

} else if (exceptionLog.isDebugEnabled()) {

exceptionLog.debug(Messages.getMessage("axisFault00"), fault);

}

//dev systems only give fault dumps

if (!isDevelopment()) {

//strip out the stack trace

fault.removeFaultDetail(Constants.QNAME_FAULTDETAIL_STACKTRACE);

}

}

/**

* log any exception to our output log, at our chosen level

* @param e what went wrong

*/

protected void logException(Throwable e) {

exceptionLog.info(Messages.getMessage("exception00"), e);

}

/**

* this method writes a fault out to an HTML stream. This includes

* escaping the strings to defend against cross-site scripting attacks

* @param writer

* @param axisFault

*/

private void writeFault(PrintWriter writer, AxisFault axisFault) {

String localizedMessage = XMLUtils.xmlEncodeString(axisFault.

getLocalizedMessage());

writer.println("<pre>Fault - " + localizedMessage + "<br>");

writer.println(axisFault.dumpToString());

writer.println("</pre>");

}

/**

* print a snippet of service info.

* @param service service

* @param writer output channel

* @param serviceName where to put stuff

*/

protected void reportServiceInfo(HttpServletResponse response,

PrintWriter writer, SOAPService service,

String serviceName) {

response.setContentType("text/html; charset=utf-8");

writer.println("<h1>"

+ service.getName()

+ "</h1>");

writer.println(

"<p>" +

Messages.getMessage("axisService00") +

"</p>");

writer.println(

"<i>" +

Messages.getMessage("perhaps00") +

"</i>");

}

/**

* report that we have no WSDL

*

* This method was moved to the querystring handler QSWSDLHandler. The

* method reportNoWSDL in AxisServlet is never called. Perhaps the method

* is overwritten in subclasses of AxisServlet so the method wasn't

* removed. See the discussion in

*

* http://nagoya.apache.org/bugzilla/show_bug.cgi?id=23845

*

* @param res

* @param writer

* @param moreDetailCode optional name of a message to provide more
detail

* @param axisFault optional fault string, for extra info at debug time
only

*/

protected void reportNoWSDL(HttpServletResponse res, PrintWriter writer,

String moreDetailCode, AxisFault axisFault) {

}

 

/**

* This method lists the available services; it is called when there is

* nothing to execute on a GET

* @param response

* @param writer

* @param request

* @throws ConfigurationException

* @throws AxisFault

*/

protected void reportAvailableServices(HttpServletResponse response,

PrintWriter writer,

HttpServletRequest request) throws

ConfigurationException, AxisFault {

AxisEngine engine = getEngine();

response.setContentType("text/html; charset=utf-8");

writer.println("<h2>And now... Some Services</h2>");

Iterator i;

try {

i = engine.getConfig().getDeployedServices();

} catch (ConfigurationException configException) {

//turn any internal configuration exceptions back into axis faults

//if that is what they are

if (configException.getContainedException() instanceof AxisFault) {

throw (AxisFault) configException.getContainedException();

} else {

throw configException;

}

}

// baseURL may change if <endpointURL> tag is used for

// custom deployment at a different location

String defaultBaseURL = getWebappBase(request) + servicesPath;

writer.println("<ul>");

while (i.hasNext()) {

ServiceDesc sd = (ServiceDesc) i.next();

StringBuffer sb = new StringBuffer();

sb.append("<li>");

String name = sd.getName();

sb.append(name);

sb.append(" <a href=\"");

String endpointURL = sd.getEndpointURL();

String baseURL = (endpointURL == null) ? defaultBaseURL :

endpointURL;

sb.append(baseURL);

sb.append(name);

sb.append("?wsdl\"><i>(wsdl)</i></a></li>");

writer.println(sb.toString());

ArrayList operations = sd.getOperations();

if (!operations.isEmpty()) {

writer.println("<ul>");

for (Iterator it = operations.iterator(); it.hasNext(); ) {

OperationDesc desc = (OperationDesc) it.next();

writer.println("<li>" + desc.getName());

}

writer.println("</ul>");

}

}

writer.println("</ul>");

}

/**

* generate the error response to indicate that there is apparently no
endpoint there

* @param request the request that didnt have an edpoint

* @param response response we are generating

* @param writer open writer for the request

*/

protected void reportCantGetAxisService(HttpServletRequest request,

HttpServletResponse response,

PrintWriter writer) {

// no such service....

response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

response.setContentType("text/html; charset=utf-8");

writer.println("<h2>" +

Messages.getMessage("error00") + "</h2>");

writer.println("<p>" +

Messages.getMessage("noService06") +

"</p>");

}

/**

* probe for a JWS page and report 'no service' if one is not found there

* @param request the request that didnt have an edpoint

* @param response response we are generating

* @param writer open writer for the request

*/

protected void reportCantGetJWSService(HttpServletRequest request,

HttpServletResponse response,

PrintWriter writer) {

// first look to see if there is a service

// requestPath is a work around to support serving .jws web services

// from services URL - see AXIS-843 for more information

String requestPath = request.getServletPath() + ((request.getPathInfo()
!= null) ?

request.getPathInfo() : "");

String realpath = getServletConfig().getServletContext()

.getRealPath(requestPath);

log.debug("JWS real path: " + realpath);

boolean foundJWSFile = (new File(realpath).exists()) &&

(realpath.endsWith(Constants.

JWS_DEFAULT_FILE_EXTENSION));

response.setContentType("text/html; charset=utf-8");

if (foundJWSFile) {

response.setStatus(HttpURLConnection.HTTP_OK);

writer.println(Messages.getMessage("foundJWS00") + "<p>");

String url = request.getRequestURI();

String urltext = Messages.getMessage("foundJWS01");

writer.println("<a href='" + url + "?wsdl'>" + urltext + "</a>");

} else {

response.setStatus(HttpURLConnection.HTTP_NOT_FOUND);

writer.println(Messages.getMessage("noService06"));

}

}

 

/**

* Process a POST to the servlet by handing it off to the Axis Engine.

* Here is where SOAP messages are received

* @param req posted request

* @param res respose

* @throws ServletException trouble

* @throws IOException different trouble

*/

public void doPost(HttpServletRequest req, HttpServletResponse res)
throws

ServletException, IOException {

long t0 = 0, t1 = 0, t2 = 0, t3 = 0, t4 = 0;

String soapAction = null;

MessageContext msgContext = null;

if (isDebug) {

log.debug("Enter: doPost()");

}

t0 = System.currentTimeMillis();

if (tlog.isDebugEnabled()) {

t0 = System.currentTimeMillis();

}

Message responseMsg = null;

String contentType = null;

try {

AxisEngine engine = getEngine();

if (engine == null) {

// !!! should return a SOAP fault...

ServletException se =

new ServletException(Messages.getMessage("noEngine00"));

log.debug("No Engine!", se);

throw se;

}

res.setBufferSize(1024 * 8); // provide performance boost.

/** get message context w/ various properties set

*/

msgContext = createMessageContext(engine, req, res);

// ? OK to move this to 'getMessageContext',

// ? where it would also be picked up for 'doGet()' ?

if (securityProvider != null) {

if (isDebug) {

log.debug("securityProvider:" + securityProvider);

}

msgContext.setProperty(MessageContext.SECURITY_PROVIDER,

securityProvider);

}

/* Get request message

*/

Message requestMsg =

new Message(req.getInputStream(),

false,

req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE),

req.getHeader(HTTPConstants.

HEADER_CONTENT_LOCATION));

// Transfer HTTP headers to MIME headers for request message.

MimeHeaders requestMimeHeaders = requestMsg.getMimeHeaders();

for (Enumeration e = req.getHeaderNames(); e.hasMoreElements(); ) {

String headerName = (String) e.nextElement();

for (Enumeration f = req.getHeaders(headerName);

f.hasMoreElements(); ) {

String headerValue = (String) f.nextElement();

requestMimeHeaders.addHeader(headerName, headerValue);

}

}

if (isDebug) {

log.debug("Request Message:" + requestMsg);

/* Set the request(incoming) message field in the context */

/**********************************************************/

}

msgContext.setRequestMessage(requestMsg);

String url = HttpUtils.getRequestURL(req).toString();

msgContext.setProperty(MessageContext.TRANS_URL, url);

// put character encoding of request to message context

// in order to reuse it during the whole process.

String requestEncoding;

try {

requestEncoding = (String) requestMsg.getProperty(SOAPMessage.

CHARACTER_SET_ENCODING);

if (requestEncoding != null) {

msgContext.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

requestEncoding);

}

} catch (SOAPException e1) {

}

try {

/**

* Save the SOAPAction header in the MessageContext bag.

* This will be used to tell the Axis Engine which service

* is being invoked. This will save us the trouble of

* having to parse the Request message - although we will

* need to double-check later on that the SOAPAction header

* does in fact match the URI in the body.

*/

// (is this last stmt true??? (I don't think so - Glen))

/********************************************************/

soapAction = getSoapAction(req);

if (soapAction != null) {

msgContext.setUseSOAPAction(true);

msgContext.setSOAPActionURI(soapAction);

}

// Create a Session wrapper for the HTTP session.

// These can/should be pooled at some point.

// (Sam is Watching! :-)

msgContext.setSession(new AxisHttpSession(req));

t1 = System.currentTimeMillis();

if (tlog.isDebugEnabled()) {

t1 = System.currentTimeMillis();

}

/* Invoke the Axis engine... */

/*****************************/

if (isDebug) {

log.debug("Invoking Axis Engine.");

//here we run the message by the engine

}

engine.invoke(msgContext);

if (isDebug) {

log.debug("Return from Axis Engine.");

}

t2 = System.currentTimeMillis();

if (tlog.isDebugEnabled()) {

t2 = System.currentTimeMillis();

}

responseMsg = msgContext.getResponseMessage();

// We used to throw exceptions on null response messages.

// They are actually OK in certain situations (asynchronous

// services), so fall through here and return an ACCEPTED

// status code below. Might want to install a configurable

// error check for this later.

} catch (AxisFault fault) {

//log and sanitize

processAxisFault(fault);

configureResponseFromAxisFault(res, fault);

responseMsg = msgContext.getResponseMessage();

if (responseMsg == null) {

responseMsg = new Message(fault);

((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

getMessage().setMessageContext(msgContext);

}

} catch (Exception e) {

//other exceptions are internal trouble

responseMsg = msgContext.getResponseMessage();

res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

responseMsg = convertExceptionToAxisFault(e, responseMsg);

((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

getMessage().setMessageContext(msgContext);

} catch (Throwable t) {

logException(t);

//other exceptions are internal trouble

responseMsg = msgContext.getResponseMessage();

res.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);

responseMsg = new Message(new AxisFault(t.toString(),t));

((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

getMessage().setMessageContext(msgContext);

}

} catch (AxisFault fault) {

processAxisFault(fault);

configureResponseFromAxisFault(res, fault);

responseMsg = msgContext.getResponseMessage();

if (responseMsg == null) {

responseMsg = new Message(fault);

((org.apache.axis.SOAPPart) responseMsg.getSOAPPart()).

getMessage().setMessageContext(msgContext);

}

}

t3 = System.currentTimeMillis();

if (tlog.isDebugEnabled()) {

t3 = System.currentTimeMillis();

}

/* Send response back along the wire... */

/***********************************/

if (responseMsg != null) {

// Transfer MIME headers to HTTP headers for response message.

MimeHeaders responseMimeHeaders = responseMsg.getMimeHeaders();

for (Iterator i = responseMimeHeaders.getAllHeaders(); i.hasNext(); ) {

MimeHeader responseMimeHeader = (MimeHeader) i.next();

res.addHeader(responseMimeHeader.getName(),

responseMimeHeader.getValue());

}

// synchronize the character encoding of request and response

String responseEncoding = (String) msgContext.getProperty(

SOAPMessage.CHARACTER_SET_ENCODING);

if (responseEncoding != null) {

try {

responseMsg.setProperty(SOAPMessage.CHARACTER_SET_ENCODING,

responseEncoding);

} catch (SOAPException e) {

}

}

//determine content type from message response

contentType = responseMsg.getContentType(msgContext.

getSOAPConstants());

sendResponse(contentType, res, responseMsg);

} else {

// No content, so just indicate accepted

res.setStatus(202);

}

if (isDebug) {

log.debug("Response sent.");

log.debug("Exit: doPost()");

}

t4 = System.currentTimeMillis();

System.out.println("Axis stats: " +

" pre=" + (t1 - t0) +

" invoke=" + (t2 - t1) +

" post=" + (t3 - t2) +

" send=" + (t4 - t3) +

" total=" + (t4 - t0));

if (tlog.isDebugEnabled()) {

t4 = System.currentTimeMillis();

tlog.debug("axisServlet.doPost: " + soapAction +

" pre=" + (t1 - t0) +

" invoke=" + (t2 - t1) +

" post=" + (t3 - t2) +

" send=" + (t4 - t3) +

" " + msgContext.getTargetService() + "." +

((msgContext.getOperation() == null) ?

"" : msgContext.getOperation().getName()));

}

}

/**

* Configure the servlet response status code and maybe other headers

* from the fault info.

* @param response response to configure

* @param fault what went wrong

*/

private void configureResponseFromAxisFault(HttpServletResponse
response,

AxisFault fault) {

// then get the status code

// It's been suggested that a lack of SOAPAction

// should produce some other error code (in the 400s)...

int status = getHttpServletResponseStatus(fault);

if (status == HttpServletResponse.SC_UNAUTHORIZED) {

// unauth access results in authentication request

// TODO: less generic realm choice?

response.setHeader("WWW-Authenticate", "Basic realm=\"AXIS\"");

}

response.setStatus(status);

}

/**

* turn any Exception into an AxisFault, log it, set the response

* status code according to what the specifications say and

* return a response message for posting. This will be the response

* message passed in if non-null; one generated from the fault otherwise.

*

* @param exception what went wrong

* @param responseMsg what response we have (if any)

* @return a response message to send to the user

*/

private Message convertExceptionToAxisFault(Exception exception,

Message responseMsg) {

logException(exception);

if (responseMsg == null) {

AxisFault fault = AxisFault.makeFault(exception);

processAxisFault(fault);

responseMsg = new Message(fault);

}

return responseMsg;

}

/**

* Extract information from AxisFault and map it to a HTTP Status code.

*

* @param af Axis Fault

* @return HTTP Status code.

*/

protected int getHttpServletResponseStatus(AxisFault af) {

// TODO: Should really be doing this with explicit AxisFault

// subclasses... --Glen

return af.getFaultCode().getLocalPart().startsWith("Server.Unauth")

? HttpServletResponse.SC_UNAUTHORIZED

: HttpServletResponse.SC_INTERNAL_SERVER_ERROR;

// This will raise a 401 for both

// "Unauthenticated" & "Unauthorized"...

}

/**

* write a message to the response, set appropriate headers for content

* type..etc.

* @param res response

* @param responseMsg message to write

* @throws AxisFault

* @throws IOException if the response stream can not be written to

*/

private void sendResponse(String contentType,

HttpServletResponse res,

Message responseMsg) throws AxisFault,

IOException {

if (responseMsg == null) {

res.setStatus(HttpServletResponse.SC_NO_CONTENT);

if (isDebug) {

log.debug("NO AXIS MESSAGE TO RETURN!");

//String resp = Messages.getMessage("noData00");

//res.setContentLength((int) resp.getBytes().length);

//res.getWriter().print(resp);

}

} else {

if (isDebug) {

log.debug("Returned Content-Type:" +

contentType);

// log.debug("Returned Content-Length:" +

// responseMsg.getContentLength());

}

try {

res.setContentType(contentType);

/* My understand of Content-Length

* HTTP 1.0

* -Required for requests, but optional for responses.

* HTTP 1.1

* - Either Content-Length or HTTP Chunking is required.

* Most servlet engines will do chunking if content-length is not
specified.

*

*

*/

//if(clientVersion == HTTPConstants.HEADER_PROTOCOL_V10) //do chunking
if necessary.

// res.setContentLength(responseMsg.getContentLength());

responseMsg.writeTo(res.getOutputStream());

} catch (SOAPException e) {

logException(e);

}

}

if (!res.isCommitted()) {

res.flushBuffer(); // Force it right now.

}

}

/**

* Place the Request message in the MessagContext object - notice

* that we just leave it as a 'ServletRequest' object and let the

* Message processing routine convert it - we don't do it since we

* don't know how it's going to be used - perhaps it might not

* even need to be parsed.

* @return a message context

*/

private MessageContext createMessageContext(AxisEngine engine,

HttpServletRequest req,

HttpServletResponse res) {

MessageContext msgContext = new MessageContext(engine);

String requestPath = getRequestPath(req);

if (isDebug) {

log.debug("MessageContext:" + msgContext);

log.debug("HEADER_CONTENT_TYPE:" +

req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE));

log.debug("HEADER_CONTENT_LOCATION:" +

req.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION));

log.debug("Constants.MC_HOME_DIR:" + String.valueOf(getHomeDir()));

log.debug("Constants.MC_RELATIVE_PATH:" + requestPath);

log.debug("HTTPConstants.MC_HTTP_SERVLETLOCATION:" +

String.valueOf(getWebInfPath()));

log.debug("HTTPConstants.MC_HTTP_SERVLETPATHINFO:" +

req.getPathInfo());

log.debug("HTTPConstants.HEADER_AUTHORIZATION:" +

req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

log.debug("Constants.MC_REMOTE_ADDR:" + req.getRemoteAddr());

log.debug("configPath:" + String.valueOf(getWebInfPath()));

}

/* Set the Transport */

/*********************/

msgContext.setTransportName(transportName);

/* Save some HTTP specific info in the bag in case someone needs it */

/********************************************************************/

msgContext.setProperty(Constants.MC_JWS_CLASSDIR, jwsClassDir);

msgContext.setProperty(Constants.MC_HOME_DIR, getHomeDir());

msgContext.setProperty(Constants.MC_RELATIVE_PATH, requestPath);

msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLET, this);

msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETREQUEST, req);

msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETRESPONSE, res);

msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETLOCATION,

getWebInfPath());

msgContext.setProperty(HTTPConstants.MC_HTTP_SERVLETPATHINFO,

req.getPathInfo());

msgContext.setProperty(HTTPConstants.HEADER_AUTHORIZATION,

req.getHeader(HTTPConstants.HEADER_AUTHORIZATION));

msgContext.setProperty(Constants.MC_REMOTE_ADDR, req.getRemoteAddr());

// Set up a javax.xml.rpc.server.ServletEndpointContext

ServletEndpointContextImpl sec = new ServletEndpointContextImpl();

msgContext.setProperty(Constants.MC_SERVLET_ENDPOINT_CONTEXT, sec);

/* Save the real path */

/**********************/

String realpath = getServletConfig().getServletContext()

.getRealPath(requestPath);

if (realpath != null) {

msgContext.setProperty(Constants.MC_REALPATH, realpath);

}

msgContext.setProperty(Constants.MC_CONFIGPATH, getWebInfPath());

return msgContext;

}

/**

* Extract the SOAPAction header.

* if SOAPAction is null then we'll we be forced to scan the body for it.

* if SOAPAction is "" then use the URL

* @param req incoming request

* @return the action

* @throws AxisFault

*/

private String getSoapAction(HttpServletRequest req) throws AxisFault {

String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);

if (soapAction == null) {

String contentType = req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);

if(contentType != null) {

int index = contentType.indexOf("action");

if(index != -1){

soapAction = contentType.substring(index + 7);

}

}

}

if (isDebug) {

log.debug("HEADER_SOAP_ACTION:" + soapAction);

/**

* Technically, if we don't find this header, we should probably fault.

* It's required in the SOAP HTTP binding.

*/

}

if (soapAction == null) {

AxisFault af = new AxisFault("Client.NoSOAPAction",

Messages.getMessage("noHeader00",

"SOAPAction"),

null, null);

exceptionLog.error(Messages.getMessage("genFault00"), af);

throw af;

}

// the SOAP 1.1 spec & WS-I 1.0 says:

// soapaction = "SOAPAction" ":" [ <"> URI-reference <"> ]

// some implementations leave off the quotes

// we strip them if they are present

if (soapAction.startsWith("\"") && soapAction.endsWith("\"")

&& soapAction.length() >= 2) {

int end = soapAction.length() - 1;

soapAction = soapAction.substring(1, end);

}

if (soapAction.length() == 0) {

soapAction = req.getContextPath(); // Is this right?

}

return soapAction;

}

/**

* Provided to allow overload of default JWSClassDir

* by derived class.

* @return directory for JWS files

*/

protected String getDefaultJWSClassDir() {

return (getWebInfPath() == null)

? null // ??? what is a good FINAL default for WebLogic?

: getWebInfPath() + File.separator + "jwsClasses";

}

/**

* Initialize a Handler for the transport defined in the Axis server
config.

* This includes optionally filling in query string handlers.

*/

public void initQueryStringHandlers() {

try {

this.transport = getEngine().getTransport(this.transportName);

if (this.transport == null) {

// No transport by this name is defined. Therefore, fill in default

// query string handlers.

this.transport = new SimpleTargetedChain();

this.transport.setOption("qs.list",

"org.apache.axis.transport.http.QSListHandler");

this.transport.setOption("qs.method",

"org.apache.axis.transport.http.QSMethodHandler");

this.transport.setOption("qs.wsdl",

"org.apache.axis.transport.http.QSWSDLHandler");

return;

}

else {

// See if we should use the default query string handlers.

// By default, set this to true (for backwards compatibility).

boolean defaultQueryStrings = true;

String useDefaults = (String)this.transport.getOption(

"useDefaultQueryStrings");

if ((useDefaults != null) &&

useDefaults.toLowerCase().equals("false")) {

defaultQueryStrings = false;

}

if (defaultQueryStrings == true) {

// We should use defaults, so fill them in.

this.transport.setOption("qs.list",

"org.apache.axis.transport.http.QSListHandler");

this.transport.setOption("qs.method",

"org.apache.axis.transport.http.QSMethodHandler");

this.transport.setOption("qs.wsdl",

"org.apache.axis.transport.http.QSWSDLHandler");

}

}

}

catch (AxisFault e) {

// Some sort of problem occurred, let's just make a default transport.

this.transport = new SimpleTargetedChain();

this.transport.setOption("qs.list",

"org.apache.axis.transport.http.QSListHandler");

this.transport.setOption("qs.method",

"org.apache.axis.transport.http.QSMethodHandler");

this.transport.setOption("qs.wsdl",

"org.apache.axis.transport.http.QSWSDLHandler");

return;

}

}

/**

* Attempts to invoke a plugin for the query string supplied in the URL.

*

* @param request the servlet's HttpServletRequest object.

* @param response the servlet's HttpServletResponse object.

* @param writer the servlet's PrintWriter object.

*/

private boolean processQuery(HttpServletRequest request,

HttpServletResponse response,

PrintWriter writer) throws AxisFault {

// Attempt to instantiate a plug-in handler class for the query string

// handler classes defined in the HTTP transport.

String path = request.getServletPath();

String queryString = request.getQueryString();

String serviceName;

AxisEngine engine = getEngine();

Iterator i = this.transport.getOptions().keySet().iterator();

if (queryString == null) {

return false;

}

String servletURI = request.getContextPath() + path;

String reqURI = request.getRequestURI();

// chop off '/'.

if (servletURI.length() + 1 < reqURI.length()) {

serviceName = reqURI.substring(servletURI.length() + 1);

} else {

serviceName = "";

} while (i.hasNext() == true) {

String queryHandler = (String) i.next();

if (queryHandler.startsWith("qs.") == true) {

// Only attempt to match the query string with transport

// parameters prefixed with "qs:".

String handlerName = queryHandler.substring

(queryHandler.indexOf(".") + 1).

toLowerCase();

// Determine the name of the plugin to invoke by using all text

// in the query string up to the first occurence of &, =, or the

// whole string if neither is present.

int length = 0;

boolean firstParamFound = false;

while (firstParamFound == false && length < queryString.length()) {

char ch = queryString.charAt(length++);

if (ch == '&' || ch == '=') {

firstParamFound = true;

--length;

}

}

if (length < queryString.length()) {

queryString = queryString.substring(0, length);

}

if (queryString.toLowerCase().equals(handlerName) == true) {

// Query string matches a defined query string handler name.

// If the defined class name for this query string handler is blank,

// just return (the handler is "turned off" in effect).

if (this.transport.getOption(queryHandler).equals("")) {

return false;

}

try {

// Attempt to dynamically load the query string handler

// and its "invoke" method.

MessageContext msgContext = createMessageContext(engine,

request, response);

Class plugin = Class.forName((String)this.transport.

getOption(queryHandler));

Method pluginMethod = plugin.getDeclaredMethod("invoke",

new Class[] {msgContext.getClass()});

String url = HttpUtils.getRequestURL(request).toString();

// Place various useful servlet-related objects in

// the MessageContext object being delivered to the

// plugin.

msgContext.setProperty(MessageContext.TRANS_URL, url);

msgContext.setProperty(HTTPConstants.

PLUGIN_SERVICE_NAME, serviceName);

msgContext.setProperty(HTTPConstants.PLUGIN_NAME,

handlerName);

msgContext.setProperty(HTTPConstants.

PLUGIN_IS_DEVELOPMENT,

new Boolean(isDevelopment()));

msgContext.setProperty(HTTPConstants.PLUGIN_ENABLE_LIST,

new Boolean(enableList));

msgContext.setProperty(HTTPConstants.PLUGIN_ENGINE,

engine);

msgContext.setProperty(HTTPConstants.PLUGIN_WRITER,

writer);

msgContext.setProperty(HTTPConstants.PLUGIN_LOG, log);

msgContext.setProperty(HTTPConstants.

PLUGIN_EXCEPTION_LOG,

exceptionLog);

// Invoke the plugin.

pluginMethod.invoke(plugin.newInstance(),

new Object[] {msgContext});

writer.close();

return true;

} catch (InvocationTargetException ie) {

reportTroubleInGet(ie.getTargetException(), response,

writer);

// return true to prevent any further processing

return true;

} catch (Exception e) {

reportTroubleInGet(e, response, writer);

// return true to prevent any further processing

return true;

}

}

}

}

return false;

}

/**

* getRequestPath a returns request path for web service padded with

* request.getPathInfo for web services served from /services directory.

* This is a required to support serving .jws web services from /services

* URL. See AXIS-843 for more information.

*

* @param request HttpServletRequest

* @return String

*/

private static String getRequestPath(HttpServletRequest request) {

return request.getServletPath() + ((request.getPathInfo() != null) ?

request.getPathInfo() : "");

}

}

 

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Monday, July 23, 2007 12:36 PM
To: Firas Khasawneh (fkhasawn); axis-user@ws.apache.org
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,

The order of  processing in the case of HTTP is;

AxisServlet->AxisEngine->HandlerChain->MessageProcessor->Service and
come back.
 
If you placed the server in a different machine, then your RTT should
definitely include the network time so it should be larger than the
processing time.
 
Thanks,
-jaliya
 

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: Jaliya Ekanayake <ma...@apache.org>  ;
axis-dev@ws.apache.org ; axis-user@ws.apache.org 
	Sent: Monday, July 23, 2007 11:27 AM
	Subject: RE: measuring Axix 1.4 overhead

	Hi Jaliya,
	 
	Do you know if response coming back from transport handler after
the request is processed in the Axis engine also hits AxisServlet and
uses doGet?
	 
	Thanks,
	Firas
	
________________________________

	From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
	Sent: Monday, July 23, 2007 9:42 AM
	To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas
Khasawneh (fkhasawn)
	Subject: Re: measuring Axix 1.4 overhead
	
	
	Hi Firas,
	 
	Are you trying both axis server and the client in a same
machine? If you put the handler in transport section, then what you will
measure is the time it takes inside the engine from transport handlers
->service -> transport handlers. One other possibility is to keep track
of the time in AxisServlet. Measure the time in AxisServlet before it
calls AxisEngine's invoke(..) method and after it is returned and you
will get the time for the total invocation.
	 
	Thanks,
	-jaliya

		----- Original Message ----- 
		From: Firas Khasawneh (fkhasawn)
<ma...@cisco.com>  
		To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
		Sent: Monday, July 23, 2007 6:06 AM
		Subject: RE: measuring Axix 1.4 overhead

		Any help regarding the below please? any suggestions on
how to measure the overhead Axis adds?

________________________________

		From: Firas Khasawneh (fkhasawn) 
		Sent: Sunday, July 22, 2007 11:50 PM
		To: 'axis-user@ws.apache.org'
		Subject: measuring Axix 1.4 overhead
		
		
		
		
		Hi all,
		 
		Anybody knows how to measure the overhead Axis 1.4 adds
to response time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
		 
		Regards,
		Firas Khasawneh


RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
Do you know if response coming back from transport handler after the
request is processed in the Axis engine also hits AxisServlet and uses
doGet?
 
Thanks,
Firas

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Monday, July 23, 2007 9:42 AM
To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh
(fkhasawn)
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,
 
Are you trying both axis server and the client in a same machine? If you
put the handler in transport section, then what you will measure is the
time it takes inside the engine from transport handlers ->service ->
transport handlers. One other possibility is to keep track of the time
in AxisServlet. Measure the time in AxisServlet before it calls
AxisEngine's invoke(..) method and after it is returned and you will get
the time for the total invocation.
 
Thanks,
-jaliya

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
	Sent: Monday, July 23, 2007 6:06 AM
	Subject: RE: measuring Axix 1.4 overhead

	Any help regarding the below please? any suggestions on how to
measure the overhead Axis adds?

________________________________

	From: Firas Khasawneh (fkhasawn) 
	Sent: Sunday, July 22, 2007 11:50 PM
	To: 'axis-user@ws.apache.org'
	Subject: measuring Axix 1.4 overhead
	
	
	
	
	Hi all,
	 
	Anybody knows how to measure the overhead Axis 1.4 adds to
response time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
	 
	Regards,
	Firas Khasawneh


RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
Yes I mean RTT by response time, the client is on a different machine. I
am not using client side Axis. I am using System.currentTimeMillis.
 
Regards,
Firas

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Monday, July 23, 2007 10:09 AM
To: Firas Khasawneh (fkhasawn); axis-dev@ws.apache.org
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,
 
What do you mean by the response time at the client. Is it the Round
Trip Time(RTT) of the web service invocation?
The reasons you are getting the same time may be;
You are using the server and the client in the same machine and the time
it takes for processing at the server is not captured at milliseconds
resolution.
 
If you are in JDK1.5 or above try using, System.nanoTime();
You will get a higer RTT if you deploy the server in a differnt machine
than where you run the client.
 
Thanks,
-jaliya
 
 

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: Jaliya Ekanayake <ma...@apache.org>  ;
axis-dev@ws.apache.org ; axis-user@ws.apache.org 
	Sent: Monday, July 23, 2007 9:45 AM
	Subject: RE: measuring Axix 1.4 overhead

	Hi Jaliya,
	 
	I am using only server side Axis, for client I am using SoapUI.
if I put the handler in transport for both response and request, I am
getting the response time I am measuring from my client so looks like it
is measuring from the client side (the time it gets the request till it
releases the http connection)
	 
	Thanks,
	Firas

________________________________

	From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
	Sent: Monday, July 23, 2007 9:42 AM
	To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas
Khasawneh (fkhasawn)
	Subject: Re: measuring Axix 1.4 overhead
	
	
	Hi Firas,
	 
	Are you trying both axis server and the client in a same
machine? If you put the handler in transport section, then what you will
measure is the time it takes inside the engine from transport handlers
->service -> transport handlers. One other possibility is to keep track
of the time in AxisServlet. Measure the time in AxisServlet before it
calls AxisEngine's invoke(..) method and after it is returned and you
will get the time for the total invocation.
	 
	Thanks,
	-jaliya

		----- Original Message ----- 
		From: Firas Khasawneh (fkhasawn)
<ma...@cisco.com>  
		To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
		Sent: Monday, July 23, 2007 6:06 AM
		Subject: RE: measuring Axix 1.4 overhead

		Any help regarding the below please? any suggestions on
how to measure the overhead Axis adds?

________________________________

		From: Firas Khasawneh (fkhasawn) 
		Sent: Sunday, July 22, 2007 11:50 PM
		To: 'axis-user@ws.apache.org'
		Subject: measuring Axix 1.4 overhead
		
		
		
		
		Hi all,
		 
		Anybody knows how to measure the overhead Axis 1.4 adds
to response time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
		 
		Regards,
		Firas Khasawneh


Re: measuring Axix 1.4 overhead

Posted by Jaliya Ekanayake <jn...@gmail.com>.
Hi Firas,

What do you mean by the response time at the client. Is it the Round Trip Time(RTT) of the web service invocation?
The reasons you are getting the same time may be;
You are using the server and the client in the same machine and the time it takes for processing at the server is not captured at milliseconds resolution.

If you are in JDK1.5 or above try using, System.nanoTime();
You will get a higer RTT if you deploy the server in a differnt machine than where you run the client.

Thanks,
-jaliya


  ----- Original Message ----- 
  From: Firas Khasawneh (fkhasawn) 
  To: Jaliya Ekanayake ; axis-dev@ws.apache.org ; axis-user@ws.apache.org 
  Sent: Monday, July 23, 2007 9:45 AM
  Subject: RE: measuring Axix 1.4 overhead


  Hi Jaliya,

  I am using only server side Axis, for client I am using SoapUI. if I put the handler in transport for both response and request, I am getting the response time I am measuring from my client so looks like it is measuring from the client side (the time it gets the request till it releases the http connection)

  Thanks,
  Firas



------------------------------------------------------------------------------
  From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
  Sent: Monday, July 23, 2007 9:42 AM
  To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh (fkhasawn)
  Subject: Re: measuring Axix 1.4 overhead


  Hi Firas,

  Are you trying both axis server and the client in a same machine? If you put the handler in transport section, then what you will measure is the time it takes inside the engine from transport handlers ->service -> transport handlers. One other possibility is to keep track of the time in AxisServlet. Measure the time in AxisServlet before it calls AxisEngine's invoke(..) method and after it is returned and you will get the time for the total invocation.

  Thanks,
  -jaliya
    ----- Original Message ----- 
    From: Firas Khasawneh (fkhasawn) 
    To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
    Sent: Monday, July 23, 2007 6:06 AM
    Subject: RE: measuring Axix 1.4 overhead


    Any help regarding the below please? any suggestions on how to measure the overhead Axis adds?



----------------------------------------------------------------------------
    From: Firas Khasawneh (fkhasawn) 
    Sent: Sunday, July 22, 2007 11:50 PM
    To: 'axis-user@ws.apache.org'
    Subject: measuring Axix 1.4 overhead


    Hi all,

    Anybody knows how to measure the overhead Axis 1.4 adds to response time? I created a handler in the requestFlow to  store System.currentTimeMillis in messageContext and another handler in the responseFlow that retrieved this value and subtracts it from System.currentTimeMillis(), when I use these classes in the global conf or transport (server side) I am getting values that correspond to the response time the client is getting so it looks like it is not calculating the Axix overhead on the server side, when I put these handlers in the requestFlow and responseFlow in the service section in server-conf.wsdd it gives differnt time which seem right but I am nti sure if this is the Axix engine overhead? Any suggestions? other ways to do this? please reply back to me or CC me if you are sending to the list since I am not yet a member in this list.

    Regards,
    Firas Khasawneh

RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
I am using only server side Axis, for client I am using SoapUI. if I put
the handler in transport for both response and request, I am getting the
response time I am measuring from my client so looks like it is
measuring from the client side (the time it gets the request till it
releases the http connection)
 
Thanks,
Firas

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Monday, July 23, 2007 9:42 AM
To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh
(fkhasawn)
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,
 
Are you trying both axis server and the client in a same machine? If you
put the handler in transport section, then what you will measure is the
time it takes inside the engine from transport handlers ->service ->
transport handlers. One other possibility is to keep track of the time
in AxisServlet. Measure the time in AxisServlet before it calls
AxisEngine's invoke(..) method and after it is returned and you will get
the time for the total invocation.
 
Thanks,
-jaliya

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
	Sent: Monday, July 23, 2007 6:06 AM
	Subject: RE: measuring Axix 1.4 overhead

	Any help regarding the below please? any suggestions on how to
measure the overhead Axis adds?

________________________________

	From: Firas Khasawneh (fkhasawn) 
	Sent: Sunday, July 22, 2007 11:50 PM
	To: 'axis-user@ws.apache.org'
	Subject: measuring Axix 1.4 overhead
	
	
	
	
	Hi all,
	 
	Anybody knows how to measure the overhead Axis 1.4 adds to
response time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
	 
	Regards,
	Firas Khasawneh


RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
I am using only server side Axis, for client I am using SoapUI. if I put
the handler in transport for both response and request, I am getting the
response time I am measuring from my client so looks like it is
measuring from the client side (the time it gets the request till it
releases the http connection)
 
Thanks,
Firas

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Monday, July 23, 2007 9:42 AM
To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh
(fkhasawn)
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,
 
Are you trying both axis server and the client in a same machine? If you
put the handler in transport section, then what you will measure is the
time it takes inside the engine from transport handlers ->service ->
transport handlers. One other possibility is to keep track of the time
in AxisServlet. Measure the time in AxisServlet before it calls
AxisEngine's invoke(..) method and after it is returned and you will get
the time for the total invocation.
 
Thanks,
-jaliya

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
	Sent: Monday, July 23, 2007 6:06 AM
	Subject: RE: measuring Axix 1.4 overhead

	Any help regarding the below please? any suggestions on how to
measure the overhead Axis adds?

________________________________

	From: Firas Khasawneh (fkhasawn) 
	Sent: Sunday, July 22, 2007 11:50 PM
	To: 'axis-user@ws.apache.org'
	Subject: measuring Axix 1.4 overhead
	
	
	
	
	Hi all,
	 
	Anybody knows how to measure the overhead Axis 1.4 adds to
response time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
	 
	Regards,
	Firas Khasawneh


RE: measuring Axix 1.4 overhead

Posted by "Firas Khasawneh (fkhasawn)" <fk...@cisco.com>.
Hi Jaliya,
 
Do you know if response coming back from transport handler after the
request is processed in the Axis engine also hits AxisServlet and uses
doGet?
 
Thanks,
Firas

________________________________

From: Jaliya Ekanayake [mailto:jnekanayake@gmail.com] 
Sent: Monday, July 23, 2007 9:42 AM
To: axis-dev@ws.apache.org; axis-user@ws.apache.org; Firas Khasawneh
(fkhasawn)
Subject: Re: measuring Axix 1.4 overhead


Hi Firas,
 
Are you trying both axis server and the client in a same machine? If you
put the handler in transport section, then what you will measure is the
time it takes inside the engine from transport handlers ->service ->
transport handlers. One other possibility is to keep track of the time
in AxisServlet. Measure the time in AxisServlet before it calls
AxisEngine's invoke(..) method and after it is returned and you will get
the time for the total invocation.
 
Thanks,
-jaliya

	----- Original Message ----- 
	From: Firas Khasawneh (fkhasawn) <ma...@cisco.com>  
	To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
	Sent: Monday, July 23, 2007 6:06 AM
	Subject: RE: measuring Axix 1.4 overhead

	Any help regarding the below please? any suggestions on how to
measure the overhead Axis adds?

________________________________

	From: Firas Khasawneh (fkhasawn) 
	Sent: Sunday, July 22, 2007 11:50 PM
	To: 'axis-user@ws.apache.org'
	Subject: measuring Axix 1.4 overhead
	
	
	
	
	Hi all,
	 
	Anybody knows how to measure the overhead Axis 1.4 adds to
response time? I created a handler in the requestFlow to  store
System.currentTimeMillis in messageContext and another handler in the
responseFlow that retrieved this value and subtracts it from
System.currentTimeMillis(), when I use these classes in the global conf
or transport (server side) I am getting values that correspond to the
response time the client is getting so it looks like it is not
calculating the Axix overhead on the server side, when I put these
handlers in the requestFlow and responseFlow in the service section in
server-conf.wsdd it gives differnt time which seem right but I am nti
sure if this is the Axix engine overhead? Any suggestions? other ways to
do this? please reply back to me or CC me if you are sending to the list
since I am not yet a member in this list.
	 
	Regards,
	Firas Khasawneh


Re: measuring Axix 1.4 overhead

Posted by Jaliya Ekanayake <jn...@gmail.com>.
Hi Firas,

Are you trying both axis server and the client in a same machine? If you put the handler in transport section, then what you will measure is the time it takes inside the engine from transport handlers ->service -> transport handlers. One other possibility is to keep track of the time in AxisServlet. Measure the time in AxisServlet before it calls AxisEngine's invoke(..) method and after it is returned and you will get the time for the total invocation.

Thanks,
-jaliya
  ----- Original Message ----- 
  From: Firas Khasawneh (fkhasawn) 
  To: axis-user@ws.apache.org ; axis-dev@ws.apache.org 
  Sent: Monday, July 23, 2007 6:06 AM
  Subject: RE: measuring Axix 1.4 overhead


  Any help regarding the below please? any suggestions on how to measure the overhead Axis adds?



------------------------------------------------------------------------------
  From: Firas Khasawneh (fkhasawn) 
  Sent: Sunday, July 22, 2007 11:50 PM
  To: 'axis-user@ws.apache.org'
  Subject: measuring Axix 1.4 overhead


  Hi all,

  Anybody knows how to measure the overhead Axis 1.4 adds to response time? I created a handler in the requestFlow to  store System.currentTimeMillis in messageContext and another handler in the responseFlow that retrieved this value and subtracts it from System.currentTimeMillis(), when I use these classes in the global conf or transport (server side) I am getting values that correspond to the response time the client is getting so it looks like it is not calculating the Axix overhead on the server side, when I put these handlers in the requestFlow and responseFlow in the service section in server-conf.wsdd it gives differnt time which seem right but I am nti sure if this is the Axix engine overhead? Any suggestions? other ways to do this? please reply back to me or CC me if you are sending to the list since I am not yet a member in this list.

  Regards,
  Firas Khasawneh