You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by rj...@apache.org on 2008/03/27 18:41:04 UTC
svn commit: r641922 - in /tomcat/sandbox/tomcat-oacc/trunk/docs: build.xml
changelog.xml index.xml oacc-howto.xml project.xml tomcat-oacc-docs.xsl
Author: rjung
Date: Thu Mar 27 10:40:59 2008
New Revision: 641922
URL: http://svn.apache.org/viewvc?rev=641922&view=rev
Log:
Add docs to OACC.
Added:
tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml (with props)
tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml (with props)
tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml (with props)
tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml (with props)
tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml (with props)
tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl (with props)
Added: tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml?rev=641922&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml (added)
+++ tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml Thu Mar 27 10:40:59 2008
@@ -0,0 +1,138 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ 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.
+-->
+<project name="tomcat-oacc-docs" default="build-main" basedir=".">
+
+
+ <!-- ===================== Initialize Property Values =================== -->
+
+ <!-- See "build.properties.sample" in the top level directory for all -->
+ <!-- property values you must customize for successful building!!! -->
+ <property file="build.properties"/>
+ <property file="../build.properties"/>
+ <property file="../build.properties.default"/>
+
+ <property name="build.compiler" value="modern"/>
+ <property name="docs.build" value="../build"/>
+ <property name="docs.dist" value="../dist"/>
+ <property name="docs.dir" value="docs"/>
+
+
+ <!-- =================== BUILD: Create Directories ====================== -->
+ <target name="build-prepare">
+ <mkdir dir="${docs.build}"/>
+ <mkdir dir="${docs.build}/${docs.dir}"/>
+ </target>
+
+
+ <!-- ================ BUILD: Copy Static Files ========================== -->
+ <target name="build-static" depends="build-prepare">
+
+ <!-- Top Level Static Files -->
+ <copy todir="${docs.build}/${docs.dir}">
+ <fileset dir="..">
+ <include name="RELEASE-NOTES"/>
+ <include name="RUNNING.txt"/>
+ <include name="BUILDING.txt"/>
+ </fileset>
+ </copy>
+ <copy todir="${docs.build}/${docs.dir}">
+ <fileset dir="." includes="**/*.html"/>
+ </copy>
+
+ <!-- Images Subdirectory -->
+ <mkdir dir="${docs.build}/${docs.dir}/images"/>
+ <copy todir="${docs.build}/${docs.dir}/images">
+ <fileset dir="images"/>
+ </copy>
+
+ <mkdir dir="${docs.build}/${docs.dir}/printer"/>
+ <!-- Top Level Static Files -->
+ <copy todir="${docs.build}/${docs.dir}/printer">
+ <fileset dir="..">
+ <include name="RELEASE-NOTES"/>
+ <include name="RUNNING.txt"/>
+ <include name="BUILDING.txt"/>
+ </fileset>
+ </copy>
+ <style basedir="."
+ destdir="${docs.build}/${docs.dir}/printer"
+ extension=".html"
+ style="tomcat-oacc-docs.xsl"
+ excludes="build.xml project.xml"
+ includes="*.xml">
+ <param name="relative-path" expression="./.."/>
+ <param name="project-menu" expression="nomenu"/>
+ </style>
+
+ </target>
+
+
+ <!-- ================= BUILD: XML-HTML Generation ======================= -->
+ <target name="build-main" depends="build-static">
+
+ <!-- Top Level Directory -->
+ <style basedir="."
+ destdir="${docs.build}/${docs.dir}"
+ extension=".html"
+ style="tomcat-oacc-docs.xsl"
+ excludes="build.xml project.xml"
+ includes="*.xml">
+ <param name="relative-path" expression="."/>
+ </style>
+
+ </target>
+
+
+ <!-- ==================== BUILD: Rebuild Everything ===================== -->
+ <target name="all" depends="build-clean,build-main"
+ description="Clean and build documentation webapp"/>
+
+
+ <!-- ======================= BUILD: Clean Directory ===================== -->
+ <target name="build-clean">
+ <delete dir="${docs.build}/${docs.dir}"/>
+ </target>
+
+
+ <!-- ======================= DIST: Create Directories =================== -->
+ <target name="dist-prepare">
+ <mkdir dir="${docs.dist}"/>
+ </target>
+
+
+ <!-- ======================= DIST: Create Distribution Files ============ -->
+ <target name="dist" depends="build-main,dist-prepare"
+ description="Create documentation webapp binary distribution">
+ <mkdir dir="${docs.dist}/${docs.dir}"/>
+ <copy todir="${docs.dist}/${docs.dir}">
+ <fileset dir="${docs.build}/${docs.dir}"/>
+ </copy>
+ </target>
+
+
+ <!-- ======================= DIST: Clean Directory ====================== -->
+ <target name="dist-clean">
+ <delete dir="${docs.dist}/${docs.dir}"/>
+ </target>
+
+
+ <!-- ====================== Convenient Synonyms ========================= -->
+ <target name="clean" depends="build-clean,dist-clean"
+ description="Clean build and dist directories"/>
+
+</project>
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/build.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml?rev=641922&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml (added)
+++ tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml Thu Mar 27 10:40:59 2008
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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.
+-->
+<!DOCTYPE document [
+ <!ENTITY project SYSTEM "project.xml">
+]>
+<document url="changelog.html">
+
+ &project;
+
+ <properties>
+ <author email="rjung@apache.org">Rainer Jung</author>
+ <title>Changelog</title>
+ </properties>
+
+<body>
+<section name="Tomcat OACC 6.0.16 (rjung)">
+ <subsection name="Cluster">
+ <changelog>
+ <add>
+ Initial port of org.apache.catalina.cluster from Tomcat 5.5
+ to Tomcat 6.0 (rjung)
+ </add>
+ </changelog>
+ </subsection>
+ <subsection name="Docs">
+ <changelog>
+ <add>
+ Initial port of Tomcat 5.5 cluster docs to OACC (rjung)
+ </add>
+ </changelog>
+ </subsection>
+</section>
+</body>
+</document>
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/changelog.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml?rev=641922&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml (added)
+++ tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml Thu Mar 27 10:40:59 2008
@@ -0,0 +1,89 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<!DOCTYPE document [
+ <!ENTITY project SYSTEM "project.xml">
+]>
+<document url="index.html">
+
+ &project;
+
+ <properties>
+ <author email="craigmcc@apache.org">Craig R. McClanahan</author>
+ <author email="remm@apache.org">Remy Maucherat</author>
+ <author email="yoavs@apache.org">Yoav Shapira</author>
+ <author email="rjung@apache.org">Rainer Jung</author>
+ <title>Documentation Index</title>
+ </properties>
+
+<body>
+
+<section name="Introduction">
+
+<p>This is the top-level entry point of the documentation for
+<strong>Apache Tomcat</strong> OACC. Apache Tomcat OACC is is
+a port of the Tomcat 5.5 cluster module to Tomcat 6.</p>
+
+<p>Its purpose is to allow users of the Tomcat 5.5 cluster a two-step
+migration to Tomcat 6. We recommend all new cluster users to start with
+the default implementation of Tomcat 6 cluster automatically contained
+in any Tomcat 6 release. OACC is only an intermediary step and will not
+be actively developed any further.</p>
+
+<p>Select one of the links from the navigation menu (to the left) to drill
+down to the more detailed documentation that is available. Each available
+manual is described in more detail below.</p>
+
+</section>
+
+
+<section name="Apache Tomcat OACC Docs">
+
+<p>The following documents will assist you in downloading, installing,
+and configuring Apache Tomcat OACC.</p>
+
+<ul>
+<li><a href="RUNNING.txt"><strong>Installation</strong></a>
+ - How to add and run Apache Tomcat OACC to an existing Tomcat 6
+ installation.</li>
+<li><a href="oacc-howto.html"><strong>HowTo</strong></a>
+ - How to configure OACC.</li>
+<li><a href="RELEASE-NOTES"><strong>Release notes</strong></a>
+ - Known issues in this Apache Tomcat OACC release.</li>
+<li><a href="changelog.html"><strong>Changelog</strong></a>
+ - Details the changes made to Apache Tomcat OACC.</li>
+<li><a href="BUILDING.txt"><strong>Building from Source</strong></a>
+ - Details the steps necessary to download Apache Tomcat OACC source code,
+ and build a binary distribution from those sources.</li>
+</ul>
+
+</section>
+
+<section name="Links">
+
+<p>The following are links to related documentation pages on the web.</p>
+<ul>
+<li><a href="http://tomcat.apache.org/tomcat-6.0-doc/"><strong>Apache Tomcat 6.0 Documentation</strong></a></li>
+<li><a href="http://tomcat.apache.org/connectros-doc/"><strong>JK Documentation (includes load balancing)</strong></a></li>
+<li><a href="http://tomcat.apache.org/faq/"><strong>Apache Tomcat FAQ</strong></a></li>
+</ul>
+
+</section>
+
+
+</body>
+</document>
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/index.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml?rev=641922&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml (added)
+++ tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml Thu Mar 27 10:40:59 2008
@@ -0,0 +1,1161 @@
+<?xml version="1.0"?>
+<!--
+ 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.
+-->
+<!DOCTYPE document [
+ <!ENTITY project SYSTEM "project.xml">
+]>
+<document url="oacc-howto.html">
+
+ &project;
+
+ <properties>
+ <author email="fhanik@apache.org">Filip Hanik</author>
+ <author email="pero@apache.org">Peter Rossbach</author>
+ <author email="rjung@apache.org">Rainer Jung</author>
+ <title>OACC Clustering/Session Replication HOW-TO</title>
+ </properties>
+
+<body>
+
+
+<section name="Quick Start">
+
+<p>To run session replication in your Tomcat 6 container, the following steps
+should be completed:</p>
+<ul>
+<li>All your session attributes must implement <code>java.io.Serializable</code></li>
+<li>Uncomment the <code>Cluster</code> element in server.xml</li>
+<li>Uncomment the <code>Valve(ReplicationValve)</code> element in server.xml</li>
+<li>If your Tomcat instances are running on the same machine, make sure the <code>tcpListenPort</code>
+ attribute is unique for each instance.</li>
+<li>Make sure your <code>web.xml</code> has the <code><distributable/></code> element
+ or set at your <code><Context distributable="true" /></code></li>
+<li>Make sure that jvmRoute attribute is set at your Engine <code><Engine name="Catalina" jvmRoute="node01" ></code></li>
+<li>Make sure that all nodes have the same time and sync with NTP service!</li>
+<li>Make sure that your loadbalancer is configured for sticky session mode.</li>
+</ul>
+<p>Load balancing can be achieved through many techniques, as seen in the
+<a href="http://tomcat.apache.org/tomcat-6.0-doc/balancer-howto.html">Load Balancing</a> document.</p>
+<p>Note: Remember that your session state is tracked by a cookie, so your URL must look the same from the out
+ side otherwise, a new session will be created.</p>
+</section>
+
+
+<section name="Overview">
+
+<p>To enable session replication in Tomcat, three different paths can be followed to achieve the exact same thing:</p>
+<ol>
+ <li>Using session persistence, and saving the session to a shared file system (PersistenceManager + FileStore)</li>
+ <li>Using session persistence, and saving the session to a shared database (PersistenceManager + JDBCStore)</li>
+ <li>Using in-memory-replication, using the SimpleTcpCluster that ships with Tomcat 5 (server/lib/catalina-cluster.jar)</li>
+</ol>
+
+<p>In this release of session replication, Tomcat performs an all-to-all replication of session state.
+
+ This is an algorithm that is only efficient when the clusters are small. For large clusters, the next
+ release will support a primary-secondary session replication where the session will only be stored at one
+ or maybe two backup servers.
+ Currently you can use the domain worker attribute (mod_jk > 1.2.8) to build cluster partitions
+ with the potential of very scaleable cluster solution.
+ In order to keep the network traffic down in an all-to-all environment, you can split your cluster
+ into smaller groups. This can be easily achieved by using different multicast addresses for the different groups.
+ A very simple setup would look like this:
+ </p>
+
+<source>
+ DNS Round Robin
+ |
+ Load Balancer
+ / \
+ Cluster1 Cluster2
+ / \ / \
+ Tomcat1 Tomcat2 Tomcat3 Tomcat4
+</source>
+
+<p>What is important to mention here, is that session replication is only the beginning of clustering.
+ Another popular concept used to implement clusters is farming, ie, you deploy your apps only to one
+ server, and the cluster will distribute the deployments across the entire cluster.
+ This is all capabilities that can go into with the FarmWarDeployer (s. cluster example at <code>server.xml</code>)</p>
+<p>In the next section will go deeper into how session replication works and how to configure it.</p>
+
+</section>
+
+<section name="How it Works">
+<p>To make it easy to understand how clustering works, We are gonna take you through a series of scenarios.
+ In the scenario we only plan to use two tomcat instances <code>TomcatA</code> and <code>TomcatB</code>.
+ We will cover the following sequence of events:</p>
+
+<ol>
+<li><code>TomcatA</code> starts up</li>
+<li><code>TomcatB</code> starts up (Wait that TomcatA start is complete)</li>
+<li><code>TomcatA</code> receives a request, a session <code>S1</code> is created.</li>
+<li><code>TomcatA</code> crashes</li>
+<li><code>TomcatB</code> receives a request for session <code>S1</code></li>
+<li><code>TomcatA</code> starts up</li>
+<li><code>TomcatA</code> receives a request, invalidate is called on the session (<code>S1</code>)</li>
+<li><code>TomcatB</code> receives a request, for a new session (<code>S2</code>)</li>
+<li><code>TomcatA</code> The session <code>S2</code> expires due to inactivity.</li>
+</ol>
+
+<p>Ok, now that we have a good sequence, we will take you through exactly what happens in the session repliction code</p>
+
+<ol>
+<li><b><code>TomcatA</code> starts up</b>
+ <p>
+ Tomcat starts up using the standard start up sequence. When the Host object is created, a cluster object is associated with it.
+ When the contexts are parsed, if the distributable element is in place in web.xml
+ Tomcat asks the Cluster class (in this case <code>SimpleTcpCluster</code>) to create a manager
+ for the replicated context. So with clustering enabled, distributable set in web.xml
+ Tomcat will create a <code>DeltaManager</code> for that context instead of a <code>StandardManager</code>.
+ The cluster class will start up a membership service (multicast) and a replication service (tcp unicast).
+ More on the architecture further down in this document.
+ </p><p></p>
+</li>
+<li><b><code>TomcatB</code> starts up</b>
+ <p>
+ When TomcatB starts up, it follows the same sequence as TomcatA did with one exception.
+ The cluster is started and will establish a membership (TomcatA,TomcatB).
+ TomcatB will now request the session state from a server that already exists in the cluster,
+ in this case TomcatA. TomcatA responds to the request, and before TomcatB starts listening
+ for HTTP requests, the state has been transferred from TomcatA to TomcatB.
+ In case TomcatA doesn't respond, TomcatB will time out after 60 seconds, and issue a log
+ entry. The session state gets transferred for each web application that has distributable in
+ its web.xml. Note: To use session replication efficiently, all your tomcat instances should be
+ configured the same.
+ </p><p></p>
+</li>
+<li><B><code>TomcatA</code> receives a request, a session <code>S1</code> is created.</B>
+ <p>
+ The request coming in to TomcatA is treated exactly the same way as without session replication.
+ The action happens when the request is completed, the <code>ReplicationValve</code> will intercept
+ the request before the response is returned to the user.
+ At this point it finds that the session has been modified, and it uses TCP to replicata the
+ session to TomcatB. Once the serialized data has been handed off to the operating systems TCP logic,
+ the request returns to the user, back through the valve pipeline.
+ For each request the entire session is replicated, this allows code that modifies attributes
+ in the session without calling setAttribute or removeAttribute to be replicated.
+ a useDirtyFlag configuration parameter can be used to optimize the number of times
+ a session is replicated.
+ </p><p></p>
+
+</li>
+<li><b><code>TomcatA</code> crashes</b>
+ <p>
+ When TomcatA crashes, TomcatB receives a notification that TomcatA has dropped out
+ of the cluster. TomcatB removes TomcatA from its membership list, and TomcatA will no longer
+ be notified of any changes that occurs in TomcatB.
+ The load balancer will redirect the requests from TomcatA to TomcatB and all the sessions
+ are current.
+ </p><p></p>
+</li>
+<li><b><code>TomcatB</code> receives a request for session <code>S1</code></b>
+ <p>Nothing exciting, TomcatB will process the request as any other request.
+ </p><p></p>
+</li>
+<li><b><code>TomcatA</code> starts up</b>
+ <p>Upon start up, before TomcatA starts taking new request and making itself
+ available to it will follow the start up sequence described above 1) 2).
+ It will join the cluster, contact TomcatB for the current state of all the sessions.
+ And once it receives the session state, it finishes loading and opens its HTTP/mod_jk ports.
+ So no requests will make it to TomcatA until it has received the session state from TomcatB.
+ </p><p></p>
+</li>
+<li><b><code>TomcatA</code> receives a request, invalidate is called on the session (<code>S1</code>)</b>
+ <p>The invalidate is call is intercepted, and the session is queued with invalidated sessions.
+ When the request is complete, instead of sending out the session that has changed, it sends out
+ an "expire" message to TomcatB and TomcatB will invalidate the session as well.
+ </p><p></p>
+
+</li>
+<li><b><code>TomcatB</code> receives a request, for a new session (<code>S2</code>)</b>
+ <p>Same scenario as in step 3)
+ </p><p></p>
+
+
+</li>
+<li><code>TomcatA</code> The session <code>S2</code> expires due to inactivity.
+ <p>The invalidate is call is intercepted the same was as when a session is invalidated by the user,
+ and the session is queued with invalidated sessions.
+ At this point, the invalidet session will not be replicated across until
+ another request comes through the system and checks the invalid queue.
+ </p><p></p>
+</li>
+</ol>
+
+<p>Phuuuhh! :)</p>
+
+<p><b>Membership</b>
+ Clustering membership is established using very simple multicast pings.
+ Each Tomcat instance will periodically send out a multicast ping,
+ in the ping message the instance will broad cast its IP and TCP listen port
+ for replication.
+ If an instance has not received such a ping within a given timeframe, the
+ member is considered dead. Very simple, and very effective!
+ Of course, you need to enable multicasting on your system.
+</p>
+
+<p><b>TCP Replication</b>
+ Once a multicast ping has been received, the member is added to the cluster
+ Upon the next replication request, the sending instance will use the host and
+ port info and establish a TCP socket. Using this socket it sends over the serialized data.
+ The reason I choose TCP sockets is because it has built in flow control and guaranteed delivery.
+ So I know, when I send some data, it will make it there :)
+</p>
+
+<p><b>Distributed locking and pages using frames</b>
+ Tomcat does not keep session instances in sync across the cluster.
+ The implementation of such logic would be to much overhead and cause all
+ kinds of problems. If your client accesses the same session
+ simultanously using multiple requests, then the last request
+ will override the other sessions in the cluster.
+</p>
+
+</section>
+
+<section name="Cluster Architecture">
+
+<p><b>Component Levels:</b>
+<source>
+ Server
+ |
+ Service
+ |
+ Engine
+ | \
+ | --- Cluster --*
+ |
+ Host
+ |
+ ------
+ / \
+ Cluster Context(1-N)
+ | \
+ | -- Manager
+ | \
+ | -- DeltaManager
+ |
+ -----------------------------
+ | | | \
+ Receiver Sender Membership \
+ \ -- Valve
+ -- SocketReplicationListener | \
+ -- ReplicationListener | -- ReplicationValve
+ | -- JvmRouteBinderValve
+ |
+ -- LifecycleListener
+ |
+ -- ClusterListener
+ | \
+ | -- ClusterSessionListener
+ | -- JvmRouteSessionIDBinderListener
+ |
+ -- Deployer
+ \
+ -- FarmWarDeployer
+
+
+</source>
+<source>
+ Sender
+ \
+ -- ReplicationTransmitter
+ |
+ ---------
+ \
+ IDataSender
+ \
+ |
+ --- (sync)
+ | \
+ | -- PooledSocketSender (pooled)
+ | -- SockerSender (synchronous)
+ |
+ --- (async)
+ \
+ -- AsyncSocketSender (asynchronous)
+ -- FastAsyncSocketSender (fastasyncqueue)
+</source>
+</p>
+
+</section>
+
+
+<section name="Cluster Configuration">
+<p>The cluster configuration is described in the sample server.xml file.
+What is worth to mention is that the attributes starting with mcastXXX
+are for the membership multicast ping, and the attributes starting with tcpXXX
+are for the actual TCP replication.
+</p>
+<p>
+ The membership is established by all the tomcat instances are sending broadcast messages
+ on the same multicast IP and port.
+ The TCP listen port, is the port where the session replication is received from other members.
+</p>
+<p>
+ The replication valve is used to find out when the request has been completed and initiate the
+ replication.
+</p>
+<p>
+ One of the most important performance considerations is the synchronous (pooled or not pooled) versus asynchronous replication
+ mode. In a synchronous replication mode the request doesn't return until the replicated session has been
+ sent over the wire and reinstantiated on all the other cluster nodes.
+ There are two settings for synchronous replication. Pooled or not pooled.
+ Not pooled (ie replicationMode="fastasnycqueue" or "synchronous") means that all the replication request are sent over a single
+ socket.
+ Using synchronous mode can potentially becomes a bottleneck when a lot of messages generated,
+ You can overcome this bottleneck by setting replicationMode="pooled" but then you worker threads blocks with replication .
+ What is recommended here is to increase the number of threads that handle
+ incoming replication request. This is the tcpThreadCount property in the cluster
+ section of server.xml. The pooled setting means that we are using multiple sockets, hence increases the performance.
+ Asynchronous replication, should be used if you have sticky sessions until fail over, then
+ your replicated data is not time crucial, but the request time is, at this time leave the tcpThreadCount to
+ be number-of-nodes-1.
+ During async replication, the request is returned before the data has been replicated. async replication yields shorter
+ request times, and synchronous replication guarantees the session to be replicated before the request returns.
+</p>
+<p>
+ The parameter "replicationMode" has four different settings: "pooled", "synchronous", "asynchronous" and "fastasyncqueue"
+</p>
+
+<section name="Simple Cluster Configuration">
+<p>
+Simple one line configuration<br/>
+<source>
+ <Server port="8011"
+ shutdown="SHUTDOWN" >
+ <GlobalNamingResources>
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+ <Service name="Catalina">
+ <Connector port="9012"
+ protocol="AJP/1.3"
+ <Connector port="9013"
+ maxThreads="100"
+ minSpareThreads="4"
+ maxSpareThreads="4"
+ />
+ <Engine name="Catalina"
+ defaultHost="localhost"
+ jvmRoute="node01">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Host name="localhost"
+ appBase="webapps">
+ <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"/>
+ </Host>
+ </Engine>
+ </Service>
+</Server>
+</source>
+<br/>
+The default mode configuration setup a <em>fastasyncqueue</em> mode cluster configuration with following
+parameters:
+<ul>
+ <li>Open Membership receiver at <em>228.0.0.4</em> and send to multicast udp port <em>8012</em></li>
+ <li>Send membership every 1 sec and drop member after 30sec.</li>
+ <li>Open message receiver at default ip interface at first free port between <em>8015</em> and <em>8019</em>.</li>
+ <li>Receiver message with <em>SocketReplicationListener</em> </li>
+ <li>Configure a <em>ReplicationTransmitter</em> with <em>fastasyncqueue</em> sender mode.</li>
+ <li>Add <em>ClusterSessionListener</em> and <em>ReplicationValve</em>.</li>
+</ul>
+</p>
+<p>
+<b>NOTE</b>: Use this configuration when you need very quick a test cluster with
+at your developer machine. You can change the default attributes from cluster sub elements.
+Use following cluster attribute prefixes <em>sender.</em>,
+<b>receiver.</b>, <b>service.</b>, <b>manager.</b>, <b>valve.</b> and <b>listener.</b>.
+<br/><b>Example</b> configure cluster at windows laptop with network connection and
+change receiver port range<br/>
+<source>
+<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
+ service.mcastBindAddress="127.0.0.1"
+ receiver.tcpListenPort="9070"
+ receiver.tcpListenMaxPort="9075" />
+</source>
+<br/>
+<b>WARNING</b>: When you add you sub elements, there overwrite the defaults complete.
+<br/><b>Example</b> configure cluster with cluster failover jsessionid support. In this
+case you need also the defaultmode Cluster listener <em>ClusterSessionListener</em> and <em>ReplicationValve</em>.<br/>
+<source>
+<Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
+ service.mcastBindAddress="127.0.0.1"
+ receiver.tcpListenPort="9070"
+ receiver.tcpListenMaxPort="9075" >
+ <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener" />
+ <ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
+ <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
+ filter=".*\.gif;.*\.js;.*\.css;.*\.png;.*\.jpeg;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"
+ primaryIndicator="true" />
+ <Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve"
+ enabled="true" />
+</Cluster>
+</source>
+</p>
+</section>
+
+<section name="Simple Engine Cluster Configuration for all hosts">
+<p>
+Simple one line engine configuration<br/>
+<source>
+ <Server port="8011"
+ shutdown="SHUTDOWN" >
+ <GlobalNamingResources>
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+ <Service name="Catalina">
+ <Connector port="9012"
+ protocol="AJP/1.3"
+ <Connector port="9013"
+ maxThreads="100"
+ minSpareThreads="4"
+ maxSpareThreads="4"
+ />
+ <Engine name="Catalina"
+ defaultHost="localhost"
+ jvmRoute="node01">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"/>
+ <Host name="localhost"
+ appBase="webapps"/>
+ </Engine>
+ </Service>
+</Server>
+</source>
+<br/>
+See default mode configuration description as simple host cluster example before.
+</p>
+</section>
+
+<section name="Complex Cluster Configuration">
+<p>
+<br/><b>Example</b> Configure cluster with complete sub elements. Activate this node
+as master farm delopyer. Message receiver is NIO based <em>ReplicationListener</em> with six parallel
+worker threads.
+<br/>
+<source>
+ <Server port="8011"
+ shutdown="SHUTDOWN" >
+ <GlobalNamingResources>
+ <Resource name="UserDatabase" auth="Container"
+ type="org.apache.catalina.UserDatabase"
+ description="User database that can be updated and saved"
+ factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
+ pathname="conf/tomcat-users.xml" />
+ </GlobalNamingResources>
+ <Service name="Catalina">
+ <Connector port="9012"
+ protocol="AJP/1.3"
+ <Connector port="9013"
+ maxThreads="100"
+ minSpareThreads="4"
+ maxSpareThreads="4"
+ />
+ <Engine name="Catalina"
+ defaultHost="localhost"
+ jvmRoute="node01">
+ <Realm className="org.apache.catalina.realm.UserDatabaseRealm"
+ resourceName="UserDatabase" />
+ <Host name="localhost"
+ appBase="webapps">
+ <Cluster className="org.apache.catalina.cluster.tcp.SimpleTcpCluster"
+ doClusterLog="true"
+ clusterLogName="clusterlog"
+ manager.className="org.apache.catalina.cluster.session.DeltaManager"
+ manager.expireSessionsOnShutdown="false"
+ manager.notifyListenersOnReplication="false"
+ manager.notifySessionListenersOnReplication="false"
+ manager.sendAllSessions="false"
+ manager.sendAllSessionsSize="500"
+ manager.sendAllSessionsWaitTime="20">
+ <Membership
+ className="org.apache.catalina.cluster.mcast.McastService"
+ mcastAddr="228.0.0.4"
+ mcastBindAddress="127.0.0.1"
+ mcastClusterDomain="d10"
+ mcastPort="45564"
+ mcastFrequency="1000"
+ mcastDropTime="30000"
+ recoveryCounter="10"
+ recoveryEnabled="true"
+ recoverySleepTime="5000"/>
+ <Receiver
+ className="org.apache.catalina.cluster.tcp.ReplicationListener"
+ tcpListenAddress="auto"
+ tcpListenPort="9015"
+ tcpSelectorTimeout="100"
+ tcpThreadCount="6"/>
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="fastasyncqueue"
+ recoverTimeout="5000"
+ recoverCounter="6"
+ doTransmitterProcessingStats="true"
+ doProcessingStats="true"
+ doWaitAckStats="true"
+ queueTimeWait="true"
+ queueDoStats="true"
+ queueCheckLock="true"
+ ackTimeout="15000"
+ waitForAck="true"
+ keepAliveTimeout="80000"
+ keepAliveMaxRequestCount="-1"/>
+ <Valve className="org.apache.catalina.cluster.tcp.ReplicationValve"
+ filter=".*\.gif;.*\.js;.*\.css;.*\.png;.*\.jpeg;.*\.jpg;.*\.htm;.*\.html;.*\.txt;"
+ primaryIndicator="true" />
+ <Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve"
+ enabled="true" />
+ <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener" />
+ <ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
+ <Deployer className="org.apache.catalina.cluster.deploy.FarmWarDeployer"
+ tempDir="${catalina.base}/war-temp"
+ deployDir="${catalina.base}/war-deploy/"
+ watchDir="${catalina.base}/war-listen/"
+ watchEnabled="true"/>
+ </Cluster>
+ </Host>
+ </Engine>
+ </Service>
+</Server>
+</source>
+</p>
+</section>
+
+<section name="Cluster Configuration for ReplicationTransmitter">
+<p>
+List of Attributes<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Attribute</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">Default value</th>
+ </tr>
+
+ <tr>
+ <td>replicationMode</td>
+ <td>replication mode (<em>synchronous</em>, <em>pooled</em>, <em>asynchronous</em> or <em>fastasyncqueue</em>)
+ </td>
+ <td><code>pooled</code></td>
+ </tr>
+
+ <tr>
+ <td>processSenderFrequency</td>
+ <td>Control the sender keepalive status and drop sender socket connection after timeout is reached.
+ Check every processSenderFrequency value engine background ticks.
+ </td>
+ <td><code>2</code></td>
+ </tr>
+
+ <tr>
+ <td>compress</td>
+ <td>compress bytes before sending (consume memory, but reduce network traffic - GZIP)</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>ackTimeout</td>
+ <td>acknowledge timeout and only usefull it waitForAck is true</td>
+ <td><code>15000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>waitForAck</td>
+ <td>Wait for ack after data send</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>autoConnect</td>
+ <td>is sender disabled, fork a new socket</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>doTransmitterProcessingStats</td>
+ <td>create processing time stats</td>
+ <td><code>false</code></td>
+ </tr>
+</table>
+</p>
+<p>
+Example to get statistic information, wait for ack at every message send and transfer at compressed mode<br/>
+<source>
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="fastasyncqueue"
+ compress="true"
+ doTransmitterProcessingStats="true"
+ ackTimeout="15000"
+ waitForAck="true"
+ autoConnect="false"/>
+</source>
+</p>
+</section>
+
+<section name="Cluster Configuration for ReplicationTransmitter (fastayncqueue - mode)">
+<p>
+List of Attributes<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Attribute</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">Default value</th>
+ </tr>
+
+ <tr>
+ <td>keepAliveTimeout</td>
+ <td>active socket keep alive timeout</td>
+ <td><code>60000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>keepAliveMaxRequestCount</td>
+ <td>max request over this socket</td>
+ <td><code>-1</code></td>
+ </tr>
+
+ <tr>
+ <td>doProcessingStats</td>
+ <td>create Processing time stats</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>doWaitAckStats</td>
+ <td>create waitAck time stats</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>resend</td>
+ <td>resend message after failure, can overwrite at message</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>recoverTimeout</td>
+ <td>recover Timeout after push message failure </td>
+ <td><code>5000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>recoverCounter</td>
+ <td>number of recover tries</td>
+ <td><code>0</code></td>
+ </tr>
+
+ <tr>
+ <td>queueDoStats</td>
+ <td>activated queue stats</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>queueCheckLock</td>
+ <td>check to lost locks</td>
+ <td><code>false</code></td>
+ </tr>
+ <tr>
+ <td>queueAddWaitTimeout</td>
+ <td>queue add wait time (tomcat connector thread waits)</td>
+ <td><code>10000 msec</code></td>
+ </tr>
+ <tr>
+ <td>queueRemoveWaitTimeout</td>
+ <td>queue remove wait time (queue thread waits)</td>
+ <td><code>30000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>maxQueueLength</td>
+ <td>max queue length (default without limit)</td>
+ <td><code>-1</code></td>
+ </tr>
+
+ <tr>
+ <td>threadPriority</td>
+ <td>change queue thread priority (1-10 ; 5 is normal)</td>
+ <td><code>5</code></td>
+ </tr>
+</table>
+
+</p>
+<p>
+Example to get a lot of statistic information, wait for ACK and
+recover after connection failure. Wait 5 secs with attribute <i>recoverTimeout</i>, make 6 trails
+with attribute <i>recoverCounter</i> and use 30 secs (<i>mcastDropTime="30000"</i>) timeout
+at Service element <br/>
+<source>
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="fastasyncqueue"
+ recoverTimeout="5000"
+ recoverCounter="6"
+ doTransmitterProcessingStats="true"
+ doProcessingStats="true"
+ queueTimeWait="true"
+ queueDoStats="true"
+ queueCheckLock="true"
+ waitForAck="true"
+ autoConnect="false"
+ keepAliveTimeout="320000"
+ keepAliveMaxRequestCount="-1"/>
+</source>
+</p>
+</section>
+
+<section name="Cluster Configuration for ReplicationTransmitter ( asynchronous - mode)">
+<p>
+List of Attributes<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Attribute</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">Default value</th>
+ </tr>
+
+ <tr>
+ <td>keepAliveTimeout</td>
+ <td>active socket keep alive timeout</td>
+ <td><code>60000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>keepAliveMaxRequestCount</td>
+ <td>max request over this socket</td>
+ <td><code>-1</code></td>
+ </tr>
+
+ <tr>
+ <td>doProcessingStats</td>
+ <td>create Processing time stats</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>doWaitAckStats</td>
+ <td>create waitAck time stats</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>resend</td>
+ <td>resend message after failure, can overwrite at message</td>
+ <td><code>false</code></td>
+ </tr>
+
+</table>
+</p>
+<p>
+Example to get a processing statistic information, resend after failure and wait for ACK<br/>
+<source>
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="asynchronous"
+ doProcessingStats="true"
+ doWaitAckStats="true"
+ waitForAck="true"
+ ackTimeout="30000"
+ resend="true"
+ keepAliveTimeout="320000"
+ keepAliveMaxRequestCount="-1"/>
+</source>
+</p>
+</section>
+
+<section name="Cluster Configuration for ReplicationTransmitter ( synchronous - mode)">
+<p>
+List of Attributes<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Attribute</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">Default value</th>
+ </tr>
+
+ <tr>
+ <td>keepAliveTimeout</td>
+ <td>active socket keep alive timeout</td>
+ <td><code>60000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>keepAliveMaxRequestCount</td>
+ <td>max request over this socket</td>
+ <td><code>-1</code></td>
+ </tr>
+
+ <tr>
+ <td>doProcessingStats</td>
+ <td>create Processing time stats</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>doWaitAckStats</td>
+ <td>create waitAck time stats</td>
+ <td><code>true</code></td>
+ </tr>
+
+ <tr>
+ <td>resend</td>
+ <td>resend message after failure, can overwrite at message</td>
+ <td><code>false</code></td>
+ </tr>
+
+</table>
+
+</p>
+<p>
+Example to get a no processing statistic information, no wait for ACK, after 10000 request renew socket and autoconnect before first request is send.<br/>
+<source>
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="synchronous"
+ autoConnect="true"
+ keepAliveTimeout="-1"
+ keepAliveMaxRequestCount="100000"/>
+</source>
+</p>
+</section>
+
+<section name="Cluster Configuration for ReplicationTransmitter ( pooled - mode)">
+<p>
+List of Attributes<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Attribute</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">Default value</th>
+ </tr>
+
+ <tr>
+ <td>keepAliveTimeout</td>
+ <td>active socket keep alive timeout</td>
+ <td><code>60000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>keepAliveMaxRequestCount</td>
+ <td>max request over this socket</td>
+ <td><code>-1</code></td>
+ </tr>
+
+ <tr>
+ <td>maxPoolSocketLimit</td>
+ <td>max pooled sockets (Sender Sockets)</td>
+ <td><code>25</code></td>
+ </tr>
+
+ <tr>
+ <td>resend</td>
+ <td>resend message after failure, can overwrite at message</td>
+ <td><code>false</code></td>
+ </tr>
+
+</table>
+
+</p>
+<p>
+Example to get a no processing statistic information, wait for ACK, after 10000 request renew socket, only 10 SockerSender available and autoconnect before first request is send.<br/>
+<source>
+ <Sender
+ className="org.apache.catalina.cluster.tcp.ReplicationTransmitter"
+ replicationMode="pooled"
+ autoConnect="true"
+ maxPoolSocketLimit="10"
+ keepAliveTimeout="-1"
+ keepAliveMaxRequestCount="10000"
+ waitForAck="true" />
+</source>
+</p>
+</section>
+
+<section name="Cluster Configuration for ReplicationTransmitter ( DeltaManager Attribute)">
+<p>
+List of Attributes<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Attribute</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">Default value</th>
+ </tr>
+
+ <tr>
+ <td>expireSessionsOnShutdown</td>
+ <td>When server stopped, expire all sessions also at backup nodes (only for testing)</td>
+ <td><code>false</code></td>
+ </tr>
+
+ <tr>
+ <td>maxActiveSessions</td>
+ <td>Number of active sessions. (Default is no limit)</td>
+ <td><code>-1</code></td>
+ </tr>
+
+ <tr>
+ <td>notifyListenersOnReplication</td>
+ <td>Notify application session listener to session creation
+ and expiring events at backup nodes</td>
+ <td><code>true</code></td>
+ </tr>
+
+ <tr>
+ <td>notifySessionListenersOnReplication</td>
+ <td>Notify application session listener to attribute changes at backup nodes</td>
+ <td><code>true</code></td>
+ </tr>
+
+ <tr>
+ <td>stateTransferTimeout</td>
+ <td>Timeout that session state transfer is complete. Is attribute <code>stateTransferTimeout == -1</code>
+ then application wait that other node send the complete session state</td>
+ <td><code>60 sec</code></td>
+ </tr>
+
+ <tr>
+ <td>sendAllSessions</td>
+ <td>Flag to send sessions as splited blocks</td>
+ <td><code>true</code></td>
+ </tr>
+
+ <tr>
+ <td>sendAllSessionsSize</td>
+ <td>Number of serialize sessions inside a send block session message. Only useful when <code>sendAllSessions==false</code></td>
+ <td><code>1000</code></td>
+ </tr>
+
+ <tr>
+ <td>sendAllSessionsWaitTime</td>
+ <td>wait time between two session send blocks.</td>
+ <td><code>2000 msec</code></td>
+ </tr>
+
+ <tr>
+ <td>sendClusterDomainOnly</td>
+ <td>Send all session messages only to member inside same cluster domain
+ (value od Membership attribute mcastClusterDomain). Also don't handle
+ session messages from other domains.</td>
+ <td><code>true</code></td>
+ </tr>
+
+ <tr>
+ <td>stateTimestampDrop</td>
+ <td>DeltaManager queued Sessions messages when send GET_ALL_SESSION to other node.
+ with stateTimestampDrop all messages before state transfer message creation date (find session) are dropped.
+ Only other GET_ALL_SESSION events are handle with date before state transfer message.</td>
+ <td><code>true</code></td>
+ </tr>
+
+ <tr>
+ <td>updateActiveInterval</td>
+ <td>Send session access message every updateActiveInterval sec.</td>
+ <td><code>60</code></td>
+ </tr>
+
+ <tr>
+ <td>expireTolerance</td>
+ <td>Autoexpire backup session after MaxInactive + expireTolerance sec.</td>
+ <td><code>300</code></td>
+ </tr>
+
+</table>
+
+</p>
+<p>
+Example send all sessions at separate blocks. Serialize and send 100 session inside one block.
+Wait maximale two minutes before the complete backup sessions are loaded inside tomcat boot process.
+Between send blocks wait 5 secs to transfers the session block to other node. This save memory
+when you use the async modes with queues.<br/>
+<source>
+ <Cluster className="org.apache.catalina.tcp.SimpleTcpCluster"
+ managerClassName="org.apache.catalina.cluster.session.DeltaManager"
+ manager.stateTransferTimeout="120"
+ manager.sendAllSessions="false"
+ manager.sendAllSessionsSize="100"
+ manager.sendAllSessionsWaitTime="5000"
+ "/>
+</source>
+</p>
+<p>
+<b>Note:</b><br/>
+As <em>Cluster.defaultMode=true</em> you can configure the manager attributes with prefix <em>manager.</em>.
+<br/>
+<b>Note:</b><br/>
+With <em>Cluster.setProperty(<String>,<String>)</em> you can modify
+attributes for all register managers. The method exists as MBeans operation.
+</p>
+</section>
+
+<section name="Bind session after crash to failover node">
+<p>
+As you configure more then two nodes at same cluster for backup, most loadbalancer
+send don't all your requests after failover to the same node.
+</p>
+<p>
+The JvmRouteBinderValve handle tomcat jvmRoute takeover using mod_jk module after node
+failure. After a node crashed the next request going to other cluster node. The JvmRouteBinderValve
+now detect the takeover and rewrite the jsessionid
+information to the backup cluster node. After the next response all client
+request goes direct to the backup node. The change sessionid send also to all
+other cluster nodes. Well, now the session stickyness work directly to the
+backup node, but traffic don't go back too restarted cluster nodes!<br/>
+As jsessionid was created by cookie, the change JSESSIONID cookie resend with next response.
+</p>
+<p>
+You must add JvmRouteBinderValve and the corresponding cluster message listener JvmRouteSessionIDBinderListener.
+As you add the new listener you must also add the default ClusterSessionListener that receiver the normal cluster messages.
+
+<source>
+<Cluster className="org.apache.catalina.tcp.SimpleTcpCluster" >
+...
+ <Valve className="org.apache.catalina.cluster.session.JvmRouteBinderValve"
+ enabled="true" sessionIdAttribute="takeoverSessionid"/>
+ <ClusterListener className="org.apache.catalina.cluster.session.JvmRouteSessionIDBinderListener" />
+ <ClusterListener className="org.apache.catalina.cluster.session.ClusterSessionListener" />
+...
+<Cluster>
+</source>
+</p>
+<p>
+<b>Hint:</b><br/>
+With attribute <i>sessionIdAttribute</i> you can change the request attribute name that included the old session id.
+Default attribuite name is <i>org.apache.catalina.cluster.session.JvmRouteOrignalSessionID</i>.
+</p>
+<p>
+<b>Trick:</b><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 session are migrated.
+</p>
+
+</section>
+
+</section>
+
+
+<section name="Monitoring your Cluster with JMX">
+<p>Monitoring is a very important question when you use a cluster. Some of the cluster objects are JMX MBeans </p>
+<p>Add the following parameter to your startup script:
+<source>
+set CATALINA_OPTS=\
+-Dcom.sun.management.jmxremote \
+-Dcom.sun.management.jmxremote.port=%my.jmx.port% \
+-Dcom.sun.management.jmxremote.ssl=false \
+-Dcom.sun.management.jmxremote.authenticate=false
+</source>
+</p>
+<p>
+List of Cluster Mbeans<br/>
+<table border="1" cellpadding="5">
+
+ <tr>
+ <th align="center" bgcolor="aqua">Name</th>
+ <th align="center" bgcolor="aqua">Description</th>
+ <th align="center" bgcolor="aqua">MBean ObjectName - Engine</th>
+ <th align="center" bgcolor="aqua">MBean ObjectName - Host</th>
+ </tr>
+
+ <tr>
+ <td>Cluster</td>
+ <td>The complete cluster element</td>
+ <td><code>type=Cluster</code></td>
+ <td><code>type=Cluster,host=${HOST}</code></td>
+ </tr>
+
+ <tr>
+ <td>ClusterSender</td>
+ <td>Configuration and stats of the sender infrastructure</td>
+ <td><code>type=ClusterSender</code></td>
+ <td><code>type=ClusterSender,host=${HOST}</code></td>
+ </tr>
+
+ <tr>
+ <td>ClusterReceiver</td>
+ <td>Configuration and stats of the recevier infrastructure</td>
+ <td><code>type=ClusterReceiver</code></td>
+ <td><code>type=ClusterReceiver,host=${HOST}</code></td>
+ </tr>
+
+ <tr>
+ <td>ClusterMembership</td>
+ <td>Configuration and stats of the membership infrastructure</td>
+ <td><code>type=ClusterMembership</code></td>
+ <td><code>type=ClusterMembership,host=${HOST}</code></td>
+ </tr>
+
+ <tr>
+ <td>IDataSender</td>
+ <td>For every cluster member it exist a sender mbeans.
+ It exists speziall MBeans to all replication modes</td>
+ <td><code>type=IDataSender,
+ senderAddress=${MEMBER.SENDER.IP},
+ senderPort=${MEMBER.SENDER.PORT}</code></td>
+ <td><code>type=IDataSender,host=${HOST},
+ senderAddress=${MEMBER.SENDER.IP},
+ senderPort=${MEMBER.SENDER.PORT}</code></td>
+ </tr>
+
+ <tr>
+ <td>DeltaManager</td>
+ <td>This manager control the sessions and handle session replication </td>
+ <td><code>type=Manager,path=${APP.CONTEXT.PATH}, host=${HOST}</code></td>
+ <td><code>type=Manager,path=${APP.CONTEXT.PATH}, host=${HOST}</code></td>
+ </tr>
+
+ <tr>
+ <td>ReplicationValve</td>
+ <td>This valve control the replication to the backup nodes</td>
+ <td><code>type=Valve,name=ReplicationValve</code></td>
+ <td><code>type=Valve,name=ReplicationValve,host=${HOST}</code></td>
+ </tr>
+
+ <tr>
+ <td>JvmRouteBinderValve</td>
+ <td>This is a cluster fallback valve to change the Session ID to the current tomcat jvmroute.</td>
+ <td><code>type=Valve,name=JvmRouteBinderValve,
+ path=${APP.CONTEXT.PATH}</code></td>
+ <td><code>type=Valve,name=JvmRouteBinderValve,host=${HOST},
+ path=${APP.CONTEXT.PATH}</code></td>
+ </tr>
+
+</table>
+</p>
+</section>
+
+<section name="FAQ">
+<p>Please see <a href="http://tomcat.apache.org/faq/cluster.html">the clustering section of the FAQ</a>.</p>
+</section>
+
+</body>
+
+</document>
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/oacc-howto.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml?rev=641922&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml (added)
+++ tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml Thu Mar 27 10:40:59 2008
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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.
+-->
+<project name="Apache Tomcat OACC Documentation"
+ href="http://tomcat.apache.org/">
+
+ <title>Apache Tomcat OACC</title>
+
+ <logo href="/images/tomcat.gif">
+ Apache Tomcat OACC
+ </logo>
+
+
+ <body>
+
+ <menu name="Documentation">
+ <item name="Docs Home" href="index.html"/>
+ <item name="Installation" href="RUNNING.txt"/>
+ <item name="HowTo" href="oacc-howto.html"/>
+ <item name="Release Notes" href="RELEASE-NOTES"/>
+ <item name="Changelog" href="changelog.html"/>
+ <item name="Building" href="BUILDING.txt"/>
+ </menu>
+
+ <menu name="Links">
+ <item name="Apache Tomcat 6 Documentation"
+ href="http://tomcat.apache.org/tomcat-6.0-doc/"/>
+ <item name="JK 1.2 Documentation"
+ href="http://tomcat.apache.org/connectors-doc/"/>
+ <item name="General Tomcat FAQ"
+ href="http://tomcat.apache.org/faq" />
+ </menu>
+
+ </body>
+
+</project>
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/project.xml
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
Added: tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl
URL: http://svn.apache.org/viewvc/tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl?rev=641922&view=auto
==============================================================================
--- tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl (added)
+++ tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl Thu Mar 27 10:40:59 2008
@@ -0,0 +1,452 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!--
+ 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.
+-->
+<!-- Content Stylesheet for "tomcat-docs" Documentation -->
+
+<!-- $Id$ -->
+
+<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+ version="1.0">
+
+
+ <!-- Output method -->
+ <xsl:output method="html"
+ encoding="iso-8859-1"
+ indent="no"/>
+
+
+ <!-- Defined parameters (overrideable) -->
+ <xsl:param name="home-name" select="'Apache Tomcat OACC'"/>
+ <xsl:param name="home-href" select="'http://tomcat.apache.org/'"/>
+ <xsl:param name="home-logo" select="'/images/tomcat.gif'"/>
+ <xsl:param name="printer-logo" select="'/images/printer.gif'"/>
+ <xsl:param name="apache-logo" select="'/images/asf-logo.gif'"/>
+ <xsl:param name="relative-path" select="'.'"/>
+ <xsl:param name="void-image" select="'/images/void.gif'"/>
+ <xsl:param name="project-menu" select="'menu'"/>
+ <xsl:param name="standalone" select="''"/>
+ <xsl:param name="buglink" select="'http://issues.apache.org/bugzilla/show_bug.cgi?id='"/>
+
+ <!-- Defined variables (non-overrideable) -->
+ <xsl:variable name="body-bg" select="'#ffffff'"/>
+ <xsl:variable name="body-fg" select="'#000000'"/>
+ <xsl:variable name="body-link" select="'#525D76'"/>
+ <xsl:variable name="banner-bg" select="'#525D76'"/>
+ <xsl:variable name="banner-fg" select="'#ffffff'"/>
+ <xsl:variable name="sub-banner-bg" select="'#828DA6'"/>
+ <xsl:variable name="sub-banner-fg" select="'#ffffff'"/>
+ <xsl:variable name="source-color" select="'#023264'"/>
+ <xsl:variable name="attributes-color" select="'#023264'"/>
+ <xsl:variable name="table-th-bg" select="'#039acc'"/>
+ <xsl:variable name="table-td-bg" select="'#a0ddf0'"/>
+
+ <!-- Process an entire document into an HTML page -->
+ <xsl:template match="document">
+ <xsl:variable name="project"
+ select="document('project.xml')/project"/>
+ <html>
+ <head>
+ <title><xsl:value-of select="project/title"/> - <xsl:value-of select="properties/title"/></title>
+ <xsl:for-each select="properties/author">
+ <xsl:variable name="name">
+ <xsl:value-of select="."/>
+ </xsl:variable>
+ <xsl:variable name="email">
+ <xsl:value-of select="@email"/>
+ </xsl:variable>
+ <meta name="author" value="{$name}"/>
+ <meta name="email" value="{$email}"/>
+ </xsl:for-each>
+ </head>
+
+ <body bgcolor="{$body-bg}" text="{$body-fg}" link="{$body-link}"
+ alink="{$body-link}" vlink="{$body-link}">
+
+ <table border="0" width="100%" cellspacing="0">
+
+ <xsl:comment>PAGE HEADER</xsl:comment>
+ <tr>
+ <td>
+ <xsl:if test="project/logo">
+ <xsl:variable name="alt">
+ <xsl:value-of select="project/logo"/>
+ </xsl:variable>
+ <xsl:variable name="home">
+ <xsl:value-of select="project/@href"/>
+ </xsl:variable>
+ <xsl:variable name="src">
+ <xsl:value-of select="$relative-path"/><xsl:value-of select="project/logo/@href"/>
+ </xsl:variable>
+
+ <xsl:comment>PROJECT LOGO</xsl:comment>
+ <a href="{$home}">
+ <img src="{$src}" align="right" alt="{$alt}" border="0"/>
+ </a>
+ </xsl:if>
+ </td>
+ <td>
+ <font face="arial,helvetica,sanserif">
+ <h1><xsl:value-of select="$project/title"/></h1>
+ </font>
+ </td>
+ <td>
+ <xsl:comment>APACHE LOGO</xsl:comment>
+ <xsl:variable name="src">
+ <xsl:value-of select="$relative-path"/><xsl:value-of select="$apache-logo"/>
+ </xsl:variable>
+ <a href="http://www.apache.org/">
+ <img src="{$src}" align="right" alt="Apache Logo" border="0"/>
+ </a>
+ </td>
+ </tr>
+ </table>
+
+ <table border="0" width="100%" cellspacing="4">
+
+ <xsl:comment>HEADER SEPARATOR</xsl:comment>
+ <tr>
+ <td colspan="2">
+ <hr noshade="noshade" size="1"/>
+ </td>
+ </tr>
+
+ <tr>
+
+ <!-- Don't generate a menu if styling printer friendly docs -->
+ <xsl:if test="$project-menu = 'menu'">
+ <xsl:comment>LEFT SIDE NAVIGATION</xsl:comment>
+ <td width="20%" valign="top" nowrap="true">
+ <xsl:apply-templates select="project/body/menu"/>
+ </td>
+ </xsl:if>
+
+ <xsl:comment>RIGHT SIDE MAIN BODY</xsl:comment>
+ <td width="80%" valign="top" align="left">
+ <table border="0" width="100%" cellspacing="4">
+ <tr>
+ <td align="left" valign="top">
+ <h1><xsl:value-of select="project/title"/></h1>
+ <h2><xsl:value-of select="properties/title"/></h2>
+ </td>
+ <td align="right" valign="top" nowrap="true">
+ <!-- Add the printer friendly link for docs with a menu -->
+ <xsl:if test="$project-menu = 'menu'">
+ <xsl:variable name="src">
+ <xsl:value-of select="$relative-path"/><xsl:value-of select="$printer-logo"/>
+ </xsl:variable>
+ <xsl:variable name="url">
+ <xsl:value-of select="/document/@url"/>
+ </xsl:variable>
+ <small>
+ <a href="printer/{$url}">
+ <img src="{$src}" border="0" alt="Printer Friendly Version"/>
+ <br />print-friendly<br />version
+ </a>
+ </small>
+ </xsl:if>
+ <xsl:if test="$project-menu != 'menu'">
+ <xsl:variable name="void">
+ <xsl:value-of select="$relative-path"/><xsl:value-of select="$void-image"/>
+ </xsl:variable>
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </xsl:if>
+ </td>
+ </tr>
+ </table>
+ <xsl:apply-templates select="body/section"/>
+ </td>
+
+ </tr>
+
+ <xsl:comment>FOOTER SEPARATOR</xsl:comment>
+ <tr>
+ <td colspan="2">
+ <hr noshade="noshade" size="1"/>
+ </td>
+ </tr>
+
+ <xsl:comment>PAGE FOOTER</xsl:comment>
+ <tr><td colspan="2">
+ <div align="center"><font color="{$body-link}" size="-1"><em>
+ Copyright © 1999-2008, Apache Software Foundation
+ </em></font></div>
+ </td></tr>
+
+ </table>
+ </body>
+ </html>
+
+ </xsl:template>
+
+
+ <!-- Process a menu for the navigation bar -->
+ <xsl:template match="menu">
+ <p><strong><xsl:value-of select="@name"/></strong></p>
+ <ul>
+ <xsl:apply-templates select="item"/>
+ </ul>
+ </xsl:template>
+
+
+ <!-- Process a menu item for the navigation bar -->
+ <xsl:template match="item">
+ <xsl:variable name="href">
+ <xsl:value-of select="@href"/>
+ </xsl:variable>
+ <li><a href="{$href}"><xsl:value-of select="@name"/></a></li>
+ </xsl:template>
+
+
+ <!-- Process a documentation section -->
+ <xsl:template match="section">
+ <xsl:variable name="name">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <table border="0" cellspacing="0" cellpadding="2">
+ <!-- Section heading -->
+ <tr><td bgcolor="{$banner-bg}">
+ <font color="{$banner-fg}" face="arial,helvetica.sanserif">
+ <a name="{$name}">
+ <strong><xsl:value-of select="@name"/></strong></a></font>
+ </td></tr>
+ <!-- Section body -->
+ <tr><td><blockquote>
+ <xsl:apply-templates/>
+ </blockquote></td></tr>
+ </table>
+ </xsl:template>
+
+
+ <!-- Process a documentation subsection -->
+ <xsl:template match="subsection">
+ <xsl:variable name="name">
+ <xsl:value-of select="@name"/>
+ </xsl:variable>
+ <table border="0" cellspacing="0" cellpadding="2">
+ <!-- Subsection heading -->
+ <tr><td bgcolor="{$sub-banner-bg}">
+ <font color="{$sub-banner-fg}" face="arial,helvetica.sanserif">
+ <a name="{$name}">
+ <strong><xsl:value-of select="@name"/></strong></a></font>
+ </td></tr>
+ <!-- Subsection body -->
+ <tr><td><blockquote>
+ <xsl:apply-templates/>
+ </blockquote></td></tr>
+ </table>
+ </xsl:template>
+
+
+ <!-- Process a source code example -->
+ <xsl:template match="source">
+ <xsl:variable name="void">
+ <xsl:value-of select="$relative-path"/><xsl:value-of select="$void-image"/>
+ </xsl:variable>
+ <div align="left">
+ <table cellspacing="4" cellpadding="0" border="0">
+ <tr>
+ <td bgcolor="{$source-color}" width="1" height="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ <td bgcolor="{$source-color}" height="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ <td bgcolor="{$source-color}" width="1" height="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ </tr>
+ <tr>
+ <td bgcolor="{$source-color}" width="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ <td bgcolor="#ffffff" height="1"><pre>
+ <xsl:value-of select="."/>
+ </pre></td>
+ <td bgcolor="{$source-color}" width="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ </tr>
+ <tr>
+ <td bgcolor="{$source-color}" width="1" height="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ <td bgcolor="{$source-color}" height="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ <td bgcolor="{$source-color}" width="1" height="1">
+ <img src="{$void}" width="1" height="1" vspace="0" hspace="0" border="0"/>
+ </td>
+ </tr>
+ </table>
+ </div>
+ </xsl:template>
+
+
+ <!-- Process an attributes list with nested attribute elements -->
+ <xsl:template match="attributes">
+ <table border="1" cellpadding="5">
+ <tr>
+ <th width="15%" bgcolor="{$attributes-color}">
+ <font color="#ffffff">Attribute</font>
+ </th>
+ <th width="85%" bgcolor="{$attributes-color}">
+ <font color="#ffffff">Description</font>
+ </th>
+ </tr>
+ <xsl:for-each select="attribute">
+ <tr>
+ <td align="left" valign="center">
+ <xsl:if test="@required = 'true'">
+ <strong><code><xsl:value-of select="@name"/></code></strong>
+ </xsl:if>
+ <xsl:if test="@required != 'true'">
+ <code><xsl:value-of select="@name"/></code>
+ </xsl:if>
+ </td>
+ <td align="left" valign="center">
+ <xsl:apply-templates/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </table>
+ </xsl:template>
+
+ <!-- Fix relative links in printer friendly versions of the docs -->
+ <xsl:template match="a">
+ <xsl:variable name="href" select="@href"/>
+ <xsl:choose>
+ <xsl:when test="$standalone = 'standalone'">
+ <xsl:apply-templates/>
+ </xsl:when>
+ <xsl:when test="$project-menu != 'menu' and starts-with(@href,'../')">
+ <a href="../{$href}"><xsl:apply-templates/></a>
+ </xsl:when>
+ <xsl:when test="$project-menu != 'menu' and starts-with(@href,'./') and contains(substring(@href,3),'/')">
+ <a href=".{$href}"><xsl:apply-templates/></a>
+ </xsl:when>
+ <xsl:when test="$project-menu != 'menu' and not(contains(@href,'//')) and not(starts-with(@href,'/')) and not(starts-with(@href,'#')) and contains(@href,'/')">
+ <a href="../{$href}"><xsl:apply-templates/></a>
+ </xsl:when>
+ <xsl:when test="$href != ''">
+ <a href="{$href}"><xsl:apply-templates/></a>
+ </xsl:when>
+ <xsl:otherwise>
+ <xsl:variable name="name" select="@name"/>
+ <a name="{$name}"><xsl:apply-templates/></a>
+ </xsl:otherwise>
+ </xsl:choose>
+ </xsl:template>
+
+ <!-- Changelog related tags -->
+ <xsl:template match="changelog">
+ <table border="0" cellpadding="2" cellspacing="2">
+ <xsl:apply-templates/>
+ </table>
+ </xsl:template>
+
+ <xsl:template match="changelog/add">
+ <tr>
+ <xsl:variable name="src"><xsl:value-of select="$relative-path"/>/images/add.gif</xsl:variable>
+ <td><img alt="add" class="icon" src="{$src}"/></td>
+ <td><xsl:apply-templates/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="changelog/update">
+ <tr>
+ <xsl:variable name="src"><xsl:value-of select="$relative-path"/>/images/update.gif</xsl:variable>
+ <td><img alt="update" class="icon" src="{$src}"/></td>
+ <td><xsl:apply-templates/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="changelog/design">
+ <tr>
+ <xsl:variable name="src"><xsl:value-of select="$relative-path"/>/images/design.gif</xsl:variable>
+ <td><img alt="design" class="icon" src="{$src}"/></td>
+ <td><xsl:apply-templates/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="changelog/docs">
+ <tr>
+ <xsl:variable name="src"><xsl:value-of select="$relative-path"/>/images/docs.gif</xsl:variable>
+ <td><img alt="docs" class="icon" src="{$src}"/></td>
+ <td><xsl:apply-templates/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="changelog/fix">
+ <tr>
+ <xsl:variable name="src"><xsl:value-of select="$relative-path"/>/images/fix.gif</xsl:variable>
+ <td><img alt="fix" class="icon" src="{$src}"/></td>
+ <td><xsl:apply-templates/></td>
+ </tr>
+ </xsl:template>
+
+ <xsl:template match="changelog/scode">
+ <tr>
+ <xsl:variable name="src"><xsl:value-of select="$relative-path"/>/images/code.gif</xsl:variable>
+ <td><img alt="code" class="icon" src="{$src}"/></td>
+ <td><xsl:apply-templates/></td>
+ </tr>
+ </xsl:template>
+
+ <!-- Process an attributes list with nested attribute elements -->
+ <xsl:template match="status">
+ <table border="1" cellpadding="5">
+ <tr>
+ <th width="15%" bgcolor="{$attributes-color}">
+ <font color="#ffffff">Priority</font>
+ </th>
+ <th width="50%" bgcolor="{$attributes-color}">
+ <font color="#ffffff">Action Item</font>
+ </th>
+ <th width="25%" bgcolor="{$attributes-color}">
+ <font color="#ffffff">Volunteers</font>
+ </th>
+ <xsl:for-each select="item">
+ <tr>
+ <td align="left" valign="center">
+ <xsl:value-of select="@priority"/>
+ </td>
+ <td align="left" valign="center">
+ <xsl:apply-templates/>
+ </td>
+ <td align="left" valign="center">
+ <xsl:value-of select="@owner"/>
+ </td>
+ </tr>
+ </xsl:for-each>
+ </tr>
+ </table>
+ </xsl:template>
+
+ <!-- Link to a bug report -->
+ <xsl:template match="bug">
+ <xsl:variable name="link"><xsl:value-of select="$buglink"/><xsl:value-of select="text()"/></xsl:variable>
+ <a href="{$link}"><xsl:apply-templates/></a>
+ </xsl:template>
+
+ <!-- Process everything else by just passing it through -->
+ <xsl:template match="*|@*">
+ <xsl:copy>
+ <xsl:apply-templates select="@*|*|text()"/>
+ </xsl:copy>
+ </xsl:template>
+
+</xsl:stylesheet>
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: tomcat/sandbox/tomcat-oacc/trunk/docs/tomcat-oacc-docs.xsl
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org