Package flex.messaging.messages

Source Code of flex.messaging.messages.MessagePerformanceUtils

/*************************************************************************
*
* ADOBE CONFIDENTIAL
* __________________
*
*  Copyright 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.