org.apache.catalina.ha.session

## Class JvmRouteBinderValve

- java.lang.Object
- - org.apache.catalina.util.LifecycleBase
  - - org.apache.catalina.util.LifecycleMBeanBase
    - - org.apache.catalina.valves.ValveBase
      - - org.apache.catalina.ha.session.JvmRouteBinderValve

All Implemented Interfaces:
  MBeanRegistration, Contained, ClusterValve, Lifecycle, Valve

    public class JvmRouteBinderValve
    extends ValveBase
    implements ClusterValve

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!

For this valve to function correctly, so that all nodes of the cluster receive the sessionid change notifications that it generates, the following ClusterListener MUST be configured at all nodes of the cluster: `JvmRouteSessionIDBinderListener` since Tomcat 5.5.10, and both JvmRouteSessionIDBinderListener and JvmRouteSessionIDBinderLifecycleListener for earlier versions of Tomcat.

Add this Valve to your host definition at conf/server.xml . Since 5.5.10 as direct cluster valve:

      <Cluster>
      <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" />
      </Cluster>

Before 5.5.10 as Host element:

      <Host>
      <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve" />
      </Host>

A Trick:
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.

Author:
  Peter Rossbach

### Field Summary

Fields
`protected CatalinaCluster` `cluster` the cluster
`protected boolean` `enabled` enabled this component
`protected static String` `info` The descriptive information about this implementation.
`static Log` `log`
`protected long` `numberOfSessions` number of session that no at this tomcat instanz hosted
`protected String` `sessionIdAttribute`
`protected static StringManager` `sm` The string manager for this package.

### Fields inherited from class org.apache.catalina.valves.ValveBase

`asyncSupported, container, containerLog, next`

### Fields inherited from class org.apache.catalina.util.LifecycleMBeanBase

`mserver`

### Fields inherited from interface org.apache.catalina.Lifecycle

`AFTER_DESTROY_EVENT, AFTER_INIT_EVENT, AFTER_START_EVENT, AFTER_STOP_EVENT, BEFORE_DESTROY_EVENT, BEFORE_INIT_EVENT, BEFORE_START_EVENT, BEFORE_STOP_EVENT, CONFIGURE_START_EVENT, CONFIGURE_STOP_EVENT, PERIODIC_EVENT, START_EVENT, STOP_EVENT`

### Constructor Summary

Constructors
Constructor and Description
`JvmRouteBinderValve()`

### Method Summary

Methods
`protected void` `changeRequestSessionID(Request request, String sessionId, String newSessionID)` Change Request Session id
`protected void` `changeSessionID(Request request, String sessionId, String newSessionID, Session catalinaSession)` change session id and send to all cluster nodes
`CatalinaCluster` `getCluster()` Returns the cluster the cluster deployer is associated with
`boolean` `getEnabled()`
`String` `getInfo()` Return descriptive information about this implementation.
`protected String` `getLocalJvmRoute(Request request)` get jvmroute from engine
`protected Manager` `getManager(Request request)` get Cluster DeltaManager
`long` `getNumberOfSessions()`
`String` `getSessionIdAttribute()` set session id attribute to failed node for request.
`protected void` `handleJvmRoute(Request request, String sessionId, String localJvmRoute)` Handle jvmRoute stickiness after tomcat instance failed.
`protected void` `handlePossibleTurnover(Request request)` handle possible session turn over.
`void` `invoke(Request request, Response response)` Detect possible the JVMRoute change at cluster backup node..
`protected void` `sendSessionIDClusterBackup(Request request, String sessionId, String newSessionID)` Send the changed Sessionid to all clusternodes.
`void` `setCluster(CatalinaCluster cluster)` Associates the cluster deployer with a cluster
`void` `setEnabled(boolean enabled)`
`void` `setSessionIdAttribute(String sessionIdAttribute)` get name of failed request session attribute
`protected void` `startInternal()` Start this component and implement the requirements of `LifecycleBase.startInternal()`.
`protected void` `stopInternal()` Stop this component and implement the requirements of `LifecycleBase.stopInternal()`.

### Methods inherited from class org.apache.catalina.valves.ValveBase

`backgroundProcess, event, getContainer, getDomainInternal, getNext, getObjectNameKeyProperties, initInternal, isAsyncSupported, setAsyncSupported, setContainer, setNext, toString`

### Methods inherited from class org.apache.catalina.util.LifecycleMBeanBase

`destroyInternal, getDomain, getObjectName, postDeregister, postRegister, preDeregister, preRegister, register, setDomain, unregister`

### Methods inherited from class org.apache.catalina.util.LifecycleBase

`addLifecycleListener, destroy, findLifecycleListeners, fireLifecycleEvent, getState, getStateName, init, removeLifecycleListener, setState, setState, start, stop`

### Methods inherited from class java.lang.Object

`clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

### Methods inherited from interface org.apache.catalina.Valve

`backgroundProcess, event, getNext, isAsyncSupported, setNext`

### Field Detail

#### log

    public static final Log log

#### info

    protected static final String info

The descriptive information about this implementation.

See Also:
  Constant Field Values

#### cluster

    protected CatalinaCluster cluster

the cluster

#### sm

    protected static final StringManager sm

The string manager for this package.

#### enabled

    protected boolean enabled

enabled this component

#### numberOfSessions

    protected long numberOfSessions

number of session that no at this tomcat instanz hosted

#### sessionIdAttribute

    protected String sessionIdAttribute

### Constructor Detail

#### JvmRouteBinderValve

    public JvmRouteBinderValve()

### Method Detail

#### getInfo

    public String getInfo()

Return descriptive information about this implementation.

Specified by:
  `getInfo` in interface `Valve`
Overrides:
  `getInfo` in class `ValveBase`

#### getSessionIdAttribute

    public String getSessionIdAttribute()

set session id attribute to failed node for request.

Returns:
  Returns the sessionIdAttribute.

#### setSessionIdAttribute

    public void setSessionIdAttribute(String sessionIdAttribute)

get name of failed request session attribute

Parameters:
  `sessionIdAttribute` - The sessionIdAttribute to set.

#### getNumberOfSessions

    public long getNumberOfSessions()

Returns:
  Returns the number of migrated sessions.

#### getEnabled

    public boolean getEnabled()

Returns:
  Returns the enabled.

#### setEnabled

    public void setEnabled(boolean enabled)

Parameters:
  `enabled` - The enabled to set.

#### invoke

    public void invoke(Request request,
              Response response)
                throws IOException,
                       ServletException

Detect possible the JVMRoute change at cluster backup node..

Specified by:
  `invoke` in interface `Valve`
Specified by:
  `invoke` in class `ValveBase`
Parameters:
  `request` - tomcat request being processed
  `response` - tomcat response being processed
Throws:
  `IOException` - if an input/output error has occurred
  `ServletException` - if a servlet error has occurred

#### handlePossibleTurnover

    protected void handlePossibleTurnover(Request request)

handle possible session turn over.

Parameters:
  `request` - current request
See Also:
  `handleJvmRoute(Request, String, String)`

#### getLocalJvmRoute

    protected String getLocalJvmRoute(Request request)

get jvmroute from engine

Parameters:
  `request` - current request
Returns:
  return jvmRoute from ManagerBase or null

#### getManager

    protected Manager getManager(Request request)

get Cluster DeltaManager

Parameters:
  `request` - current request
Returns:
  manager or null

#### getCluster

    public CatalinaCluster getCluster()

Description copied from interface: `ClusterValve`
Returns the cluster the cluster deployer is associated with

Specified by:
  `getCluster` in interface `ClusterValve`
Returns:
  Returns the cluster.

#### setCluster

    public void setCluster(CatalinaCluster cluster)

Description copied from interface: `ClusterValve`
Associates the cluster deployer with a cluster

Specified by:
  `setCluster` in interface `ClusterValve`
Parameters:
  `cluster` - The cluster to set.

#### handleJvmRoute

    protected void handleJvmRoute(Request request,
                      String sessionId,
                      String localJvmRoute)

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.

Parameters:
  `request` - current request
  `sessionId` - request SessionID from Cookie
  `localJvmRoute` - local jvmRoute

#### changeSessionID

    protected void changeSessionID(Request request,
                       String sessionId,
                       String newSessionID,
                       Session catalinaSession)

change session id and send to all cluster nodes

Parameters:
  `request` - current request
  `sessionId` - original session id
  `newSessionID` - new session id for node migration
  `catalinaSession` - current session with original session id

#### changeRequestSessionID

    protected void changeRequestSessionID(Request request,
                              String sessionId,
                              String newSessionID)

Change Request Session id

Parameters:
  `request` - current request
  `sessionId` - original session id
  `newSessionID` - new session id for node migration

#### sendSessionIDClusterBackup

    protected void sendSessionIDClusterBackup(Request request,
                                  String sessionId,
                                  String newSessionID)

Send the changed Sessionid to all clusternodes.

Parameters:
  `sessionId` - current failed sessionid
  `newSessionID` - new session id, bind to the new cluster node
See Also:
  `JvmRouteSessionIDBinderListener.messageReceived( org.apache.catalina.ha.ClusterMessage)`

#### startInternal

    protected void startInternal()
                          throws LifecycleException

Start this component and implement the requirements of `LifecycleBase.startInternal()`.

Overrides:
  `startInternal` in class `ValveBase`
Throws:
  `LifecycleException` - if this component detects a fatal error that prevents this component from being used

#### stopInternal

    protected void stopInternal()
                         throws LifecycleException

Stop this component and implement the requirements of `LifecycleBase.stopInternal()`.

Overrides:
  `stopInternal` in class `ValveBase`
Throws:
  `LifecycleException` - if this component detects a fatal error that prevents this component from being used