Package org.apache.catalina.cluster.tcp

Source Code of org.apache.catalina.cluster.tcp.ReplicationValve

/*
* Copyright 1999,2004-2005 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.catalina.cluster.tcp;

import java.io.IOException;
import java.util.StringTokenizer;
import java.util.regex.Pattern;

import javax.servlet.ServletException;

import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.cluster.CatalinaCluster;
import org.apache.catalina.cluster.ClusterManager;
import org.apache.catalina.cluster.ClusterMessage;
import org.apache.catalina.cluster.ClusterSession;
import org.apache.catalina.cluster.ClusterValve;
import org.apache.catalina.cluster.session.DeltaManager;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.util.StringManager;
import org.apache.catalina.valves.ValveBase;

/**
* <p>Implementation of a Valve that logs interesting contents from the
* specified Request (before processing) and the corresponding Response
* (after processing).  It is especially useful in debugging problems
* related to headers and cookies.</p>
*
* <p>This Valve may be attached to any Container, depending on the granularity
* of the logging you wish to perform.</p>
*
* <p>primaryIndicator=true, then the request attribute <i>org.apache.catalina.cluster.tcp.isPrimarySession.</i>
* is set true, when request processing is at sessions primary node.
* </p>
*
* @author Craig R. McClanahan
* @author Filip Hanik
* @author Peter Rossbach
* @version $Revision: 304032 $ $Date: 2005-07-27 11:11:55 -0400 (Wed, 27 Jul 2005) $
*/

public class ReplicationValve
    extends ValveBase implements ClusterValve {
   
    private static org.apache.commons.logging.Log log =
        org.apache.commons.logging.LogFactory.getLog( ReplicationValve.class );

    // ----------------------------------------------------- Instance Variables

    /**
     * The descriptive information related to this implementation.
     */
    private static final String info =
        "org.apache.catalina.cluster.tcp.ReplicationValve/1.2";


    /**
     * The StringManager for this package.
     */
    protected static StringManager sm =
        StringManager.getManager(Constants.Package);

    private CatalinaCluster cluster = null ;

    /**
     * holds file endings to not call for like images and others
     */
    protected java.util.regex.Pattern[] reqFilters = new java.util.regex.Pattern[0];
    protected String filter ;

    protected long totalRequestTime=0;
    protected long totalSendTime=0;
    protected long nrOfRequests =0;
    protected long lastSendTime =0;
    protected long nrOfFilterRequests=0;
    protected boolean primaryIndicator = false ;
    protected String primaryIndicatorName = "org.apache.catalina.cluster.tcp.isPrimarySession";
  
    // ------------------------------------------------------------- Properties

    public ReplicationValve() {
    }
    /**
     * Return descriptive information about this Valve implementation.
     */
    public String getInfo() {

        return (info);

    }
   
    /**
     * @return Returns the cluster.
     */
    public CatalinaCluster getCluster() {
        return cluster;
    }
   
    /**
     * @param cluster The cluster to set.
     */
    public void setCluster(CatalinaCluster cluster) {
        this.cluster = cluster;
    }
    /**
     * @return Returns the filter
     */
    public String getFilter() {
       return filter ;
    }

    /**
     * compile filter string to regular expressions
     * @see Pattern#compile(java.lang.String)
     * @param filter
     *            The filter to set.
     */
    public void setFilter(String filter) {
        if (log.isDebugEnabled())
            log.debug(sm.getString("ReplicationValve.filter.loading", filter));
        this.filter = filter;
        StringTokenizer t = new StringTokenizer(filter, ";");
        this.reqFilters = new Pattern[t.countTokens()];
        int i = 0;
        while (t.hasMoreTokens()) {
            String s = t.nextToken();
            if (log.isTraceEnabled())
                log.trace(sm.getString("ReplicationValve.filter.token", s));
            try {
                reqFilters[i++] = Pattern.compile(s);
            } catch (Exception x) {
                log.error(sm.getString("ReplicationValve.filter.token.failure",
                        s), x);
            }
        }
    }

    /**
     * @return Returns the primaryIndicator.
     */
    public boolean isPrimaryIndicator() {
        return primaryIndicator;
    }
    /**
     * @param primaryIndicator The primaryIndicator to set.
     */
    public void setPrimaryIndicator(boolean primaryIndicator) {
        this.primaryIndicator = primaryIndicator;
    }
    /**
     * @return Returns the primaryIndicatorName.
     */
    public String getPrimaryIndicatorName() {
        return primaryIndicatorName;
    }
    /**
     * @param primaryIndicatorName The primaryIndicatorName to set.
     */
    public void setPrimaryIndicatorName(String primaryIndicatorName) {
        this.primaryIndicatorName = primaryIndicatorName;
    }
     
    /**
     * @return Returns the lastSendTime.
     */
    public long getLastSendTime() {
        return lastSendTime;
    }
   
    /**
     * @return Returns the nrOfRequests.
     */
    public long getNrOfRequests() {
        return nrOfRequests;
    }
   
    /**
     * @return Returns the nrOfFilterRequests.
     */
    public long getNrOfFilterRequests() {
        return nrOfFilterRequests;
    }

    /**
     * @return Returns the totalRequestTime.
     */
    public long getTotalRequestTime() {
        return totalRequestTime;
    }
   
    /**
     * @return Returns the totalSendTime.
     */
    public long getTotalSendTime() {
        return totalSendTime;
    }

    /**
     * @return Returns the reqFilters.
     */
    protected java.util.regex.Pattern[] getReqFilters() {
        return reqFilters;
    }
    /**
     * @param reqFilters The reqFilters to set.
     */
    protected void setReqFilters(java.util.regex.Pattern[] reqFilters) {
        this.reqFilters = reqFilters;
    }
   
    // --------------------------------------------------------- Public Methods
   

    /**
     * Log the interesting request parameters, invoke the next Valve in the
     * sequence, and log the interesting response parameters.
     *
     * @param request The servlet request to be processed
     * @param response The servlet response to be created
     *
     * @exception IOException if an input/output error occurs
     * @exception ServletException if a servlet error occurs
     */
    public void invoke(Request request, Response response)
        throws IOException, ServletException
    {
        long totalstart = System.currentTimeMillis();
        //this happens before the request
        if (primaryIndicator)
            createPrimaryIndicator( request) ;
        getNext().invoke(request, response);
        //this happens after the request
        long start = System.currentTimeMillis();
        Manager manager = request.getContext().getManager();
        if (manager != null && manager instanceof ClusterManager) {
            ClusterManager clusterManager = (ClusterManager) manager;
            CatalinaCluster cluster = (CatalinaCluster) getContainer()
                    .getCluster();
            if (cluster == null) {
                if (log.isWarnEnabled())
                    log.warn(sm.getString("ReplicationValve.nocluster"));
                return;
            }
            // valve cluster can access manager - other clusterhandle replication
            // at host level - hopefully!
            if(cluster.getManager(clusterManager.getName()) == null)
                return ;
            if(cluster.getMembers().length > ) {
                try {
                    // send invalid sessions
                    // DeltaManager returns String[0]
                    if (!(clusterManager instanceof DeltaManager))
                        sendInvalidSessions(clusterManager, cluster);
                    // send replication
                    sendSessionReplicationMessage(request, clusterManager, cluster);
                } catch (Exception x) {
                    log.error(sm.getString("ReplicationValve.send.failure"), x);
                } finally {
                    long stop = System.currentTimeMillis();
                    updateStats(stop - totalstart, stop - start);
                }
            }
        }
    }
 
    /**
     * reset the active statitics
     */
    public void resetStatistics() {
        totalRequestTime = 0 ;
        totalSendTime = 0 ;
        lastSendTime = 0 ;
        nrOfFilterRequests = 0 ;
        nrOfRequests = 0 ;
    }
   
    /**
     * Return a String rendering of this object.
     */
    public String toString() {

        StringBuffer sb = new StringBuffer("ReplicationValve[");
        if (container != null)
            sb.append(container.getName());
        sb.append("]");
        return (sb.toString());

    }

    // --------------------------------------------------------- Protected Methods

    /**
     * Send Cluster Replication Request
     * @see DeltaManager#requestCompleted(String)
     * @see SimpleTcpCluster#send(ClusterMessage)
     * @param request
     * @param manager
     * @param cluster
     */
    protected void sendSessionReplicationMessage(Request request,
            ClusterManager manager, CatalinaCluster cluster) {
        Session session = request.getSessionInternal(false);
        if (session != null) {
            String uri = request.getDecodedRequestURI();
            // request without session change
            if (!isRequestWithoutSessionChange(uri)) {

                if (log.isDebugEnabled())
                    log.debug(sm.getString("ReplicationValve.invoke.uri", uri));
                String id = session.getIdInternal();
                if (id != null) {
                    ClusterMessage msg = manager.requestCompleted(id);
                    // really send replication send request
                    // FIXME send directly via ClusterManager.send
                    if (msg != null) {
                        if(manager.isSendClusterDomainOnly())
                            cluster.sendClusterDomain(msg);
                        else
                            cluster.send(msg);
                    }
                }
            } else
                nrOfFilterRequests++;
        }

    }
   
    /**
     * check for session invalidations
     * @param manager
     * @param cluster
     */
    protected void sendInvalidSessions(ClusterManager manager, CatalinaCluster cluster) {
        String[] invalidIds=manager.getInvalidatedSessions();
        if ( invalidIds.length > 0 ) {
            for ( int i=0;i<invalidIds.length; i++ ) {
                try {
                    ClusterMessage imsg = manager.requestCompleted(invalidIds[i]);
                    // FIXME send directly via ClusterManager.send
                    if (imsg != null) {
                        if(manager.isSendClusterDomainOnly())
                            cluster.sendClusterDomain(imsg);
                        else
                            cluster.send(imsg);
                    }
                } catch ( Exception x ) {
                    log.error(sm.getString("ReplicationValve.send.invalid.failure",invalidIds[i]),x);
                }
            }
        }
    }
   
    /**
     * is request without possible session change
     * @param uri The request uri
     * @return True if no session change
     */
    protected boolean isRequestWithoutSessionChange(String uri) {

        boolean filterfound = false;

        for (int i = 0; (i < reqFilters.length) && (!filterfound); i++) {
            java.util.regex.Matcher matcher = reqFilters[i].matcher(uri);
            filterfound = matcher.matches();
        }
        return filterfound;
    }

    /**
     * protocol cluster replications stats
     * @param requestTime
     * @param clusterTime
     */
    protected synchronized void updateStats(long requestTime, long clusterTime) {
        totalSendTime+=clusterTime;
        totalRequestTime+=requestTime;
        nrOfRequests++;
        if ( (nrOfRequests % 100) == 0 ) {
            if(log.isInfoEnabled()) {
                 log.info(sm.getString("ReplicationValve.stats",
                     new Object[]{
                         new Long(totalRequestTime/nrOfRequests),
                         new Long(totalSendTime/nrOfRequests),
                         new Long(nrOfRequests),
                         new Long(nrOfFilterRequests),
                         new Long(totalRequestTime),
                         new Long(totalSendTime)}));
             }
        }
        lastSendTime=System.currentTimeMillis();
    }


    /**
     * Mark Request that processed at primary node with attribute
     * primaryIndicatorName
     *
     * @param request
     * @throws IOException
     */
    protected void createPrimaryIndicator(Request request) throws IOException {
        String id = request.getRequestedSessionId();
        if ((id != null) && (id.length() > 0)) {
            Manager manager = request.getContext().getManager();
            Session session = manager.findSession(id);
            if (session instanceof ClusterSession) {
                ClusterSession cses = (ClusterSession) session;
                if (cses != null) {
                    Boolean isPrimary = new Boolean(cses.isPrimarySession());
                    if (log.isDebugEnabled())
                        log.debug(sm.getString(
                                "ReplicationValve.session.indicator", request.getContext().getName(),id,
                                primaryIndicatorName, isPrimary));
                    request.setAttribute(primaryIndicatorName, isPrimary);
                }
            } else {
                if (log.isDebugEnabled()) {
                    if (session != null) {
                        log.debug(sm.getString(
                                "ReplicationValve.session.found", request.getContext().getName(),id));
                    } else {
                        log.debug(sm.getString(
                                "ReplicationValve.session.invalid", request.getContext().getName(),id));
                    }
                }
            }
        }
    }



}
TOP

Related Classes of org.apache.catalina.cluster.tcp.ReplicationValve

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.