# 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

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.

This Valve may be attached to any Container, depending on the granularity of the logging you wish to perform.

primaryIndicator=true, then the request attribute org.apache.catalina.ha.tcp.isPrimarySession. is set true, when request processing is at sessions primary node.

Author:
  Craig R. McClanahan, Peter Rossbach

- ## Nested Class Summary

  ### Nested classes/interfaces inherited from interface org.apache.catalina.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`
  `protected LongAdder`
  `nrOfCrossContextSendRequests`
  `protected LongAdder`
  `nrOfFilterRequests`
  `protected LongAdder`
  `nrOfRequests`
  `protected LongAdder`
  `nrOfSendRequests`
  `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`
  `protected LongAdder`
  `totalSendTime`

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

  `asyncSupported, container, containerLog, next`

  ### 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
  Description
  `ReplicationValve()`

- ## 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()`
  `long`
  `getLastSendTime()`
  `long`
  `getNrOfCrossContextSendRequests()`
  `long`
  `getNrOfFilterRequests()`
  `long`
  `getNrOfRequests()`
  `long`
  `getNrOfSendRequests()`
  `String`
  `getPrimaryIndicatorName()`
  `long`
  `getTotalRequestTime()`
  `long`
  `getTotalSendTime()`
  `void`
  `invoke(Request request, Response response)`
  Perform request processing as required by this Valve.
  `boolean`
  `isPrimaryIndicator()`
  `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)`
  `protected void`
  `sendSessionReplicationMessage(Request request, ClusterManager manager)`
  Send Cluster Replication Request
  `void`
  `setCluster(CatalinaCluster cluster)`
  Associates the cluster deployer with a cluster
  `void`
  `setFilter(String filter)`
  compile filter string to regular expression
  `void`
  `setPrimaryIndicator(boolean primaryIndicator)`
  `void`
  `setPrimaryIndicatorName(String primaryIndicatorName)`
  `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 org.apache.catalina.valves.ValveBase

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

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

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

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

  `addLifecycleListener, destroy, findLifecycleListeners, fireLifecycleEvent, getState, getStateName, getThrowOnFailure, init, removeLifecycleListener, setState, setState, setThrowOnFailure, 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, 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

  - ### totalSendTime

    protected LongAdder totalSendTime

  - ### nrOfRequests

    protected LongAdder nrOfRequests

  - ### lastSendTime

    protected AtomicLong lastSendTime

  - ### nrOfFilterRequests

    protected LongAdder nrOfFilterRequests

  - ### nrOfSendRequests

    protected LongAdder nrOfSendRequests

  - ### nrOfCrossContextSendRequests

    protected LongAdder nrOfCrossContextSendRequests

  - ### 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()

- ## 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 deployer with a cluster
    Specified by:
      `setCluster` in interface `ClusterValve`
    Parameters:
      `cluster` - The cluster to set.

  - ### getFilter

    public String getFilter()
    Returns:
      the filter

  - ### 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()
    Returns:
      the primaryIndicator.

  - ### setPrimaryIndicator

    public void setPrimaryIndicator(boolean primaryIndicator)
    Parameters:
      `primaryIndicator` - The primaryIndicator to set.

  - ### getPrimaryIndicatorName

    public String getPrimaryIndicatorName()
    Returns:
      the primaryIndicatorName.

  - ### setPrimaryIndicatorName

    public void setPrimaryIndicatorName(String primaryIndicatorName)
    Parameters:
      `primaryIndicatorName` - The primaryIndicatorName to set.

  - ### 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()
    Returns:
      the lastSendTime.

  - ### getNrOfRequests

    public long getNrOfRequests()
    Returns:
      the nrOfRequests.

  - ### getNrOfFilterRequests

    public long getNrOfFilterRequests()
    Returns:
      the nrOfFilterRequests.

  - ### getNrOfCrossContextSendRequests

    public long getNrOfCrossContextSendRequests()
    Returns:
      the nrOfCrossContextSendRequests.

  - ### getNrOfSendRequests

    public long getNrOfSendRequests()
    Returns:
      the nrOfSendRequests.

  - ### getTotalRequestTime

    public long getTotalRequestTime()
    Returns:
      the totalRequestTime.

  - ### getTotalSendTime

    public long getTotalSendTime()
    Returns:
      the totalSendTime.

  - ### 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)

  - ### 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