# Class ReplicationValve

java.lang.Object
org.apache.catalina.util.LifecycleBase
org.apache.catalina.util.LifecycleMBeanBase
org.apache.catalina.valves.ValveBase
org.apache.catalina.ha.tcp.ReplicationValve

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

public class ReplicationValve extends ValveBase implements ClusterValve
Valve that triggers session replication across the cluster.

- ## Nested Class Summary

  ### Nested classes/interfaces inherited from interface Lifecycle

  `Lifecycle.SingleUse`

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected final ThreadLocal<ArrayList<DeltaSession>>`
  `crossContextSessions`
  crossContext session container
  `protected boolean`
  `doProcessingStats`
  doProcessingStats (default = off)
  `protected Pattern`
  `filter`
  Filter expression
  `protected AtomicLong`
  `lastSendTime`
  Total number of requests.
  `protected LongAdder`
  `nrOfCrossContextSendRequests`
  Number of cross-context requests sent for replication.
  `protected LongAdder`
  `nrOfFilterRequests`
  Number of requests filtered out.
  `protected LongAdder`
  `nrOfRequests`
  Number of requests.
  `protected LongAdder`
  `nrOfSendRequests`
  Number of requests sent for replication.
  `protected boolean`
  `primaryIndicator`
  Must set primary change indicator.
  `protected String`
  `primaryIndicatorName`
  Name of primary change indicator as request attribute
  `protected static final StringManager`
  `sm`
  The StringManager for this package.
  `protected LongAdder`
  `totalRequestTime`
  Total request time in nanoseconds.
  `protected LongAdder`
  `totalSendTime`
  Total send time in nanoseconds.

  ### Fields inherited from class ValveBase

  `asyncSupported, container, containerLog, next`

  ### Fields inherited from class LifecycleMBeanBase

  `mserver`

  ### Fields inherited from interface 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
  Description
  `ReplicationValve()`
  Default constructor.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `protected void`
  `createPrimaryIndicator(Request request)`
  Mark Request that processed at primary node with attribute primaryIndicatorName
  `boolean`
  `doStatistics()`
  Calc processing stats
  `CatalinaCluster`
  `getCluster()`
  Returns the cluster the valve is associated with
  `String`
  `getFilter()`
  Return the replication filter pattern as a string.
  `long`
  `getLastSendTime()`
  Return the last send time.
  `long`
  `getNrOfCrossContextSendRequests()`
  Return the number of cross-context send requests.
  `long`
  `getNrOfFilterRequests()`
  Return the number of filtered requests.
  `long`
  `getNrOfRequests()`
  Return the number of requests.
  `long`
  `getNrOfSendRequests()`
  Return the number of send requests.
  `String`
  `getPrimaryIndicatorName()`
  Return the primary indicator name.
  `long`
  `getTotalRequestTime()`
  Return the total request time.
  `long`
  `getTotalSendTime()`
  Return the total send time.
  `void`
  `invoke(Request request, Response response)`
  Perform request processing as required by this Valve.
  `boolean`
  `isPrimaryIndicator()`
  Return whether the primary indicator is enabled.
  `protected boolean`
  `isRequestWithoutSessionChange(String uri)`
  is request without possible session change
  `void`
  `registerReplicationSession(DeltaSession session)`
  Register all cross context sessions inside endAccess.
  `protected void`
  `resetDeltaRequest(Session session)`
  Reset DeltaRequest from session
  `protected void`
  `resetReplicationRequest(Request request, boolean isCrossContext)`
  Fix memory leak for long sessions with many changes, when no backup member exists!
  `void`
  `resetStatistics()`
  reset the active statistics
  `protected void`
  `send(ClusterManager manager, String sessionId)`
  send manager requestCompleted message to cluster
  `protected void`
  `sendCrossContextSession()`
  Send all changed cross context sessions to backups
  `protected void`
  `sendInvalidSessions(ClusterManager manager)`
  check for session invalidations
  `protected void`
  `sendMessage(Session session, ClusterManager manager)`
  Send message delta message from request session
  `protected void`
  `sendReplicationMessage(Request request, long totalstart, boolean isCrossContext, boolean isAsync, ClusterManager clusterManager)`
  Send a replication message for the given request.
  `protected void`
  `sendSessionReplicationMessage(Request request, ClusterManager manager)`
  Send Cluster Replication Request
  `void`
  `setCluster(CatalinaCluster cluster)`
  Associates the cluster valve with a cluster
  `void`
  `setFilter(String filter)`
  compile filter string to regular expression
  `void`
  `setPrimaryIndicator(boolean primaryIndicator)`
  Set whether the primary indicator is enabled.
  `void`
  `setPrimaryIndicatorName(String primaryIndicatorName)`
  Set the primary indicator name.
  `void`
  `setStatistics(boolean doProcessingStats)`
  Set Calc processing stats
  `protected void`
  `startInternal()`
  Start this component and implement the requirements of `LifecycleBase.startInternal()`.
  `protected void`
  `updateStats(long requestTime, long clusterTime, boolean isAsync)`
  Protocol cluster replications stats

  ### Methods inherited from class ValveBase

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

  ### Methods inherited from class LifecycleMBeanBase

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

  ### Methods inherited from class LifecycleBase

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

  ### Methods inherited from class Object

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

  ### Methods inherited from interface Valve

  `backgroundProcess, getNext, isAsyncSupported, setNext`

- ## Field Details

  - ### sm

    protected static final StringManager sm
    The StringManager for this package.

  - ### filter

    protected Pattern filter
    Filter expression

  - ### crossContextSessions

    protected final ThreadLocal<ArrayList<DeltaSession>> crossContextSessions
    crossContext session container

  - ### doProcessingStats

    protected boolean doProcessingStats
    doProcessingStats (default = off)

  - ### totalRequestTime

    protected LongAdder totalRequestTime
    Total request time in nanoseconds.

  - ### totalSendTime

    protected LongAdder totalSendTime
    Total send time in nanoseconds.

  - ### lastSendTime

    protected AtomicLong lastSendTime
    Total number of requests.

  - ### nrOfFilterRequests

    protected LongAdder nrOfFilterRequests
    Number of requests filtered out.

  - ### nrOfSendRequests

    protected LongAdder nrOfSendRequests
    Number of requests sent for replication.

  - ### nrOfCrossContextSendRequests

    protected LongAdder nrOfCrossContextSendRequests
    Number of cross-context requests sent for replication.

  - ### nrOfRequests

    protected LongAdder nrOfRequests
    Number of requests.

  - ### primaryIndicator

    protected boolean primaryIndicator
    Must set primary change indicator.

  - ### primaryIndicatorName

    protected String primaryIndicatorName
    Name of primary change indicator as request attribute

- ## Constructor Details

  - ### ReplicationValve

    public ReplicationValve()
    Default constructor.

- ## Method Details

  - ### getCluster

    public CatalinaCluster getCluster()
    Description copied from interface: `ClusterValve`
    Returns the cluster the valve is associated with
    Specified by:
      `getCluster` in interface `ClusterValve`
    Returns:
      the cluster.

  - ### setCluster

    public void setCluster(CatalinaCluster cluster)
    Description copied from interface: `ClusterValve`
    Associates the cluster valve with a cluster
    Specified by:
      `setCluster` in interface `ClusterValve`
    Parameters:
      `cluster` - The cluster to set.

  - ### getFilter

    public String getFilter()
    Return the replication filter pattern as a string.
    Returns:
      the filter pattern, or `null` if not set

  - ### setFilter

    public void setFilter(String filter)
    compile filter string to regular expression
    Parameters:
      `filter` - The filter to set.
    See Also:
      - `Pattern.compile(String)`

  - ### isPrimaryIndicator

    public boolean isPrimaryIndicator()
    Return whether the primary indicator is enabled.
    Returns:
      `true` if the primary indicator is enabled

  - ### setPrimaryIndicator

    public void setPrimaryIndicator(boolean primaryIndicator)
    Set whether the primary indicator is enabled.
    Parameters:
      `primaryIndicator` - `true` to enable the primary indicator

  - ### getPrimaryIndicatorName

    public String getPrimaryIndicatorName()
    Return the primary indicator name.
    Returns:
      the primary indicator name

  - ### setPrimaryIndicatorName

    public void setPrimaryIndicatorName(String primaryIndicatorName)
    Set the primary indicator name.
    Parameters:
      `primaryIndicatorName` - the primary indicator name

  - ### doStatistics

    public boolean doStatistics()
    Calc processing stats
    Returns:
      `true` if statistics are enabled

  - ### setStatistics

    public void setStatistics(boolean doProcessingStats)
    Set Calc processing stats
    Parameters:
      `doProcessingStats` - New flag value
    See Also:
      - `resetStatistics()`

  - ### getLastSendTime

    public long getLastSendTime()
    Return the last send time.
    Returns:
      the last send time

  - ### getNrOfRequests

    public long getNrOfRequests()
    Return the number of requests.
    Returns:
      the number of requests

  - ### getNrOfFilterRequests

    public long getNrOfFilterRequests()
    Return the number of filtered requests.
    Returns:
      the number of filtered requests

  - ### getNrOfCrossContextSendRequests

    public long getNrOfCrossContextSendRequests()
    Return the number of cross-context send requests.
    Returns:
      the number of cross-context send requests

  - ### getNrOfSendRequests

    public long getNrOfSendRequests()
    Return the number of send requests.
    Returns:
      the number of send requests

  - ### getTotalRequestTime

    public long getTotalRequestTime()
    Return the total request time.
    Returns:
      the total request time

  - ### getTotalSendTime

    public long getTotalSendTime()
    Return the total send time.
    Returns:
      the total send time

  - ### registerReplicationSession

    public void registerReplicationSession(DeltaSession session)
    Register all cross context sessions inside endAccess. Use a list with contains check, that the Portlet API can include a lot of fragments from same or different applications with session changes.
    Parameters:
      `session` - cross context session

  - ### invoke

    public void invoke(Request request, Response response) throws IOException, ServletException
    Description copied from interface: `Valve`

    Perform request processing as required by this Valve.

    An individual Valve MAY perform the following actions, in the specified order:

    - Examine and/or modify the properties of the specified Request and Response.
    - Examine the properties of the specified Request, completely generate the corresponding Response, and return control to the caller.
    - Examine the properties of the specified Request and Response, wrap either or both of these objects to supplement their functionality, and pass them on.
    - If the corresponding Response was not generated (and control was not returned), call the next Valve in the pipeline (if there is one) by executing `getNext().invoke()`.
    - Examine, but not modify, the properties of the resulting Response (which was created by a subsequently invoked Valve or Container).

    A Valve MUST NOT do any of the following things:

    - Change request properties that have already been used to direct the flow of processing control for this request (for instance, trying to change the virtual host to which a Request should be sent from a pipeline attached to a Host or Context in the standard implementation).
    - Create a completed Response AND pass this Request and Response on to the next Valve in the pipeline.
    - Consume bytes from the input stream associated with the Request, unless it is completely generating the response, or wrapping the request before passing it on.
    - Modify the HTTP headers included with the Response after the `getNext().invoke()` method has returned.
    - Perform any actions on the output stream associated with the specified Response after the `getNext().invoke()` method has returned.
    Specified by:
      `invoke` in interface `Valve`
    Parameters:
      `request` - The servlet request to be processed
      `response` - The servlet response to be created
    Throws:
      `IOException` - if an input/output error occurs, or is thrown by a subsequently invoked Valve, Filter, or Servlet
      `ServletException` - if a servlet error occurs, or is thrown by a subsequently invoked Valve, Filter, or Servlet

  - ### resetStatistics

    public void resetStatistics()
    reset the active statistics

  - ### startInternal

    protected void startInternal() throws LifecycleException
    Description copied from class: `ValveBase`
    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

  - ### sendReplicationMessage

    protected void sendReplicationMessage(Request request, long totalstart, boolean isCrossContext, boolean isAsync, ClusterManager clusterManager)
    Send a replication message for the given request.
    Parameters:
      `request` - the request
      `totalstart` - the start time
      `isCrossContext` - `true` if cross-context
      `isAsync` - `true` if async
      `clusterManager` - the cluster manager

  - ### sendCrossContextSession

    protected void sendCrossContextSession()
    Send all changed cross context sessions to backups

  - ### resetReplicationRequest

    protected void resetReplicationRequest(Request request, boolean isCrossContext)
    Fix memory leak for long sessions with many changes, when no backup member exists!
    Parameters:
      `request` - current request after response is generated
      `isCrossContext` - check crosscontext threadlocal

  - ### resetDeltaRequest

    protected void resetDeltaRequest(Session session)
    Reset DeltaRequest from session
    Parameters:
      `session` - HttpSession from current request or cross context session

  - ### sendSessionReplicationMessage

    protected void sendSessionReplicationMessage(Request request, ClusterManager manager)
    Send Cluster Replication Request
    Parameters:
      `request` - current request
      `manager` - session manager

  - ### sendMessage

    protected void sendMessage(Session session, ClusterManager manager)
    Send message delta message from request session
    Parameters:
      `session` - current session
      `manager` - session manager

  - ### send

    protected void send(ClusterManager manager, String sessionId)
    send manager requestCompleted message to cluster
    Parameters:
      `manager` - SessionManager
      `sessionId` - sessionid from the manager
    See Also:
      - `DeltaManager.requestCompleted(String)`
      - `SimpleTcpCluster.send(ClusterMessage)`

  - ### sendInvalidSessions

    protected void sendInvalidSessions(ClusterManager manager)
    check for session invalidations
    Parameters:
      `manager` - Associated manager

  - ### isRequestWithoutSessionChange

    protected boolean isRequestWithoutSessionChange(String uri)
    is request without possible session change
    Parameters:
      `uri` - The request uri
    Returns:
      True if no session change

  - ### updateStats

    protected void updateStats(long requestTime, long clusterTime, boolean isAsync)
    Protocol cluster replications stats
    Parameters:
      `requestTime` - Request time
      `clusterTime` - Cluster time
      `isAsync` - if the request was in async mode

  - ### createPrimaryIndicator

    protected void createPrimaryIndicator(Request request) throws IOException
    Mark Request that processed at primary node with attribute primaryIndicatorName
    Parameters:
      `request` - The Servlet request
    Throws:
      `IOException` - IO error finding session