<?xml version="1.0" encoding="UTF-8"?>
<section version="5.0" xml:lang="en" xmlns="http://docbook.org/ns/docbook"
         xmlns:xlink="http://www.w3.org/1999/xlink"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:svg="http://www.w3.org/2000/svg"
         xmlns:mml="http://www.w3.org/1998/Math/MathML"
         xmlns:html="http://www.w3.org/1999/xhtml"
         xmlns:db="http://docbook.org/ns/docbook">
  <info>
    <title>EJB clustering with CMI and HA service</title>
  </info>

  <section><info><title>Introduction</title></info>

    <para>
      CMI and HA service do provide the following clustering features:
    </para>
    <itemizedlist>
      <listitem><para>
        JNDI high availability through the registry replication and the multi-target lookup
      </para></listitem>
      <listitem><para>
        EJB load-balancing and fail-over through the CMI cluster proxy
        <itemizedlist>
          <listitem><para>
            for the EJB2.1 home interface (SSB, SFSB, EB)
          </para></listitem>
          <listitem><para>
            for the EJB2.1 remote interface (SSB)
          </para></listitem>
          <listitem><para>
            for the EJB3 (SSB, SFSB)
          </para></listitem>
        </itemizedlist>
      </para></listitem>
      <listitem><para>
        EJB high availability with the HA service
        <itemizedlist>
          <listitem><para>
            for the EJB2.1 SFSB
          </para></listitem>
          <listitem><para>
            EJB3 support being under development
          </para></listitem>
        </itemizedlist>
      </para></listitem>
    </itemizedlist>
    <para>
      <mediaobject>
        <imageobject>
          <imagedata align="center"
                     fileref="../../../../resources/images/clustering/cmi_cluster.png"
                     width="60%" scalefit="1">
          </imagedata>
        </imageobject>
      </mediaobject>
    </para>

   <section><info><title>CMI</title></info>
      <para>
         <link
          xlink:href="http://cmi.ow2.org">CMI</link>
         is an OW2 project providing a framework to define and configure clusters of RMI objects. CMI is embedded both in JOnAS and EasyBeans projects.
      </para>

       <para>
        The main features are :
        <itemizedlist>
          <listitem><para>Support of EJB2 and EJB3</para></listitem>
          <listitem><para>Definition of the cluster logic with simple POJO (policy and strategy)</para></listitem>
          <listitem><para>Delivery of a set of predefined policies (round robin, first available, random, ...) and strategies (weighted, local preference, ...)</para></listitem>
          <listitem><para>Dynamic update of the policy and strategy from the server side</para></listitem>
          <listitem><para>Smooth shutdown of a cluster member</para></listitem>
          <listitem><para>JMX management</para></listitem>
          <listitem><para>Separation of the control flow and the service flow</para></listitem>
          <listitem><para>multi-protocols support: jrmp, irmi, iiop</para></listitem>
        </itemizedlist>

		<note>
		  <para>CMI described in this section is CMI v2 available in JOnAS 5 (not in JOnAS 4).</para>
		</note>

      </para>

      <xi:include href="../../cmi/userguide.xml" xpointer="cmi.ug.lb" />
      <xi:include href="../../cmi/userguide.xml" xpointer="cmi.ug.arch.interfaces" />
      <xi:include href="../../cmi/userguide.xml" xpointer="cmi.ug.arch.internals" />

    </section>

   <section><info><title>HA service</title></info>

     <para>HA service provides High Availability for the EJB. A first implementation based on the Horizontal replication is delivered for EJB2.1.
     Other solutions are under development: Terracotta based and pair replication.</para>

     <section><info><title>High Availability with Horizontal Replication</title></info>


      <para>
        Stateful session beans (EJB2.1) can be replicated since JOnAS 4.7 in order to provide high availability in the case of failures in clustered environments.
        A new service called High Availability (HA) has been included in JOnAS to provide replication mechanisms.
        JOnAS HA also requires the cluster method invocation (CMI) protocol.
      </para>
      <para>
        From JOnAS 4.8, a new replication algorithm based on a horizontal replication approach is available. The algorithm improves the algorithm implemented for JOnAS 4.7 with the following enhancements:
      </para>
      <itemizedlist>
        <listitem><para>
          Replication of SFSBs with references to EBs: The algorithm can replicate SFSBs that reference EB by means of both, local or remote interfaces.
          </para></listitem>
        <listitem><para>
          Transaction awareness: The algorithm is transaction aware, meaning that the state is not replicated if the transaction aborts.
        </para></listitem>
        <listitem><para>
          Exactly-once semantics: Each transaction is committed exactly once at the DB if the client does not fail. If the client fails, each transaction is committed at most once at the DB
        </para></listitem>
      </itemizedlist>

      <section><info><title>EJB replication Description</title></info>

        <section><info><title>Update-everywhere mode</title></info>

          <para>
            JOnAS implements an update-everywhere replication protocol according to the database replication terminology (See the  J. Gray et al.'s paper ''The dangers of replication and a solution'' in proceedings of the ACM SIGMOD 96's conference, Canada). In this protocol, a client can connect to any server. When the client calls the create() method on the SFSB's Home interface, the server the client connects to is selected following a round-robin scheme. All the requests from the client to the SFSB will be processed by this server until the client calls the remove() method on the remote interface. The rest of the servers will act as backups for that client. Before sending the response to the client, the SFSB's state is sent to the backups.
          </para>
          <para>
            If the server fails, another server among the backups will be selected to serve the client requests, first restoring the current state of the SFSBs from the state information stored in the HA local service. From this point on, this server will receive the new client requests.
          </para>
          <para>
            The supported replication scenarios are shown in the following figure:
          </para>
          <para>
            <mediaobject>
              <imageobject>
                <imagedata align="center"
                           fileref="../../../../resources/images/clustering/jonas48repscenarios.jpg"
                           width="60%" scalefit="1">
                   <info>
                     <othercredit otherclass="srccredit" class="other">
                       <orgname>OW2</orgname>
                       <contrib>Replication scenarios in JOnAS 4.8</contrib>
                     </othercredit>
                   </info>
                </imagedata>
              </imageobject>
            </mediaobject>
          </para>
        </section>
        <section><info><title>Transaction aware fail-over</title></info>

          <para>
            The horizontal approach aims to guarantee that the transactions are kept consistent when a fail-over occurs. They are either aborted or restored for ensuring the exactly-once semantics. During a fail-over, the new primary uses a special table in the database for storing the transaction identifier and enabling to find out if the transaction was committed or not.
            <itemizedlist>
              <listitem><para>
                If  the transaction is aborted due to the primary failure, then the new primary will     not find the transaction identifier in the special table. The request will be replayed.
              </para></listitem>
              <listitem><para>
                If the transaction is committed, then the new primary will find the transaction identifier,     which means that the transaction was committed. The request won't be replayed; the replicated     result is returned.
              </para></listitem>
            </itemizedlist>
             Beyond the SFSB replication, the algorithm enables the building of applications (stateful or stateless) with a high level of reliability and integrity.
          </para>
        </section>
      </section>

    </section>
   </section>
  </section>

  <section><info><title>Configuring an EJB farm</title></info>

    <section><info><title>At the server side</title></info>
      <para>
        The setting of an EJB farm is achieved by
        <itemizedlist>
          <listitem>configuring the CMI service</listitem>
          <listitem>configuring the registry distribution</listitem>
          <listitem>configuring the EJB application</listitem>
        </itemizedlist>
      </para>

      <xi:include href="../../services/cmi/config.xml"/>

      <section><info><title>Registry distribution (server mode)</title></info>
        <para>
         By default, CMI relies on JGroups group-communication protocol for ensuring the global registry distribution. The parameters are gathered in the:
        </para>
        <itemizedlist>
          <listitem><para>
            $JONAS_BASE/conf/cmi-config.xml for specifying the JGroups configuration file name and the JGroups group name.
          </para></listitem>
          <listitem><para>
            $JONAS_BASE/conf/jgroups-cmi.xml file for the settings of the jgroups protocol stack. By default, the JGroups configuration uses the UDP
            protocol and the multicast IP for broadcasting the registry updates. A TCP-based stack can be used in a network environment that does not allow
            the use of multicast IP or when a cluster is distributed over a WAN.
          </para></listitem>
         </itemizedlist>
      <para>
        <mediaobject>
          <imageobject>
            <imagedata align="center"
                       fileref="../../../../resources/images/clustering/registry_replication.png"
                       width="60%" scalefit="1"/>
           </imageobject>
        </mediaobject>
      </para>
      <para>For example, the <literal>jgroups-cmi.xml</literal> file may contain the following stack configuration:</para>
  <example>
     <title>JGroups's configuration stack</title>
      <screen>
&lt;config&gt;
    &lt;UDP mcast_addr="224.0.0.35"
         mcast_port="35467"
         tos="8"
         ucast_recv_buf_size="20000000"
         ucast_send_buf_size="640000"
         mcast_recv_buf_size="25000000"
         mcast_send_buf_size="640000"
         loopback="false"
         discard_incompatible_packets="true"
         max_bundle_size="64000"
         max_bundle_timeout="30"
         use_incoming_packet_handler="true"
         ip_ttl="2"
         enable_bundling="true"
         enable_diagnostics="true"
         thread_naming_pattern="cl"

         use_concurrent_stack="true"

         thread_pool.enabled="true"
         thread_pool.min_threads="1"
         thread_pool.max_threads="25"
         thread_pool.keep_alive_time="5000"
         thread_pool.queue_enabled="false"
         thread_pool.queue_max_size="100"
         thread_pool.rejection_policy="Run"

         oob_thread_pool.enabled="true"
         oob_thread_pool.min_threads="1"
         oob_thread_pool.max_threads="8"
         oob_thread_pool.keep_alive_time="5000"
         oob_thread_pool.queue_enabled="false"
         oob_thread_pool.queue_max_size="100"
         oob_thread_pool.rejection_policy="Run"/&gt;

    &lt;PING timeout="2000"
            num_initial_members="3"/&gt;
    &lt;MERGE2 max_interval="30000"
            min_interval="10000"/&gt;
    &lt;FD_SOCK/&gt;
    &lt;FD timeout="2000" max_tries="3" shun="true"/&gt;
    &lt;VERIFY_SUSPECT timeout="1500"  /&gt;
    &lt;BARRIER /&gt;
    &lt;pbcast.NAKACK max_xmit_size="60000"
                   use_mcast_xmit="false" gc_lag="0"
                   retransmit_timeout="300,600,1200,2400,4800"
                   discard_delivered_msgs="true"/&gt;
    &lt;UNICAST timeout="300,600,1200,2400,3600"/&gt;
    &lt;pbcast.STABLE stability_delay="1000" desired_avg_gossip="50000"
                   max_bytes="400000"/&gt;
    &lt;VIEW_SYNC avg_send_interval="60000"   /&gt;
    &lt;pbcast.GMS print_local_addr="true" join_timeout="3000"
                join_retry_timeout="2000" shun="true" /&gt;
    &lt;SEQUENCER/&gt;
    &lt;FC max_credits="20000000"
                    min_threshold="0.10"/&gt;
    &lt;!--pbcast.STREAMING_STATE_TRANSFER use_reading_thread="true"/--&gt;
    &lt;pbcast.STATE_TRANSFER  /&gt;
    &lt;!-- pbcast.FLUSH  /--&gt;
&lt;/config&gt;
      </screen>
      </example>

     <note>You can find more information about JGroups and about the stack configuration
     <link xlink:href="http://www.jgroups.org">here</link>.</note>

      <para>
        All the members of a cluster share the same JGroups configuration.
      </para>
      <para>
        If several cluster partitions are required over a single LAN,
        several JGroups configurations must be configured with different values for the following parameters:
      </para>
      <itemizedlist>
        <listitem><para>
          JGroups group name
        </para></listitem>
        <listitem><para>
          JGroups multicast address
        </para></listitem>
        <listitem><para>
          JGroups multicast port
        </para></listitem>
      </itemizedlist>
      <para>
        When a new node appears in the cluster, its registry content is synchronized automatically.
      </para>
      <para>
        When a node disappears, JGroups notifies the other's member of the node leaving and the registry entries related to this node are removed.
      </para>
      </section>

      <section><info><title>Configuring an EJB application for Load-Balancing</title></info>

        <para>Informations must be put in the EJB meta-datas for clustering them.
        The following section gives a description of the clustering parameters of the EJBs and indicates how to
        configure the load-balancing algorithm.
        Afterwards, the different settings for EJB2 and EJB3 (specific deployment descriptor and/or annotation) are described.
        </para>


        	<section xml:id="cmi.ejb.parameters"><info><title>Overview</title></info>

       			<para>EJB meta-data for clustering contains the following parameters:

    				<informaltable>
      					<tgroup cols="2">
        					<tbody>
          						<row>
            						<entry align="center">Parameter</entry>

									<entry align="center">Description</entry>
          						</row>

          						<row>
            						<entry>name</entry>
            						<entry>specifies the cluster name associated with the EJB. This information is set for administration
									purpose. Default name is <literal>defaultCluster</literal>.</entry>
          						</row>
          						<row>
            						<entry>pool</entry>
            						<entry>describes the stubs pool configuration at the client side (one pool per EJB).
 										<itemizedlist>
											<listitem><literal>max</literal> : maximum size of the pool. Default is infinite.</listitem>
											<listitem><literal>max-waiters</literal>: maximum number of waiter threads. Default is infinite.</listitem>
											<listitem><literal>timeout</literal>: maximum time that a thread should wait for a resource in the pool (in ms).
											Default is infinite.</listitem>
										</itemizedlist>
            						</entry>
          						</row>
          						<row>
            						<entry>policy</entry>
            						<entry>specifies the load-balancing algorithm policy (POJO) used for the EJB.
						 			Built-in policies are provided. The user can provide its own implementation.</entry>
          						</row>
          						<row>
            						<entry>strategy</entry>
            						<entry>specifies the load-balancing algorithm strategy (POJO) used for the EJB.
						 			Built-in strategies are provided. The user can provide its own implementation.</entry>
          						</row>
          						<row>
            						<entry>properties</entry>
            						<entry>Set of properties that may be passed to the policy and/or strategy.
									The parameter is optional and is reserved for an advanced use. The parameter is not used by the built-in policies
									and strategies and may be read by the user policies and/or strategies.</entry>
          						</row>
          						<row>
            						<entry>replicated</entry>
            						<entry>boolean indicating whether the ejb is replicated or not. Not applicable in farming.</entry>
          						</row>

					        </tbody>
      					</tgroup>
   					 </informaltable>

  				</para>
			</section>

        	<section><info><title>Built-in policies and strategies</title></info>

        		<para>The following policies implementations are provided with JOnAS:
    				<informaltable>
      					<tgroup cols="2">
        					<tbody>
          						<row>
            						<entry align="center">Policy</entry>

									<entry align="center">Description</entry>
          						</row>

          						<row>
            						<entry><property>RoundRobin.class</property></entry>
            						<entry>round-robin algorithm, all the node are served sequentially.</entry>
          						</row>
           						<row>
            						<entry><property>Random.class</property></entry>
            						<entry>random algorithm, a node is chosen randomly.</entry>
          						</row>
          						<row>
            						<entry><property>FirstAvailable.class</property></entry>
            						<entry>first-available algorithm, at first a server is selected randomly and then is bound.</entry>
          						</row>
          						<row>
            						<entry><property>HASingleton.class</property></entry>
            						<entry>HA-singleton algorithm, all the clients are bound to the same server.</entry>
          						</row>

					        </tbody>
      					</tgroup>
   					 </informaltable>
				</para>

        		<para>The policies can be pointed out with some strategies:
    				<informaltable>
      					<tgroup cols="3">
        					<tbody>
          						<row>
            						<entry align="center">Strategy</entry>

									<entry align="center">Description</entry>

									<entry align="center">Applicable to policy</entry>

          						</row>

          						<row>
            						<entry><property>NoStrategy.class</property></entry>
            						<entry>no strategy, set by default.</entry>
            						<entry>All</entry>
          						</row>
           						<row>
            						<entry><property>LocalPreference.class</property></entry>
            						<entry>local preference, if present, a collocated server is selected.</entry>
            						<entry>RoundRobin, Random, FirstAvailable</entry>
          						</row>
          						<row>
            						<entry><property>LoadFactorWeight.class</property></entry>
            						<entry>add a weighted load factor to the policy, for example for specifying the weighted round-robin algorithm.</entry>
            						<entry>RoundRobin</entry>
          						</row>
          						<row>
            						<entry><property>LoadFactorSort.class</property></entry>
            						<entry>add a sorted load factor to the policy, for example for specifying the sorted round-robin algorithm.</entry>
            						<entry>RoundRobin</entry>
          						</row>

					        </tbody>
      					</tgroup>
   					 </informaltable>
				</para>
       	 	</section>
        	<section><info><title>User policies and strategies</title></info>

        		<para>CMI permits to provide its own policy and strategy. The POJO must implement CMI interfaces and
        		the classes must be deployed across the cluster.</para>

        		<section><info><title>User policy implementation</title></info>

        			<para>The policy must implement the <literal>org.ow2.cmi.lb.policy.IPolicy</literal> interface:</para>
        			<screen>
package org.ow2.cmi.lb.policy;

import java.lang.reflect.Method;
import java.util.Collection;

import org.ow2.cmi.lb.LoadBalanceable;
import org.ow2.cmi.lb.NoLoadBalanceableException;
import org.ow2.cmi.lb.decision.DecisionManager;
import org.ow2.cmi.lb.strategy.IStrategy;

/**
* Interface of the policies for load-balancing.
* @param &lt;T&gt; The type of object that was load-balanced
* @author The new CMI team
*/
public interface IPolicy&lt;T extends LoadBalanceable&gt; {

    /**
     * Chooses a load-balanceable among the list of load-balanceables.
     * @param loadBalanceables a list of load-balanceables
     * @throws NoLoadBalanceableException if no server is available
     * @return the chosen load-balanceable
     */
    T choose(Collection&lt;T&gt; loadBalanceables) throws NoLoadBalanceableException;

    /**
     * Return a strategy to modify the behavior of this policy.
     * @return a strategy to modify the behavior of this policy
     */
    IStrategy&lt;T&gt; getStrategy();

    /**
     * Sets a strategy to modify the behavior of this policy.
     * @param strategy a strategy of load-balancing
     */
    void setStrategy(IStrategy&lt;T&gt; strategy);

    /********************** Begin of callback definitions **********************/

    /**
     * Returns a decision when an exception is thrown during an access to a registry
     * for a given load-balanceable.
     * @param loadBalanceable the load-balanceable that have caused the exception
     * @param thr the exception that is thrown
     * @return the decision when an exception is thrown during an access to a registry
     * for a given load-balanceable
     */
    DecisionManager&lt;Void&gt; onLookupException(T loadBalanceable, Throwable thr);

    /**
     * Returns a decision when an exception is thrown during an invocation for a given
     * load-balanceable.
     * @param method the method that was invoked
     * @param parameters the parameters of the method
     * @param loadBalanceable the load-balanceable that have caused the exception
     * @param thr the exception that is thrown
     * @return the decision when an exception is thrown during an invocation for a given
     * load-balanceable
     */
    DecisionManager&lt;Void&gt; onInvokeException(Method method, Object[] parameters, T loadBalanceable, Throwable thr);

    /**
     * Return a decision when a server is chosen and its delegate retrieved.
     * @param &lt;ReturnType&gt; the type of delegate
     * @param method the method that was invoked
     * @param parameters the parameters of the method
     * @param chosenValue the delegate of chosen server
     * @return the decision when the server is chosen and its delegate retrieved
     */
    &lt;ReturnType&gt; DecisionManager&lt;ReturnType&gt; onChoose(Method method, Object[] parameters, ReturnType chosenValue);

    /**
     * Returns a decision when the invocation of a remote method ends.
     * @param &lt;ReturnType&gt; the type of the returned value
     * @param method the method that was invoked
     * @param parameters the parameters of the method
     * @param loadBalanceable the load-balanceable used for the invocation
     * @param retVal the returned value
     * @return the decision when the invocation of a remote method ends
     */
    &lt;ReturnType&gt; DecisionManager&lt;ReturnType&gt; onReturn(Method method, Object[] parameters, T loadBalanceable, ReturnType retVal);

}
        			</screen>


			        <para>CMI provides the <literal>org.ow2.cmi.lb.policy.AbstractPolicy</literal> abstract class for simplifying
			        the policies implementation. The user class can extend it and provides, at least, an implementation of the <literal>choose</literal>
			        method. Example for the round-robin implementation:</para>
  <example>
     <title>Round-robin policy in CMI</title>

			        <screen>
package org.ow2.cmi.lb.policy;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Random;

import net.jcip.annotations.ThreadSafe;

import org.ow2.cmi.lb.LoadBalanceable;
import org.ow2.cmi.lb.NoLoadBalanceableException;
import org.ow2.cmi.lb.strategy.IStrategy;
import org.ow2.cmi.lb.strategy.NoStrategy;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;
/**
 * The default load-balancing policy (Round Robin) that always chooses the next available load-balanceable.
 * @param &lt;T&gt; The type of objects that are load-balanced
 * @author The new CMI team
 */
@ThreadSafe
public final class RoundRobin&lt;T extends LoadBalanceable&gt; extends AbstractPolicy&lt;T&gt; {

    /**
     * Logger.
     */
    private static final Log LOGGER = LogFactory.getLog(RoundRobin.class);

    /**
     * Initial value of the pointer.
     */
    private static final int INITIAL_VALUE = -1;

    /**
     * The pointer to store the last ref.
     */
    private int pointer;

    /**
     * Random numbers.
     */
    private final Random rand = new Random();

    /**
     * Build the Round Robin policy.
     * Give to the pointer an initial value.
     */
    public RoundRobin() {
        pointer = INITIAL_VALUE;
    }

    /**
     * Chooses the next load-balanceable among the list of load-balanceables.
     * @param loadBalanceables the list of load-balanceables
     * @throws NoLoadBalanceableException if no server available
     * @return the chosen load-balanceable
     */
    @Override
    public synchronized T choose(final Collection&lt;T&gt; loadBalanceables) throws NoLoadBalanceableException{

        if (loadBalanceables == null || loadBalanceables.isEmpty()) {
            LOGGER.error("The given list is null or empty: " + loadBalanceables);
            throw new NoLoadBalanceableException("The given list is null or empty: " + loadBalanceables);
        }
        List&lt;T&gt; cmiRefsWithStrategy;

        IStrategy&lt;T&gt; strategy = getStrategy();

        if(strategy != null) {
            cmiRefsWithStrategy = strategy.choose(loadBalanceables);
            // If no server corresponds at this strategy, we don't use it
            if(cmiRefsWithStrategy.isEmpty()) {
                cmiRefsWithStrategy = new ArrayList&lt;T&gt;(loadBalanceables);
            }
        } else {
            cmiRefsWithStrategy = new ArrayList&lt;T&gt;(loadBalanceables);
        }

        int size = cmiRefsWithStrategy.size();
		if(pointer == INITIAL_VALUE){
            // The initial pointer depends on the strategy
            if(strategy != null &amp;&amp; !(strategy instanceof NoStrategy)) {
                // Use the first element chosen by the strategy
                pointer = 0;
            } else {
                // No strategy, choose randomly the first element
                pointer = rand.nextInt(size);
            }
        } else {
            // Perhaps some servers are disappeared, in this case the pointer can out of bounds
            if(pointer &gt;= size) {
                pointer = INITIAL_VALUE;
            }
            // Choose the next target
            pointer = (pointer + 1) % size;
        }
        return cmiRefsWithStrategy.get(pointer);
    }

    @Override
    public String toString() {
        return "RoundRobin[pointer: "
        + pointer + " - strategy: " + getStrategy() + "]";
    }

}			        </screen>
</example>

       	 		</section>
        		<section><info><title>User strategy implementation</title></info>

        			<para>The policy must implement the <literal>org.ow2.cmi.lb.strategy.IStrategy</literal> interface:</para>
        			<screen>
package org.ow2.cmi.lb.strategy;

import java.util.Collection;
import java.util.List;

import org.ow2.cmi.lb.LoadBalanceable;

/**
 * Interface of the load-balancing strategies.
 * A strategy allows to modify a list of load-balanceables before applying a policy to elect only one load-balanceable.
 * @param &lt;T&gt; The type of object that was load-balanced
 * @author The new CMI team
 */
public interface IStrategy&lt;T extends LoadBalanceable&gt; {

    /**
     * Returns a new list of load-balanceables by modifying the given list.
     * @param loadBalanceables a list of load-balanceables
     * @return a new list of load-balanceables by modifying the given list
     */
    List&lt;T&gt; choose(Collection&lt;T&gt; loadBalanceables);

}
        			</screen>
  <example>
     <title>Local preference strategy in CMI</title>
			        <para>Example for the local preference implementation:</para>

			        <screen>
package org.ow2.cmi.lb.strategy;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import net.jcip.annotations.Immutable;

import org.ow2.cmi.controller.client.ClientClusterViewManager;
import org.ow2.cmi.controller.common.ClusterViewManager;
import org.ow2.cmi.controller.server.ServerClusterViewManager;
import org.ow2.cmi.lb.LoadBalanceable;
import org.ow2.cmi.reference.ServerRef;
import org.ow2.util.log.Log;
import org.ow2.util.log.LogFactory;

/**
 * Defines a strategy that enable the local preference.
 * @param &lt;T&gt; The type of objects that are load-balanced
 * @author The new CMI team
 */
@Immutable
public final class LocalPreference&lt;T extends LoadBalanceable&gt; implements IStrategy&lt;T&gt; {

    /**
     * Logger.
     */
    private static final Log LOGGER = LogFactory.getLog(LocalPreference.class);

    /**
     * The manager of the cluster view.
     */
    private final ClusterViewManager clusterViewManager;

    /**
     * Constructs a strategy for load-factor.
     * @param clusterViewManager the manager of the cluster view
     */
    public LocalPreference(final ClusterViewManager clusterViewManager) {
        this.clusterViewManager = clusterViewManager;
    }

    /**
     * Returns a list of CMIReference that references the local servers.
     * @param cmiRefs a list of CMIReference
     * @return a list of CMIReference that references the local servers
     */
    public List&lt;T&gt; choose(final Collection&lt;T&gt; cmiRefs) {

        List&lt;T&gt; localServers = new ArrayList&lt;T&gt;();

        for(T cmiRef : cmiRefs) {

            // Gets the reference of server that have deployed the object
            ServerRef serverRef = cmiRef.getServerRef();

            //  Gets its address
            InetAddress inetAddress = serverRef.getInetAddress();

            try {
                // Checks if the addresses match
                if(isLocal(inetAddress)) {
                    // Local address: adds reference in the first position
                    localServers.add(cmiRef);
                }
            } catch (SocketException e) {
                LOGGER.error("Cannot know if is local or not", e);
                throw new RuntimeException("Cannot know if is local or not", e);
            }
        }
        return localServers;
    }

    /**
     * Tests if an address is local.
     * @param inetAddress an address
     * @return true if the given address is local
     * @throws SocketException if an I/O error occurs
     */
    private boolean isLocal(final InetAddress inetAddress) throws SocketException {

        if(clusterViewManager instanceof ClientClusterViewManager) {
            if(NetworkInterface.getByInetAddress(inetAddress)!=null) {
                return true;
            }
        } else if(clusterViewManager instanceof ServerClusterViewManager) {
            if(inetAddress.equals(((ServerClusterViewManager) clusterViewManager).getInetAddress())) {
                return true;
            }
        }
        return false;
    }

    @Override
    public String toString() {
        return "LocalPreference";
    }

}
			        </screen>
			        </example>

       	 		</section>
       			<section><info><title>User policy and strategy deployment</title></info>

        			<para>User policy and/or strategy must be deployed across all nodes of the cluster. For example, you can :
						<itemizedlist>
							<listitem>package the POJO in a jar file and put it in the <literal>$JONAS_BASE/lib/ext</literal> directory
							on each cluster member.
							</listitem>
							<listitem>package the POJO in a jar file and put it in a repository and deploy it through
							a deployment plan.</listitem>
						</itemizedlist>
					</para>
       	 		</section>

        </section>

        <section><info><title>Setting for an EJB2 application</title></info>

          <para>Clustering meta-datas must be added in the deployment descriptor.</para>

            <para>The JOnAS's deployment descriptor of an EJB 2.1 (session stateless, session stateful or entity) may contain the <literal>cluster-config</literal> element
            with the following entries. Refer to <xref linkend="cmi.ejb.parameters" /> for a precise information about the parameters.</para>
    			<informaltable>
      				<tgroup cols="2">
        				<tbody>
          					<row>
	            				<entry align="center">Element</entry>
								<entry align="center">Description</entry>
       						</row>

       						<row>
           						<entry><property>cluster-config/name</property></entry>
           						<entry>cluster name</entry>
       						</row>
       						<row>
           						<entry><property>cluster-config/pool</property></entry>
           						<entry>pool configuration with the following sub-elements
									<itemizedlist>
										<listitem><literal>max-size</literal></listitem>
										<listitem><literal>max-waiters</literal></listitem>
										<listitem><literal>timeout</literal></listitem>
									</itemizedlist>
           						</entry>
       						</row>
       						<row>
           						<entry><property>cluster-config/policy</property></entry>
           						<entry>load-balancing policy</entry>
       						</row>
       						<row>
           						<entry><property>cluster-config/strategy</property></entry>
           						<entry>load-balancing strategy</entry>
       						</row>
       						<row>
           						<entry><property>cluster-config/properties</property></entry>
           						<entry>parameters for a customized user load-balancing algorithm.
           						Example:


           						<screen>
&lt;cluster-config&gt;
...
    &lt;properties&gt;
        &lt;simple-property name="prop1" value="val1" /&gt;
        &lt;simple-property name="prop2" value="38" /&gt;
        &lt;array-property name="prop3"&gt;
            &lt;value&gt;true&lt;/value&gt;
        &lt;/array-property&gt;
        &lt;array-property name="prop4"&gt;
            &lt;value&gt;java.util.LinkedList&lt;/value&gt;
            &lt;value&gt;java.util.ArrayList&lt;/value&gt;
        &lt;/array-property&gt;
        &lt;array-property name="prop5"&gt;
            &lt;value&gt;http://carol.ow2.org&lt;/value&gt;
        &lt;/array-property&gt;
    &lt;/properties&gt;
&lt;/cluster-config&gt;

           						</screen>
           						</entry>
       						</row>

				        </tbody>
      				</tgroup>
   				</informaltable>

            <para>Example:</para>
  <example>
     <title>EJB2.1 deployment descriptor for clustering</title>
            <screen>
&lt;jonas-ejb-jar xmlns="http://www.objectweb.org/jonas/ns"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.objectweb.org/jonas/ns
      http://www.objectweb.org/jonas/ns/jonas-ejb-jar_5_1.xsd"&gt;

    &lt;jonas-session&gt;
        &lt;ejb-name&gt;MyEjb1SLR&lt;/ejb-name&gt;
        &lt;jndi-name&gt;MyEjb1Home&lt;/jndi-name&gt;
        &lt;min-pool-size&gt;3&lt;/min-pool-size&gt;
        &lt;cluster-config&gt;
        	&lt;name&gt;jonas-cluster&lt;/name&gt;
        	&lt;policy&gt;org.ow2.cmi.lb.policy.RoundRobin&lt;/policy&gt;
        	&lt;strategy&gt;org.ow2.cmi.lb.strategy.LocalPreference&lt;/strategy&gt;
        	&lt;pool&gt;
           		&lt;max-size&gt;10&lt;/max-size&gt;
            	&lt;max-waiters&gt;15&lt;/max-waiters&gt;
            	&lt;timeout&gt;2000&lt;/timeout&gt;
           &lt;/pool&gt;
       &lt;/cluster-config&gt;
    &lt;/jonas-session&gt;
&lt;/jonas-ejb-jar&gt;
            </screen>
            </example>
          </section>

        <section><info><title>Setting for an EJB3 application</title></info>

          <para>Clustering meta-datas can be added either through Java annotations or in the specific deployment descriptor.</para>

          <section><info><title>Java annotations</title></info>

          	<para>CMI provides the following annotations (Refer to the <xref linkend="cmi.ejb.parameters" />section for more information).</para>

    			<informaltable>
      				<tgroup cols="2">
        				<tbody>
          					<row>
	            				<entry align="center">Annotation</entry>
								<entry align="center">Description</entry>
       						</row>

       						<row>
           						<entry><property>@Cluster</property></entry>
           						<entry>Set the cluster name and the pool stubs configuration.
									Example:
									<screen>
@Cluster(name="test_cluster", pool=@Pool(max=2))
									</screen>
								</entry>
       						</row>
       						<row>
           						<entry><property>@Policy</property></entry>
           						<entry>Set the load-balancing algorithm policy.
									Example:
									<screen>
@Policy(RoundRobin.class)
									</screen>
								</entry>
       						</row>
       						<row>
           						<entry><property>@Strategy</property></entry>
           						<entry>Set the load-balancing algorithm strategy.
									Example:
									<screen>
@Strategy(LocalPreference.class)
									</screen>
								</entry>
       						</row>
       						<row>
           						<entry><property>@Properties</property></entry>
           						<entry>Set properties for user policies and/or strategies.
									Example:
									<screen>
@Properties(
  simpleProperties={
    @SimpleProperty(
      name="prop1",
      value="val1"),
    @SimpleProperty(
      name="prop2",
      value="38")},
  arrayProperties={
    @ArrayProperty(
      name="prop3"
      values="true"),
    @ArrayProperty(
      name="prop4",
      values={"java.util.LinkedList",
              "java.util.ArrayList"}),
    @ArrayProperty(
      name="prop5",
      values={"http://www.ow2.org"})})
									</screen>
								</entry>
       						</row>


				        </tbody>
      				</tgroup>
   				</informaltable>

            <para>The example below illustrates the use of the annotations for configuring a cluster named <literal>test_cluster</literal>.
            The <literal>round-robin</literal> algorithm is set by default.
            The complete code can be downloaded from the <link xlink:href="http://www.easybeans.net">EasyBeans</link> project</para>
  <example>
     <title>EJB3 SSB with clustering annotations</title>

            <screen>
package org.ow2.easybeans.examples.cluster;

import javax.ejb.Remote;
import javax.ejb.Stateless;

import org.ow2.cmi.annotation.Cluster;
import org.ow2.cmi.annotation.Policy;
import org.ow2.cmi.lb.policy.RoundRobin;
import org.ow2.easybeans.api.bean.EasyBeansBean;

@Stateless
@Remote(ClusterRemote.class)
@Cluster(name="test_cluster")
@Policy(RoundRobin.class)
public class ClusterBeanAN implements ClusterRemote {

    private String ezbServerDescription = null;

    public String getEZBServerDescription(final String msg) {

        if(this.ezbServerDescription == null) {
            this.ezbServerDescription =
                ((EasyBeansBean) this).getEasyBeansFactory().getContainer().getConfiguration().getEZBServer().getDescription();
        }
        System.out.println(msg);
        return this.ezbServerDescription + "\n";
    }
}
            </screen>
            </example>

          </section>
          <section><info><title>Specific Deployment descriptor</title></info>
            <para>The default clustering configuration can be overridden by a specific deployment descriptor.
            The file is named <literal>easybeans.xml</literal> and may contain the <literal>cluster:cluster</literal> element
            with the following entries. Refer to <xref linkend="cmi.ejb.parameters" /> for a precise information about the parameters.</para>
    			<informaltable>
      				<tgroup cols="2">
        				<tbody>
          					<row>
	            				<entry align="center">Element</entry>
								<entry align="center">Description</entry>
       						</row>

       						<row>
           						<entry><property>cluster:cluster/name</property></entry>
           						<entry>cluster name</entry>
       						</row>
       						<row>
           						<entry><property>cluster:cluster/pool</property></entry>
           						<entry>pool configuration with the following sub-elements
									<itemizedlist>
										<listitem><literal>max-size</literal></listitem>
										<listitem><literal>max-waiters</literal></listitem>
										<listitem><literal>timeout</literal></listitem>
									</itemizedlist>
           						</entry>
       						</row>
       						<row>
           						<entry><property>cluster:cluster/policy</property></entry>
           						<entry>load-balancing policy</entry>
       						</row>
       						<row>
           						<entry><property>cluster:cluster/strategy</property></entry>
           						<entry>load-balancing strategy</entry>
       						</row>
       						<row>
           						<entry><property>cluster:cluster/properties</property></entry>
           						<entry>parameters for a customized user load-balancing algorithm
           						Example:

           						<screen>
&lt;cluster:cluster&gt;
...
    &lt;properties&gt;
        &lt;simple-property name="prop1" value="val1" /&gt;
        &lt;simple-property name="prop2" value="38" /&gt;
        &lt;array-property name="prop3"&gt;
            &lt;value&gt;true&lt;/value&gt;
        &lt;/array-property&gt;
        &lt;array-property name="prop4"&gt;
            &lt;value&gt;java.util.LinkedList&lt;/value&gt;
            &lt;value&gt;java.util.ArrayList&lt;/value&gt;
        &lt;/array-property&gt;
        &lt;array-property name="prop5"&gt;
            &lt;value&gt;http://carol.ow2.org&lt;/value&gt;
        &lt;/array-property&gt;
    &lt;/properties&gt;
&lt;/cluster:cluster&gt;
								</screen>
           						</entry>
       						</row>

				        </tbody>
      				</tgroup>
   				</informaltable>

            <para>Example:</para>
  <example>
     <title>EJB3 deployment descriptor for clustering</title>
            <screen>
&lt;easybeans xmlns="http://org.ow2.easybeans.deployment.ejb"
	xmlns:cluster="http://org.ow2.cmi.info.mapping"&gt;
	&lt;ejb&gt;
 		&lt;session&gt;

			&lt;ejb-name&gt;clusterXMLBean&lt;/ejb-name&gt;
			&lt;cluster:cluster name="easybeans-cmi"&gt;
				&lt;cluster:policy&gt;org.ow2.cmi.lb.policy.FirstAvailable&lt;/cluster:policy&gt;
				&lt;cluster:strategy&gt;org.ow2.cmi.lb.strategy.LocalPreference&lt;/cluster:strategy&gt;
        	    &lt;pool&gt;
           		    &lt;max-size&gt;10&lt;/max-size&gt;
            	    &lt;max-waiters&gt;15&lt;/max-waiters&gt;
            	    &lt;timeout&gt;2000&lt;/timeout&gt;
                &lt;/pool&gt;
			&lt;/cluster:cluster&gt;
		&lt;/session&gt;
	&lt;/ejb&gt;
&lt;/easybeans&gt;
            </screen>
		</example>

          </section>

        </section>

      </section>

    </section>
    <section id="cmi.farming.client"><info><title>At the client side</title></info>

      <para>EJB clustering can be transparent for the client so that a client which is connected
      to a standalone server can be switched to a clustering mode without any configuration changes.
      </para>
      <para>
      However either for disabling CMI and for ensuring the JNDI availability, a CMI configuration
      can be required.</para>

          <section><info><title>Configuration file location</title></info>
      	    <para>Depending on the type of the client, the configuration is retrieved from:</para>
   				<informaltable>
      				<tgroup cols="2">
        				<tbody>
          					<row>
	            				<entry align="center">Type of client</entry>
								<entry align="center">Location of the configuration file</entry>
       						</row>

       						<row>
           						<entry><property>Java client</property></entry>
           						<entry>Pointed by the <literal>cmi.conf.url</literal> java property.
           						Example:
           						<screen>
java -jar myclient.jar -cp&lt;...&gt; -Dcmi.conf.url=/tmp/cmi-config.xml
           						</screen>

           						</entry>
       						</row>
       						<row>
           						<entry><property>JOnAS client (jclient)</property></entry>
           						<entry>Pointed by the <literal>cmi.conf.url</literal> java property.</entry>
       						</row>
       						<row>
           						<entry><property>Web tier client</property></entry>
           						<entry>In <literal>$JONAS_BASE/conf/cmi-config.xml</literal> file.</entry>
       						</row>

				        </tbody>
      				</tgroup>
   				</informaltable>

          </section>
          <section><info><title>Disabling CMI</title></info>
      	    <para>If the server side is configured with CMI, by default, the CMI client will
      	    switch to the cluster mode and will perform a load-balancing. For administration
      	    purpose or application requirements as well, one may want to
      	    enforce the client not to use the clustering mode. There are two different settings
      	    for doing that:
            </para>
   				<informaltable>
      				<tgroup cols="2">
        				<tbody>
          					<row>
	            				<entry align="center">Setting</entry>
								<entry align="center">Description and example</entry>
       						</row>

       						<row>
           						<entry><property>Java property</property></entry>
           						<entry>The <literal>cmi.disabled</literal> java property must be set to <literal>true</literal>.
           							<screen>
jclient -jar myclient.jar -Dcmi.disabled=true
           							</screen>

           						</entry>
       						</row>
       						<row>
            					<entry><property>CMI configuration file</property></entry>
           						<entry>The client part of the configuration file must contain the <literal>noCmi</literal> attribute set to <literal>true</literal>.
           							<screen>
&lt;cmi xmlns="http://org.ow2.cmi.controller.common"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
    &lt;client noCmi="true" /&gt;
&lt;/cmi&gt;
           							</screen>

           						</entry>
           					</row>

				        </tbody>
      				</tgroup>
   				</informaltable>
          </section>
           <section><info><title>Cluster view manager fail-over</title></info>
      	    <para>CAROL is a the JOnAS's protocol abstract layer
      	    and the <literal>carol.properties</literal> indicates the default protocol and the registry URL.
      	    The client retrieves the cluster view from the server side. By default it gets in
      	    touch with the server identified by the CAROL configuration.
      	    For ensuring high availability of the service, a list of cluster view manager URLs can be provided to the client
      	    through the CMI configuration file.  Refer to <xref linkend="services.cmi.config" /> for a precise information
      	    about the setting.

      	    Example:
      	    </para>
  <example>
     <title>CMI configuration at the client side</title>
          							<screen>
&lt;cmi xmlns="http://org.ow2.cmi.controller.common"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;

    &lt;client noCmi="false"&gt;
    	&lt;jndi&gt;
        	&lt;protocol name="jrmp"&gt;
            	&lt;providerUrls&gt;
                	&lt;providerUrl&gt;rmi://localhost:1099&lt;/providerUrl&gt;
                	&lt;providerUrl&gt;rmi://localhost:2001&lt;/providerUrl&gt;
            	&lt;/providerUrls&gt;
        	&lt;/protocol&gt;
    	&lt;/jndi&gt;
    &lt;/client&gt;
&lt;/cmi&gt;
           							</screen>
           				</example>
           <para>A first available policy with local preference is applied for selecting a provider URL.
           If the primary gets unavailable, a secondary is selected randomly at fail-over.
           </para>

           <note>In the case of a web tier which acts as a CMI client (CMI service with client mode), a list of provider URLs must be
           specified in the <literal>$JONAS_BASE/conf/cmi-config.xml</literal> file.
           </note>
          </section>
    </section>

    <section><info><title>Summary</title></info>
        <section><info><title>CMI configuration for a 2-tiers architecture (server mode)</title></info>
        	<mediaobject>
        		<imageobject>
          			<imagedata align="center"
                     		   fileref="../../../../resources/images/clustering/cmi_cluster_config_2tiers_server.png"
                     		   width="70%" scalefit="1">
          			</imagedata>
       			</imageobject>
      		</mediaobject>
      	<para>Use case : fits with the most use and is the default configuration. A CMI view manager is started in each node.</para>
    	</section>
       <section><info><title>CMI configuration for a 2-tiers architecture (client mode)</title></info>
        	<mediaobject>
        		<imageobject>
          			<imagedata align="center"
                     		   fileref="../../../../resources/images/clustering/cmi_cluster_config_2tiers_client.png"
                     		   width="80%" scalefit="1">
          			</imagedata>
       			</imageobject>
      		</mediaobject>
      	<para>Use case : when a local view manager is not acceptable regarding the resources consumptions or the network configuration.</para>
    	</section>
        <section><info><title>CMI configuration for java client</title></info>
        	<mediaobject>
        		<imageobject>
          			<imagedata align="center"
                     		   fileref="../../../../resources/images/clustering/cmi_cluster_config_javaclient.png"
                     		   width="80%" scalefit="1">
          			</imagedata>
       			</imageobject>
      		</mediaobject>
      	<para>Use case : fat EJB client.</para>
    	</section>
    </section>

  </section>
  
  <section><info><title>Configuring an EJB distribution</title></info>
    <para>
      The setting of an EJB distribution is achieved by
      <itemizedlist>
        <listitem>configuring the CMI service</listitem>
        <listitem>configuring the registry distribution</listitem>
      </itemizedlist>
    </para>
    <para>
      The EJB application doesn't need to be modified.
    </para>
  </section>
  
  <section><info><title>Configuring an EJB cluster</title></info>
    <section><info><title>At the server side</title></info>

    <section><info><title>Configuring JOnAS for EJB Replication</title></info>

      <para>
        The High Availability (HA) service is required in JOnAS in order to replicate SFSBs. The HA service must be included in the list of available services in JOnAS.
        This is done in the jonas.properties file located in $JONAS_BASE/conf.
      </para>
      <screen>
...
jonas.services registry,jmx,jtm,db,dbm,security,wm,wc,resource,cmi,ha,ejb2,ejb3,ws,web,ear,depmonitor
...      </screen>
      <para>
        The HA service must also be configured in the jonas.properties file:
      </para>

      <xi:include href="../../services/ha/config.xml"/>

      <para>
        The HA service uses JGroups as a group communication layer (GCL). JGroups behavior is specified by means of a stack of properties configured through
        an XML file (See JGroups documentation for more information: http://www.jgroups.org).
        The default configuration of the HA service uses the $JONAS_BASE/conf/jgroups-ha.xml file and the jonas-rep group name.
        The HA service can be told to use a particular stack configuration or a particular group name by modifying the following parameters:
      </para>
      <screen>
...
jonas.service.ha.jgroups.conf jgroups-ha.xml
jonas.service.ha.jgroups.groupname jonas-rep
...      </screen>

    </section>
    <section><info><title>Transaction Table Configuration</title></info>

      <para>
        The horizontal replication algorithm uses a database table to keep track of current running transactions.
        This table is accessed from the new elected node during fail-over to detect whether or not the current
        transaction has committed at the former local node, ensuring
        exactly-once
         semantics. The table contains only one column: the transaction identifier (txid).
      </para>
      <para>
        In JOnAS 4.8 this table must be created manually with the following SQL command:
      </para>
      <screen>
create TABLE ha_transactions (txid varchar(60));      </screen>
      <para>
        This table should be located preferably in the database used by the replicated application, but it is not mandatory. If the table is not created in the database used by the replicated application, it is necessary to configure a new datasource for the database that contains this transaction table. This datasource must be configured to use the
        serializable
         transaction isolation level.
      </para>
      <para>
        The database that holds the transaction table is accessed by the replication service with the JNDI name configured in jonas.properties.
      </para>
      <screen>
...
jonas.service.ha.datasource tx_table_ds
...      </screen>
    </section>
    <section><info><title>Configuring Garbage Collection</title></info>
      <para>
       Due to the fact that the replication algorithm stores information associated with clients' transactions and that the server is not notified when a client dies, the HA service might have been storing unnecessary replication information over time. In order to automatically clean this unnecessary replication information, the HA service includes a garbage collection mechanism. It is possible to configure the number of seconds the system waits to execute this mechanism by changing the following property in the jonas.properties file: </para>
      <screen>
...
jonas.service.ha.timeout 600
...      </screen>
    </section>
    <section><info><title>Configuring an EJB2 application for Replication</title></info>

      <section><info><title>jonas-ejb-jar.xml</title></info>

        <para>
          In order to configure an application for replication, the &lt;cluster-replicated/&gt; element must be added
          to the bean definition of every bean requiring high availability in the jonas-ejb-jar.xml deployment descriptor file.
          This element can have two possible values: true or false (default value).
          In addition, if the programmer wants to change the behavior of the CMI proxy (e.g., the server selection policy),
          it is possible to specify different policy implementations by means of &lt;cluster-config/&gt; elements.
        </para>
        <para>
          The following is an example description for a replicated SFSB in jonas-ejb-jar.xml file:
        </para>
  <example>
     <title>EJB2.1 deployment descriptor for session replication</title>
        <screen>
...
&lt;jonas-session&gt;
   &lt;ejb-name&gt;DummySFSB&lt;/ejb-name&gt;
   &lt;jndi-name&gt;DummySFSB&lt;/jndi-name&gt;
   ...
   &lt;cluster-replicated&gt;true&lt;/cluster-replicated&gt;
   &lt;cluster-config&gt;
       &lt;name&gt;jonas-cluster&lt;/name&gt;
       &lt;policy&gt;org.ow2.cmi.lb.policy.RoundRobin&lt;/policy&gt;
       &lt;strategy&gt;org.ow2.cmi.lb.strategy.LocalPreference&lt;/strategy&gt;
       &lt;pool&gt;
           &lt;max-size&gt;10&lt;/max-size&gt;
           &lt;max-waiters&gt;15&lt;/max-waiters&gt;
           &lt;timeout&gt;2000&lt;/timeout&gt;
       &lt;/pool&gt;
   &lt;/cluster-config&gt;
   &lt;is-modified-method-name&gt;true&lt;/is-modified-method-name&gt;

 &lt;/jonas-session&gt;
...        </screen>
</example>
        <para>
          The &lt;cluster-replicated/&gt; element can also be set in the SSB or EB for
          <itemizedlist>
            <listitem><para>
              enabling the transaction checking mechanism ensuring the exactly-once semantic at fail-over
            </para></listitem>
            <listitem><para>
              supporting the EB references replication
            </para></listitem>
          </itemizedlist>
        </para>
        <para>
          Note: When set in the SSB, the mechanism inhibits the load-balancing at the remote interface.
          After the home create() method call, all the requests are sent to the same instance.
        </para>
      </section>
      <section><info><title>Entity Beans lock policy</title></info>

        <para>
          The lock policy for the Entity Beans in a replicated application must be configured as
          database
           in the jonas-ejb-jar.xml deployment descriptor file.
        </para>
        <para>
          The following is an example description for a replicated EB, i.e. an entity that is accessed from a replicated SFSB, in the jonas-ejb-jar.xml:
        </para>
        <screen>
...
&lt;jonas-entity&gt;
    &lt;ejb-name&gt;MyEntitySLR&lt;/ejb-name&gt;
    &lt;jndi-name&gt;MyEntityHome&lt;/jndi-name&gt;
    &lt;cluster-replicated&gt;true&lt;/cluster-replicated&gt;
    &lt;shared&gt;true&lt;/shared&gt;
    &lt;jdbc-mapping&gt;
        &lt;jndi-name&gt;example_ds&lt;/jndi-name&gt;
    &lt;/jdbc-mapping&gt;
    &lt;lock-policy&gt;database&lt;/lock-policy&gt;
&lt;/jonas-entity&gt;
...        </screen>
      </section>
      <section><info><title>Datasource used by the application</title></info>

        <para>
          The datasources used by replicated applications must be configured to use the
          serializable
           transaction isolation level.
        </para>
        <para>
          The following is an example for a datasource configuration file for the Postgres DBMS:
        </para>
        <screen>
...
datasource.name         example_ds
datasource.url          jdbc:postgresql://xxx.xxx.xxx.xxx:xxxx/database
datasource.classname    org.postgresql.Driver
datasource.username     jonas
datasource.password
datasource.mapper       rdb.postgres
datasource.isolationlevel       serializable
...        </screen>
        <para>
          Finally, when compiling the application that includes the replicated beans, the CMI protocol must be specified in order to generate the classes that include the replication logic.
        </para>
      </section>
    </section>

    </section>
    <section><info><title>At the client side</title></info>
      <para>As for the farming, the cluster mode can be transparent for the client configuration apart for
      the expected high availability of the CMI internals service. In particular the CMI cluster view
      manager client part must be configure with a list of provider urls in order to be able to take-over
      when a server node failure occurs.
      Refer to <xref linkend="cmi.farming.client" /> for a precise information about the setting.
      </para>

    </section>
  </section>

</section>
