Package flex.messaging.messages

Source Code of flex.messaging.messages.MessagePerformanceUtils

/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
*  [2002] - [2007] Adobe Systems Incorporated
*  All Rights Reserved.
*
* NOTICE:  All information contained herein is, and remains
* the property of Adobe Systems Incorporated and its suppliers,
* if any.  The intellectual and technical concepts contained
* herein are proprietary to Adobe Systems Incorporated
* and its suppliers and may be covered by U.S. and Foreign Patents,
* patents in process, and are protected by trade secret or copyright law.
* Dissemination of this information or reproduction of this material
* is strictly forbidden unless prior written permission is obtained
* from Adobe Systems Incorporated.
*/
package flex.messaging.messages;

import flex.messaging.messages.BatchableMessage;
import flex.messaging.io.amf.ActionContext;
import flex.messaging.log.Log;
import flex.messaging.log.LogCategories;

/**
* @exclude
*
* Utility class for populating  MessagePerformanceInformation objects at various stages of
* server processing.  A given message may have three MPI headers populated (naming convention
* of these headers is from the perspective of the server):
*
* DSMPII - incoming message, message sent from client to server
* DSMPIO - outgoing message, response/acknowledgement message sent from server back to client
* DSMPIP - only populated for a pushed message, this is information for the incoming message
* that caused the pushed message
*/
public class MessagePerformanceUtils
{
 
  static final String LOG_CATEGORY = LogCategories.MESSAGE_GENERAL;
 
    public static final String MPI_HEADER_IN = "DSMPII";
    public static final String MPI_HEADER_OUT = "DSMPIO";
    public static final String MPI_HEADER_PUSH = "DSMPIP";
   
  public static int MPI_NONE = 0;
  public static int MPI_TIMING = 1;
  public static int MPI_TIMING_AND_SIZING = 2;
 
  /**
   * @exclude
   *
   * Clones the MPI object for the incoming message from client to server
   * from the batch wrapper to all messages included in it, keeping track of
   * overhead time spent doing this.
   *
   * @param message The message whose MPI should be propogated
   */
    public static void propogateMPIDownBatch(Message message)
    {
      long overhead = System.currentTimeMillis();
      if(message instanceof BatchableMessage)
      {
            BatchableMessage dm = (BatchableMessage)message;
        if(dm.isBatched())
        {
           Object[] batchedMessages = (Object[])message.getBody();
           int batchedLength = batchedMessages.length;
           for(int a=0;a<batchedLength;a++)
           {
             Message currentMess = (Message)batchedMessages[a];
             MessagePerformanceInfo mpi = MessagePerformanceUtils.getMPII(message);
             MessagePerformanceUtils.setMPII(currentMess, (MessagePerformanceInfo)mpi.clone());
             propogateMPIDownBatch(currentMess);
           }
        }
      }
      overhead = System.currentTimeMillis() - overhead;
      MessagePerformanceUtils.getMPII(message).addToOverhead(overhead);
   }
   
  /**
   * @exclude
   *
   * This method finalizes the incoming MPI instance.  It is necessary because the client
   * send time is stored on the incoming MPII and the server receive time as well as message
   * size are populated in the MPI object stored on the ActionContext, this method combines
   * the information into one MPI instance. 
   *
   * @param context - The action context used to deserialize the incoming message, it will have the
   * server receive time and message size information
   * @param inMessage - The incoming message, its MPI will have the client send time
   */
    public static void setupMPII(ActionContext context, Message inMessage)
    {         
        try
        {  
          // the MPI from the incoming message will have the client-send timestamp
          MessagePerformanceInfo mpii= MessagePerformanceUtils.getMPII(inMessage);
         
          // this is the MPI that we want to propogate
          MessagePerformanceInfo contextMPI = context.getMPII();
          if(contextMPI!=null && mpii!=null){
            contextMPI.sendTime = mpii.sendTime;
            MessagePerformanceUtils.setMPII(inMessage, (MessagePerformanceInfo)contextMPI.clone());
            propogateMPIDownBatch(inMessage);
          }
        }
        catch(Exception e)
        {
            if (Log.isDebug())
                Log.getLogger(LOG_CATEGORY).error("MPI error: setting up response MPI : " +
                     e.toString());
        }
    }   
   
  /**
   * @exclude
   *
   * This method sets up the outgoing MPI object for a response/acknowledgement message. 
   * The outgoing message should also have a copy of the incoming MPI so that when the client
   * receives the response it has access to all information
   *
   * @param context - The context used to deserialize the incoming message
   * @param inMessage - The incoming message
   * @param outMessage - The response message
   */
    public static void updateOutgoingMPI(ActionContext context, Message inMessage, Object outMessage)
    {
        try
      {
          MessagePerformanceInfo mpio=null;
          if(context != null)
          {
            mpio = context.getMPIO();
            if(mpio == null)
            {
              mpio = new MessagePerformanceInfo();
              if(MessagePerformanceUtils.getMPII(inMessage)!=null && MessagePerformanceUtils.getMPII(inMessage).sendTime!=0)
                mpio.infoType="OUT";
            }         
            Message mess = (Message)outMessage;
            if(MessagePerformanceUtils.getMPII(inMessage)!=null)
              MessagePerformanceUtils.setMPII(mess, (MessagePerformanceInfo)MessagePerformanceUtils.getMPII(inMessage).clone());
            MessagePerformanceUtils.setMPIO(mess, mpio);
            context.setMPIO(mpio);
          }
         
          if(outMessage instanceof CommandMessage &&
              ((CommandMessage)outMessage).getOperation() == CommandMessage.CLIENT_SYNC_OPERATION)
          {
            // pushed message case
            CommandMessage cmd = (CommandMessage)outMessage;
            Object[] cmdBody = (Object[])cmd.getBody();
            // in the pushed message case we want the outgoing metrics of the message to be updated
            // however, we want the incoming metrics to be that of the poll message and
            // the incoming push metrics to be that of the original message              
            int batchedLength = cmdBody.length;
            for(int i = 0; i < batchedLength; i++)
            {             
              Message currentMess = (Message)cmdBody[i];
                    MessagePerformanceInfo origMPII =  MessagePerformanceUtils.getMPII(currentMess);
                   
                    if (origMPII == null || MessagePerformanceUtils.getMPII(inMessage) == null)
                    {
                        // this can happen if the server has MPI enabled but the producing client does not
                        // log a warning for this and break out of here as MPI requires all participating
                        // parties to have the same settings
                        if (Log.isError())
                        {
                            Log.getLogger(LOG_CATEGORY).error
                            (
                                    "MPI is enabled but could not get message performance information " +
                                            "for incoming MPI instance from client message.  The client "+
                                            "might have created a new channel not configured to send message" +
                                            " performance after declaring a different destination which does." +
                                            "  The client channel should either be configured to add MPI " +
                                            "properties, or a server destion which has the same MPI " +
                                            "properties as the client channel should be used.");
                        }
                        return;
                    }
                   
              MessagePerformanceUtils.setMPIP(currentMess, (MessagePerformanceInfo)origMPII.clone());
              MessagePerformanceInfo newMPII = (MessagePerformanceInfo)MessagePerformanceUtils.getMPII(inMessage).clone();
              mpio.pushedFlag=true;
              MessagePerformanceUtils.setMPII(currentMess, newMPII);
              MessagePerformanceUtils.setMPIO(currentMess, mpio);
            }       
          }         
        } 
        catch(Exception e)
        {
            if (Log.isDebug())
                Log.getLogger(LOG_CATEGORY).error("MPI error: setting up response MPI : " +
                     e.toString());
        }        
    }

  /**
   * @exclude
   *
   * Convenience method for setting the incoming MPI object on a message.
   *
   * @param message The message whose MPI header will be set
   * @param mpi The incoming MPI instance
   */
    public static void setMPII(Message message, MessagePerformanceInfo mpi)
    {
      message.setHeader(MPI_HEADER_IN, mpi);
    }

  /**
   * @exclude
   *
   * Convenience method for setting the outgoing MPI object on a message.
   *
   * @param message The message whose MPI header will be set
   * @param mpi The outgoing MPI instance
   */    
    public static void setMPIO(Message message, MessagePerformanceInfo mpi)
    {
      message.setHeader(MPI_HEADER_OUT, mpi);
    }   
   
  /**
   * @exclude
   *
   * Convenience method for setting the pushed MPI object on a message.
   *
   * @param message The message whose MPI header will be set
   * @param mpi The pushed MPI instance (this is the incoming MPI instance
   * of the message that caused the push)
   */     
    public static void setMPIP(Message message, MessagePerformanceInfo mpi)
    {
      message.setHeader(MPI_HEADER_PUSH, mpi);
    }   

  /**
   * @exclude
   *
   * Convenience method for retrieving the incoming MPI object from a message.
   *
   * @param message The message whose MPI header will be retrieved
   * @return mpi Incoming MPI instance
   */
    public static MessagePerformanceInfo getMPII(Message message)
    {
      return (MessagePerformanceInfo)message.getHeader(MPI_HEADER_IN);
    }

  /**
   * @exclude
   *
   * Convenience method for retrieving the outgoing MPI object from a message.
   *
   * @param message The message whose MPI header will be retrieved
   * @return mpi Outgoing MPI instance
   */    
    public static MessagePerformanceInfo getMPIO(Message message)
    {
      return (MessagePerformanceInfo)message.getHeader(MPI_HEADER_OUT);
    }   

  /**
   * @exclude
   *
   * Convenience method for retrieving the pushed MPI object from a message.
   *
   * @param message The message whose MPI header will be retrieved
   * @return mpi Pushed MPI instance (this is the incoming MPI instance
   * of the message that caused the push)
   */    
    public static MessagePerformanceInfo getMPIP(Message message)
    {
      return (MessagePerformanceInfo)message.getHeader(MPI_HEADER_PUSH);
    }       

  /**
   * @exclude
   *
   * Convenience method for setting server pre-push processing time on a message.
   * No-op if record-message-times is false
   *
   * @param message The message whose MPI header will be updated
   */     
    public static void markServerPrePushTime(Message message)
    {
      // If the message does not have an MPI header then we are not recording message times
      // and we have nothing to do here
      if (getMPII(message) == null || getMPII(message).sendTime == 0)
        return;
     
      MessagePerformanceInfo mpi = getMPII(message);
      mpi.serverPrePushTime = System.currentTimeMillis();
    }
   
  /**
   * @exclude
   *
   * Convenience method for setting server pre-adapter timestamp on a message.
   * No-op if record-message-times is false
   *
   * @param message The message whose MPI header will be updated
   */     
    public static void markServerPreAdapterTime(Message message)
    {
      // If the message does not have an MPI header then we are not recording message times
      // and we have nothing to do here
      if (getMPII(message) == null || getMPII(message).sendTime == 0)
        return;
     
      MessagePerformanceInfo mpi = getMPII(message);
       
        // it is possible that a batched message will have this called multiple times,
        // do not reset stamp once it has been set
        if (mpi.serverPreAdapterTime != 0)
            return;
       
      mpi.serverPreAdapterTime = System.currentTimeMillis();
    }   
   
  /**
   * @exclude
   *
   * Convenience method for setting server post-adapter timestamp on a message.
   * No-op if record-message-times is false
   *
   * @param message The message whose MPI header will be updated
   */     
    public static void markServerPostAdapterTime(Message message)
    {
      // If the message does not have an MPI header then we are not recording message times
      // and we have nothing to do here
      if (getMPII(message) == null || getMPII(message).sendTime == 0 || getMPII(message).serverPostAdapterTime != 0)
        return;
     
      MessagePerformanceInfo mpi = getMPII(message);
      mpi.serverPostAdapterTime = System.currentTimeMillis();
    }     
   
  /**
   *
   * Method may be called from a custom adapter to mark the beginning of processing that occurs
   * outside of the adapter for a particular message.  Use this method in conjunction with
   * <code>markServerPostAdapterExternalTime</code> to mark the amount of time spent when your
   * adapter must make a call to an external component.  If <code>record-message-times</code> is
   * <code>true</code> for the communication channel, the server processing time external to the
   * adapter may be retrieved via MessagePerformanceUtils.serverAdapterExternalTime on the client
   * once it receives the message.
   *
   * If <code>record-message-times</code> is <code>false</code> for the communication channel,
   * calling this method will have no effect.     
   *
   * @param message The message being processed
   */     
    public static void markServerPreAdapterExternalTime(Message message)
    {
      // If the message does not have an MPI header then we are not recording message times
      // and we have nothing to do here
      if (getMPII(message) == null || getMPII(message).sendTime == 0)
        return;
     
      MessagePerformanceInfo mpi = getMPII(message);
      mpi.serverPreAdapterExternalTime = System.currentTimeMillis();
    }   
   
  /**
   *
   * Method may be called from a custom adapter to mark the end of processing that occurs
   * outside of the adapter for a particular message.  Use this method in conjunction with
   * <code>markServerPreAdapterExternalTime</code> to mark the amount of time spent when your
   * adapter must make a call to an external component.  If <code>record-message-times</code> is
   * <code>true</code> for the communication channel, the server processing time external to the
   * adapter may be retrieved via MessagePerformanceUtils.serverAdapterExternalTime on the client
   * once it receives the message.
   *
   * If <code>record-message-times</code> is <code>false</code> for the communication channel,
   * calling this method will have no effect.     
   *
   * @param message The message being processed
   */     
    public static void markServerPostAdapterExternalTime(Message message)
    {
      // If the message does not have an MPI header then we are not recording message times
      // and we have nothing to do here
      if (getMPII(message) == null || getMPII(message).sendTime == 0 || getMPII(message).serverPostAdapterExternalTime != 0)
        return;
     
      MessagePerformanceInfo mpi = getMPII(message);
      mpi.serverPostAdapterExternalTime = System.currentTimeMillis();
    }     

}
TOP

Related Classes of flex.messaging.messages.MessagePerformanceUtils

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.