/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.ha.session;

import java.io.IOException;

import jakarta.servlet.ServletException;

import org.apache.catalina.Cluster;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Manager;
import org.apache.catalina.Session;
import org.apache.catalina.authenticator.Constants;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
import org.apache.catalina.ha.CatalinaCluster;
import org.apache.catalina.ha.ClusterManager;
import org.apache.catalina.ha.ClusterValve;
import org.apache.catalina.session.ManagerBase;
import org.apache.catalina.session.PersistentManager;
import org.apache.catalina.valves.ValveBase;
import org.apache.juli.logging.Log;
import org.apache.juli.logging.LogFactory;
import org.apache.tomcat.util.res.StringManager;

/**
 * Valve to handle Tomcat jvmRoute takeover using mod_jk module after node failure. After a node crashes, subsequent
 * requests go to other cluster nodes. That incurs a drop in performance. When this Valve is enabled on a backup node
 * and sees a request, which was intended for another (thus failed) node, it will rewrite the cookie jsessionid
 * information to use the route to this backup cluster node, that answered the request. After the response is delivered
 * to the client, all subsequent client requests will go directly to the backup node. The change of sessionid is also
 * sent to all other cluster nodes. After all that, the session stickiness will work directly to the backup node and the
 * traffic will not go back to the failed node after it is restarted!
 * <p>
 * Add this Valve to your cluster definition at conf/server.xml .
 *
 * <pre>
 *  &lt;Cluster&gt;
 *  &lt;Valve className=&quot;org.apache.catalina.ha.session.JvmRouteBinderValve&quot; /&gt;
 *  &lt;/Cluster&gt;
 * </pre>
 *
 * <em>A Trick:</em><br>
 * You can enable this mod_jk turnover mode via JMX before you drop a node to all backup nodes! Set enable true on all
 * JvmRouteBinderValve backups, disable worker at mod_jk and then drop node and restart it! Then enable mod_jk worker
 * and disable JvmRouteBinderValves again. This use case means that only requested sessions are migrated.
 */
public class JvmRouteBinderValve extends ValveBase implements ClusterValve {

    /*--Static Variables----------------------------------------*/
    public static final Log log = LogFactory.getLog(JvmRouteBinderValve.class);

    // ------------------------------------------------------ Constructor
    public JvmRouteBinderValve() {
        super(true);
    }

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

    /**
     * the cluster
     */
    protected CatalinaCluster cluster;

    /**
     * The string manager for this package.
     */
    protected static final StringManager sm = StringManager.getManager(JvmRouteBinderValve.class);

    /**
     * enabled this component
     */
    protected boolean enabled = true;

    /**
     * number of session that no at this tomcat instance hosted
     */
    protected long numberOfSessions = 0;

    protected String sessionIdAttribute = "org.apache.catalina.ha.session.JvmRouteOriginalSessionID";


    /*--Logic---------------------------------------------------*/

    /**
     * set session id attribute to failed node for request.
     *
     * @return Returns the sessionIdAttribute.
     */
    public String getSessionIdAttribute() {
        return sessionIdAttribute;
    }

    /**
     * get name of failed request session attribute
     *
     * @param sessionIdAttribute The sessionIdAttribute to set.
     */
    public void setSessionIdAttribute(String sessionIdAttribute) {
        this.sessionIdAttribute = sessionIdAttribute;
    }

    /**
     * @return Returns the number of migrated sessions.
     */
    public long getNumberOfSessions() {
        return numberOfSessions;
    }

    /**
     * @return Returns the enabled.
     */
    public boolean getEnabled() {
        return enabled;
    }

    /**
     * @param enabled The enabled to set.
     */
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * Detect possible the JVMRoute change at cluster backup node.
     *
     * @param request  tomcat request being processed
     * @param response tomcat response being processed
     *
     * @exception IOException      if an input/output error has occurred
     * @exception ServletException if a servlet error has occurred
     */
    @Override
    public void invoke(Request request, Response response) throws IOException, ServletException {

        if (getEnabled() && request.getContext() != null && request.getContext().getDistributable() &&
                !request.isAsyncDispatching()) {
            // valve cluster can access manager - other cluster handle turnover
            // at host level - hopefully!
            Manager manager = request.getContext().getManager();

            if (manager != null && ((manager instanceof ClusterManager && getCluster() != null &&
                    getCluster().getManager(((ClusterManager) manager).getName()) != null) ||
                    (manager instanceof PersistentManager))) {
                handlePossibleTurnover(request);
            }
        }
        // Pass this request on to the next valve in our pipeline
        getNext().invoke(request, response);
    }

    /**
     * handle possible session turn over.
     *
     * @see JvmRouteBinderValve#handleJvmRoute(Request, String, String)
     *
     * @param request current request
     */
    protected void handlePossibleTurnover(Request request) {
        String sessionID = request.getRequestedSessionId();
        if (sessionID != null) {
            long t1 = System.currentTimeMillis();
            String jvmRoute = getLocalJvmRoute(request);
            if (jvmRoute == null) {
                if (log.isDebugEnabled()) {
                    log.debug(sm.getString("jvmRoute.missingJvmRouteAttribute"));
                }
                return;
            }
            handleJvmRoute(request, sessionID, jvmRoute);
            if (log.isTraceEnabled()) {
                long t2 = System.currentTimeMillis();
                long time = t2 - t1;
                log.trace(sm.getString("jvmRoute.turnoverInfo", Long.valueOf(time)));
            }
        }
    }

    /**
     * get jvmroute from engine
     *
     * @param request current request
     *
     * @return return jvmRoute from ManagerBase or null
     */
    protected String getLocalJvmRoute(Request request) {
        Manager manager = getManager(request);
        if (manager instanceof ManagerBase) {
            return ((ManagerBase) manager).getJvmRoute();
        }
        return null;
    }

    /**
     * get ClusterManager
     *
     * @param request current request
     *
     * @return manager or null
     */
    protected Manager getManager(Request request) {
        Manager manager = request.getContext().getManager();
        if (log.isDebugEnabled()) {
            if (manager != null) {
                log.trace(sm.getString("jvmRoute.foundManager", manager, request.getContext().getName()));
            } else {
                log.debug(sm.getString("jvmRoute.notFoundManager", request.getContext().getName()));
            }
        }
        return manager;
    }

    @Override
    public CatalinaCluster getCluster() {
        return cluster;
    }

    @Override
    public void setCluster(CatalinaCluster cluster) {
        this.cluster = cluster;
    }

    /**
     * Handle jvmRoute stickiness after tomcat instance failed. After this correction a new Cookie send to client with
     * new jvmRoute and the SessionID change propagate to the other cluster nodes.
     *
     * @param request       current request
     * @param sessionId     request SessionID from Cookie
     * @param localJvmRoute local jvmRoute
     */
    protected void handleJvmRoute(Request request, String sessionId, String localJvmRoute) {
        // get requested jvmRoute.
        String requestJvmRoute = null;
        int index = sessionId.indexOf('.');
        if (index > 0) {
            requestJvmRoute = sessionId.substring(index + 1);
        }
        if (requestJvmRoute != null && !requestJvmRoute.equals(localJvmRoute)) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("jvmRoute.failover", requestJvmRoute, localJvmRoute, sessionId));
            }
            Session catalinaSession = null;
            try {
                catalinaSession = getManager(request).findSession(sessionId);
            } catch (IOException ignore) {
                // Error looking for session using old session ID. Treat it as not found.
            }
            String id = sessionId.substring(0, index);
            String newSessionID = id + "." + localJvmRoute;
            // OK - turnover the session and inform other cluster nodes
            if (catalinaSession != null) {
                changeSessionID(request, sessionId, newSessionID, catalinaSession);
                numberOfSessions++;
            } else {
                try {
                    catalinaSession = getManager(request).findSession(newSessionID);
                } catch (IOException ignore) {
                    // Error looking for session using new session ID. Treat it as not found.
                }
                if (catalinaSession != null) {
                    // Session was rewritten in other, concurrent request. Rewrite this request also.
                    changeRequestSessionID(request, sessionId, newSessionID);
                } else {
                    if (log.isDebugEnabled()) {
                        log.debug(sm.getString("jvmRoute.cannotFindSession", sessionId));
                    }
                }
            }
        }
    }

    /**
     * change session id and send to all cluster nodes
     *
     * @param request         current request
     * @param sessionId       original session id
     * @param newSessionID    new session id for node migration
     * @param catalinaSession current session with original session id
     */
    protected void changeSessionID(Request request, String sessionId, String newSessionID, Session catalinaSession) {
        fireLifecycleEvent("Before session migration", catalinaSession);
        getManager(request).changeSessionId(catalinaSession, newSessionID);
        changeRequestSessionID(request, sessionId, newSessionID);
        changeSessionAuthenticationNote(sessionId, newSessionID, catalinaSession);
        fireLifecycleEvent("After session migration", catalinaSession);
        if (log.isDebugEnabled()) {
            log.debug(sm.getString("jvmRoute.changeSession", sessionId, newSessionID));
        }
    }

    /**
     * Change Request Session id
     *
     * @param request      current request
     * @param sessionId    original session id
     * @param newSessionID new session id for node migration
     */
    protected void changeRequestSessionID(Request request, String sessionId, String newSessionID) {
        request.changeSessionId(newSessionID);

        // set original sessionid at request, to allow application detect the
        // change
        if (sessionIdAttribute != null && !sessionIdAttribute.isEmpty()) {
            if (log.isDebugEnabled()) {
                log.debug(sm.getString("jvmRoute.set.originalsessionid", sessionIdAttribute, sessionId));
            }
            request.setAttribute(sessionIdAttribute, sessionId);
        }
    }


    /**
     * Change the current session ID that is stored in a session note during authentication. It is part of the CSRF
     * protection.
     *
     * @param sessionId       The original session ID
     * @param newSessionID    The new session ID for node migration
     * @param catalinaSession The session object (that will be using the new session ID at the point this method is
     *                            called)
     */
    protected void changeSessionAuthenticationNote(String sessionId, String newSessionID, Session catalinaSession) {
        if (sessionId.equals(catalinaSession.getNote(Constants.SESSION_ID_NOTE))) {
            catalinaSession.setNote(Constants.SESSION_ID_NOTE, newSessionID);
        }
    }


    /**
     * Start this component and implement the requirements of
     * {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
     *
     * @exception LifecycleException if this component detects a fatal error that prevents this component from being
     *                                   used
     */
    @Override
    protected void startInternal() throws LifecycleException {

        if (cluster == null) {
            Cluster containerCluster = getContainer().getCluster();
            if (containerCluster instanceof CatalinaCluster) {
                setCluster((CatalinaCluster) containerCluster);
            }
        }

        if (log.isInfoEnabled()) {
            log.info(sm.getString("jvmRoute.valve.started"));
            if (cluster == null) {
                log.info(sm.getString("jvmRoute.noCluster"));
            }
        }

        super.startInternal();
    }


    /**
     * Stop this component and implement the requirements of
     * {@link org.apache.catalina.util.LifecycleBase#stopInternal()}.
     *
     * @exception LifecycleException if this component detects a fatal error that prevents this component from being
     *                                   used
     */
    @Override
    protected void stopInternal() throws LifecycleException {

        super.stopInternal();

        cluster = null;
        numberOfSessions = 0;
        if (log.isInfoEnabled()) {
            log.info(sm.getString("jvmRoute.valve.stopped"));
        }

    }

}
