Monday, 12 August 2013

HTML5 support in JSF 2.2 with Bean Validation 1.1 (JavaEE 7)

In this post i will show the HTML5 Support given by JSF 2.2, Which is part of Java EE 7 Spec. Also how to integrate the Bean Validation 1.1 feature with help of CDI (Contexts and Dependency Injection) 1.1 spec.

Before going the HTML5 support, my earlier posts on JSF, i used @ManagedBean annotation, because its part of Managed Bean Specification (Java EE 6). Another Reason i used Tomcat as a primary container, if i used Managed Bean Spec then its part of Mojjara implementation, so no need to add more CDI specific (Jboss Weld lib) lib to class-path.

But from Java EE 7 on-wards, JCP community expand the CDI capabilities and make CDI as important spec in Java EE 7 and Managed Bean spec is deprecated in favor of CDI . so they recommend to use CDI wherever its possible. so our future all post to target the CDI. next post i will show how add the CDI capability to tomcat container.

So as part of CDI we need to use 
@Named annotation. Its equal to  @ManagedBean annotation, but its CDI Specific and all life cycle of the beans takes care by CDI container.
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@Named
@SessionScoped
public class DemoBean implements Serializable{
    
}


HTML5

            HTML5 is future of web standard, its provide lots of capability to browser like Full multimedia (audio and video playback), access the local resources like camera, microphone, Geolocation.
for more information check these resources

HTML5 Form elements are part of this features. This feature enable to the website without any 3rd party JavaScript framework to get fields/widgets like date picker, color picker, Check the sample page here


HTML5 Support in JSF2.2

           In JSF 2.0/2.1, its not supporting HTML5 form elements, the reason is HTML render-kit, which is part of JSF Implementation is not aware the HTML 5 elements or attributes. so even we put these attributes like placeholder, type=date, these Render-kit it just ignore while generating the HTML for client request. In that case there is 3rd party plugin called OmniFaces provides the Render-kit to support the HTML5 in JSF 2.0/2.1.

In JSF 2.2 onward's, HTML5 support internally as part of the Framework. The big issue is HTML5 attributes are we can't count or categorized. for example any input tag we add the data-* as attribute like data-theme, data-highlight, etc..  so we need to do some way to classify these attribute. That way is called "Pass through".

For eample i want to add one HTML5 input tag like this

<input type="text" placeholder="Enter your Name" />

here i want to convert this tag to JSF tags, because i want to bind this tag to my backing bean then 

<h:inputText  p:placeholder="Enter your Name" />


here
h: is prefix for normal HTML components, but p: is prefix for pass through.

 Like we can add the HTML5 Date picker componet

Original HTML5 Code :
<input type="date" />

JSF2.2 Code : 
<h:inputText  p:type="date" />


Check the Video below, for more information and step - by step

Add Validation

       Now we got HTML5 Form elements in our projects, we need to validate what user entered, for this purpose either we used client side validation or server side validation.

Client side validation is faster and good. but if somebody disable the JavaScript and submit the form then big problem. so we need server side validation also important. In server side we manually validate these fields.

Java EE 7 gives updated Bean Validation 1.1 spec for this purpose. These Bean validations are declarative way we can specify and validate by the system. so its very cool feature.

For example i asked user name to client, now client entered some value, now i need to validate its should not be null and its satisfy my other requirements like at-least 5 char for name like this

so usually what we do we put if condition like this

if(name !=null && "".equals(name.trim())  && name.length>5)
{
          // some logic
}

these kind of statements needed for all fields. But if we using Bean Validation then its simple.

open the backing bean and mark the fields with constraint annotation

public class DemoBean {
     @NotEmpty
     private String name;

     @NotNull
     @Past
     private Date dob;


     @Email    
     private String email;

     // Getter and Setters
}

When the the form is submit, then CDI called the bean validation features in transparent manner. If any validation is failed then its add those messages into faces context. so we can see those messages in that page.


Bean Validation applicable not only bean fields, Its have capability to validate the method arguments and its return type. This is grate features of bean validation.

    @NotNull
    public String method1( @NotNull String name, @Size(min=5) String lastName)
     {
          //logic

          return somevalue;
     }

Now when we call this method through CDI, these validation are applied.

Twitter BootStrap Theme

        I make one small example of HTML5 support and Bean validation, i used some free template based on Twitter bootstrap.  these are the refernce


In last link we can learn the twitter bootstrap in depth.

Check the video for small demo code combine HTML5 Support + Bean Validation + Twitter Bootstrap Theme. (Watch it in HD mode)


Demo Code is available in my
Github or u can download zip from here

Screen Cast :

Tuesday, 4 June 2013

File Upload is Easy in JSF2.2

To bring the File Upload feature in Java based web application is one of the difficult and complex job, we need to dependent on 3rd party libraries like Apache Commons FileUpload  Libraries. These libraries codes are complex and most of them boilerplate code.

If we are using Java Server Faces (JSF), we have the page with some fields and file upload menu the its add more complexity, fields are binded to backing bean but these file uploads components are need to tie up with some 3rd party file upload libraries.

In Primefaces provide easy way to do the file upload in JSF web application, even though primefaces internally used the same Apache Commons FileUpload Libraries, but provide simple JSF tags. We need configure  some listeners.

In Servlet 3.0 they introduced the
Part Interfaces and @MultiPartConfig annotations for easy way to do the file upload without any 3rd party libs, Servlet 3.0 is part of Java EE 6 specification. so any servlet 3.0 implementation servers  like Tomcat 7, Jboss 6, GlassFish 3 they can get benefit of servlet 3.0. but this feature is not available in JSF 2.1. so again still it's complex to use file upload in JSF, because we need to mix servlet and JSF backing bean.

Recently JSF 2.2 is released as part of Java EE 7 specification. Now this specs are final and its going to release Q2 of 2013.

Check my post about An introduction to JSF 2.2

in this post i going to show the File Upload feature with a demo

At last JSF 2.2 is added the File Upload component, so we just use <h:inputFile> tag to make the file upload web application so easily, and this component use the Part interface, which its introduced its part of Servlet 3.0. so this JSF2.2 libraries is working perfectly with Tomcat 7 (because tomcat 7 is implemented the Servlet 3.0 spec).

To bring the File Upload feature we need to follow 3 step process

  1. Add <h:inputFile> tag in JSF page
  2. Add enctype="multipart/form-data" attribute in enclosing <h:form> tag
  3. Create the field in Backing bean with Part data type.

Setup the Environment

JSF 2.2 lib are part of Java EE 7, but we can include as a libraries into existing Java EE 6 platform without upgrading the server.
we can get the JSF 2.2 libraries (
Mojarra implementation) from here

Step 1:  Add <h:inputFile> tag in JSF page

In JSF page add the <h:inputFile> tag where we need file upload component

<h:inputFile value= "#{demoBean.file1}" />

here i bind the value property to file1 field, which data type is Part, check the third step


Step 2:  Add enctype="multipart/form-data" attribute in enclosing <h:form> tag

When u want file upload feature then we need to inform the browser that form may contain multiple normal text input field  and some file upload component, so prepare the POST request in special form, like parts by part with special delimiter boundary.
<h:form enctype= "multipart/form-data" >
</h:form>

so index.xhtml file looks like
    
        Hello from Facelets
        
        



Step 2:  Create Backing Bean

now create the backing bean for this page. we need to create the fields for input File component with Part type. Part interface is introduced in servlet 3.0 for represent the file chunks sent by browser, JSF 2.2 use this Part interface, Using the Part interface we can get the header information of each file chunk sent by browser, these header contain the file name and other meta information about the file.

Part interface also contain write() method to write the file contents into specified server location, or u can get the InputStream then we can process it.

DemoBean.java

import java.io.IOException;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.servlet.http.Part;


/**
 *
 * @author ramki
 */
@ManagedBean
@SessionScoped
public class DemoBean {

    private Part file1;
    private Part file2;

    // getters and setters for file1 and file2

    public String upload() throws IOException {
         InputStream inputStream = file1.getInputStream();        
        FileOutputStream outputStream = new FileOutputStream(getFilename(file1));
        
        byte[] buffer = new byte[4096];        
        int bytesRead = 0;
        while(true) {                        
            bytesRead = inputStream.read(buffer);
            if(bytesRead > 0) {
                outputStream.write(buffer, 0, bytesRead);
            }else {
                break;
            }                       
        }
        outputStream.close();
        inputStream.close();
       
        return "success";
    }

    private static String getFilename(Part part) {
        for (String cd : part.getHeader("content-disposition").split(";")) {
            if (cd.trim().startsWith("filename")) {
                String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\') + 1); // MSIE fix.
            }
        }
        return null;
    }
}


here we need get the file name from the Header of the chunk, so there is boilerplate code can do, here i don't like this method :-(

there is no direct method to retrieve the file name. so use this code we can get the name of the file is uploaded by client, then using write method we can store into server.


Get my sample project from my
Github or download from here

For more information (step by step) see the screencast

Screencast

An Introduction to JSF 2.2

Recently Java EE 7 specification goes into final. Next week (June 12) oracle going to release the Java EE 7 specification and Glass Fish 4 as reference implementation to general availability.

Java EE 7 adds more features like JSF 2.2, Servlet 3.1, Json Processing, websocket support, etc..
click here about the spec.

In this post i'm going walk through in JSF 2.2

JSF 2.2 is added more features, and JSF as  a main presentation layer of Java EE platform. compare to JSP, jsp is not getting more feature, they just add maintenance release.

Features of JSF 2.2

  • File Upload Component
  • Faces Flow
  • HTML5 Support
  • Cross Site Request Forgery Protection (CSRF)
  • Multi-Templating

File Upload Component


This is most awaited feature in JSF, now we can build the file upload feature in web application without any 3rd party libraries.

i am going to cover this topic in another post.

Faces Flows


Faces flows provides to create the JSF web application in modular way, each module is self contained pages , own backing beans and entry and exit points. Its make the module more reusable.

Faces flows are inspired from Spring Web Flows and Oracle Task Flows

Arun Gupta described his post about Faces Flows

HTML5 Support


HTML5 is future of the web, old JSF libraries are doesn't support HTML5 tags and attributes like placeholder attribute in input field tag, etc.
  <h:inputText   value="#{backingBean.field}"   p:placeholder="Enter text"  />

Cross Site Request Forgery Protection (CSRF)


CSRF is one kind of security attack, Its make the request on existing session.

For example i opened the Tomcat Manager web application and i logged in, now i try to open another web site in different tab, now that website try to execute the code like
http://localhost:8080/manager/html/stop?path=/app1

then browser make the request to that server (localhost:8080), browser already have session, so that server stop the application.

so we need to add CSRF protection token for every request, if token is not found or invalid then that request is not proceed further, server ignores the request

tomcat 7 uses own CSRF token
http://localhost:8080/manager/html/stop?path=/app1&org.apache.catalina.filters.CSRF_NONCE=CEF9F082EF983140038CF804CA81F29E

here tomcat 7 adds the CSRF token

now JSF 2.2 we can declaratively add the CSRF token to protecting the resources from CSRF attacks


Multi - Templating


Multi Templating is another feature to add more templates (Layout, skins), to web applications.
so we can change the template in run time like wordpress we can change the themes,
just put the theme jar file in classpath, Java platform discovered and apply the templates.


If u have any comments welcomed






Monday, 28 January 2013

Tomcat Clustering Series Part 5 : NginX as Load Balancer

Hi this is my fifth part of the  Tomcat Clustering Series . In this post we are going to discuss how to replace Apache httpd load balancer to Nginx as a load balancer.  [Check the video below for better understanding]

Hi i finished
Tomcat Clustering Series . In these series we have 2 big setups needed for Tomcat Clustering
  1. Setup and configure the Load Balancer
  2. Configure the Session Replication in Tomcat.




In first setup, we configure the Load Balancer using Apache httpd web server. Its open source and widely used.
Second setup is session replication in Tomcat through modify/add <cluster> tag in server.xml file. These tomcat instance may run on single machine or different machine.



In our Tomcat Clustering Series, the big part is configure the Load balancer (Apache httpd web server). Because there are lots of steps are involved
  1. Install the Apache httpd web server from either source or repo
  2. Compile and install the mod_jk connector
  3. Create the workers.properties file (add tomcat IP and ajp port information )
  4. Configure into httpd.conf file (Add mod_jk related settings)
these setups are take more time and very difficult to debug.

Is there is any alternative to load balancer?
    Yes, Nginx its emerging web server. this post we are going to discuss how to setup nginx as a load balancer in our tomcat cluster.

What is Nginx?
      Nginx is open source and alternative to Apache httpd web server. Its provide more performance and little memory foot print.

Install Nginx
    we can install nginx through either repository (apt-get,yum) or from source. here i m build nginx from source from here. then extract the compressed file.
./configure --help      
above command shows possible command line options available for compile
for install use this command
./configure   --prefix=/home/ramki/nginx   --with-http_ssl_module     
here
--prefix used to specify where nginx server want to install, here i m using my home folder (like /usr/local/nginx)
--with-http_ssl_module here i specified install SSL module (https), its not necessary. If we want secure webpage then this module is needed.

then compile the source
 make      

install the nginx based on our configuration
sudo make install     

now installation is done, To start the nginx
cd /home/ramki/nginx/sbin   
sudo ./nginx     

now open browser and go to http://localhost to get nginx default page.

To stop the nginx, we need to pass stop signal via -s option
sudo ./nginx  -s stop     

Configure as a Load Balancer
     Nginx configurations are stored in nginx.con file in conf/ folder.  We need to perform 2 steps to make nginx as load balancer.

First define Upstream block in nginx.conf file

            Upstream block provides simple load-balancing across upstream (backend) servers. In upstream block have unique name (here  tomcatcluster), later we need to point out from other block.

       upstream tomcatcluster  {
                server 127.0.0.1:8181;
server 127.0.0.1:8282;
server 127.0.0.1:8383;
         }

here we define the back-end servers (Tomcat instances) via server directive.
In each server directive we mention IP address of server and HTTP port number(Not AJP port number). 

Second forward (proxy) the request to back-end servers

             This step is forward the request to upstream blocks, where we define the back end servers.

 location / {
             proxy_pass http://tomcatcluster;
        }   

here if location / is already present, then remove and add this new one.

here proxy_pass directive, proxifier(forward) the requests to upstream servers. here tomcatcluster is name of the upstream block and we used http protocol to forward the request.

that's it. Load balancer is ready.

now start the tomcat instances based on my previous post (session replication). then start nginx.
now access http://localhost.

now nginx forward the request in round robin fashion to back-end servers. all servers have the session, so it can able to process the request

This is same as non-sticky session method we used in my previous posts.


If we want sticky session, then nginx directly not provide, but some 3rd party patches are available. but nginx provide ip_hash directive. Its forward all request from single IP to same tomcat like sticky session. But sticky session works based on cookie (session). but ip_hash is based on IP address of client.

If u want to configure ip_hash, then modify the upstream block, add ip_hash

upstream tomcatcluster  {
                ip_hash;
                server 127.0.0.1:8181;
server 127.0.0.1:8282;
server 127.0.0.1:8383;
         }

just restart the server, u feel like sticky session concept.

when we compare the Nginx to Apache httpd web server, nginx is provide simple configuration, and can handle huge amount of traffic, consume little memory foot print and its take little CPU load.
search Nginx vs Apache we get some amazing benchmark results. 

Screen Cast :



Wednesday, 5 December 2012

Tomcat Clustering Series Part 4 : Session Replication using Backup Manager

Hi this is my fourth part of the Tomcat Clustering Series. In this post we are going to discuss the how to setup session replication using Backup Manager in tomcat clustering environment. Session replication makes High availability and full fail-over capability to our clustering environment.[Check the video below for better understanding]

Its continuation of the last post (session replication using Delta Manager). In delta manager each tomcat instance need to replicate the session information to all other tomcat instances. Its take more time and replication if our cluster size is increased. so there is alternative manager is there. Its Backup Manager.

Backup Manager is replicate the copy of session data to exactly one other tomcat instances. This big difference between both managers. here which tomcat creates that is primary copy of the session. and another tomcat whose hold the replicate session is backup copy. If any one of the tomcat is down. back up tomcat serve the session. Its achieve the fail over capability.

The setup process of backup manager is same as Delta manager. except we need to mention the Manager as BacupManager (org.apache.catalina.ha.session.DeltaManager)  inside <Cluster> element.


Suppose we have 3 tomcat instances like previous post. and i configured into backup manager.

now user try access the page. User request comes to load balancer, and load balancer redirect the rquest to suppose tomcat1. Now tomcat one create the session, now tomcat1 is responsible to replicate exactly one copy to any one of the tomcat. so tomcat1 picks any tomcat which is part of the cluster (multicast). here tomcat1 picks tomcat3 as a backup. so tomcat3 hold the backup copy of the session.

we are run the load balancer in sticky session mode. so all further request from that particular user  is redirect to tomcat1 only. all modification in tomcat1 is replicate to tomcat3.

now tomcat1 is crashed/shutdown for some reason



now same user try to access the page. this time load balancer try to redirect to tomcat1. but tomcat1 is down. so load-balancer pick one tomcat from the remaining tomcats. here interestingly 2 case are there.

Case 1:

  Suppose Load balancer pick the tomcat3 then tomcat3 receive the request and tomcat3 itself hold the backup copy of the session. so tomcat3 make that session as primary copy and tomcat3 pick any one tomcat as backup copy. so here remaining only one tomcat is there. so tomcat3 replicate the session to tomcat2. so now tomcat3 hold primary copy and tomcat2 hold the backup copy. now tomcat3 give the response to user. all further request is handled by tomcat3 (sticky session).

case 2:

 Suppose Load balancer pick the tomcat2 then tomcat2 receive the request and tomcat2 don't have the session. so tomcat2 session manager (Backup Manager) ask to all other tomcat manager "hi anybody hold the session for this user (based on session id [cookie])". Actually tomcat3 have the backup session. so tomcat3 inform to tomcat2. and replicate the session to tomcat2. now  tomcat2 make that session as primary copy and tomcat3 whose already have copy of session as remains as a backup copy of that session. so now tomcat2 hold primary copy and tomcat3 hold the backup copy. now tomcat2 give the response to user. all further request is handled by tomcat2 (sticky session).

so in either case our session is replicate and maintained by backup manager. Its good for large cluster.
check the video below

check my configuration in my github repo or get as ZIP file


Note:


Load balancer also faces single point failure. to resolve this we need to put another load balancer with public address and update the new IP to DNS server with same URL. so our URL like example.com query resolves the 2 IP address for 2 load balancer.

How its work:-
-> If browser want to access http://example.com then it first ask DNS server.
-> DNS server gives 2 IP address to browser
-> Browser take the first IP address and try to connect.
-> If in the case that server is failed to respond then browser side make timeout
-> then browser contact second IP address, now second load balancer is works fine.

This kind of adding more load balancer makes to our website more scalable and reliable in case of tragedy.

check in ur terminal

>     nslookup google.com      

its gives 11 IP address. these all are google load balancer's located in various geographic locations


Another thing this DNS servers not return same order of IP list to browser. each an every time its rotate(round robin) the IP list. so in 2 different machine ask google.com get different order of IP list. so these 2 differnt machine connect different google load balancer. so here DNS server also play little role for distribute the requests(loads).

to verify use same command twice. and verify the IP order.



Screen Cast:


Tuesday, 20 November 2012

Tomcat Clustering Series Part 3 : Session Replication

Hi this is my third part of the  Tomcat Clustering Series . In this post we are going to discuss the how to setup session replication in tomcat clustering environment. Session replication makes High availability and full fail-over capability to our clustering environment. [Check the video below for better understanding]

In my previous post we discussed about setup
simple load balancer and how to make session affinity concepts.

How to setup Session Replication in tomcat
   before going to session replication we need to understand 2 important concepts
  • Multicast
  • Session Manager in Tomcat
Multicast

     Multicast is To transmit a single message to a select group of recipients. here multicast used by tomcat cluster to identify the instances those part of cluster. 

There is 2 types of cluster
  • Static Tomcat Cluster
  • Dynamic Tomcat Cluster
In static cluster there is no need multicast, because each tomcat we statically defined/configured the other instances. But dynamic Cluster we are not defined anything. so each tomcat in that cluster some how to identify the other tomcat instances.

so here multicast concepts is used. each and every tomcat first joining to single multicast group. and send the heartbeat signals in periodic interval. so other tomcat instances received these signal and add the member to the cluster.

Session Manager in Tomcat

      Session Manager is used to create and manage the session behalf the application. In Servlet Specification request.getSession(); line is mention that container (tomcat) is responsible for create the session. here tomcat use the Session Manager for this purpose.

there is 4 types of Session Manager
  • Standard Manager
  • Persistent Manager
  • Delta Manager
  • Backup Manager

Standard Manager

Its is the default manager used by tomcat. Even though we are not mention in our web application tomcat use this manager for managing our session. If u want to customize the this standard manager then add <Manager> tag in context.xml file.

<Manager className=“org.apache.catalina.session.StandardManager” />

here org.apache.catalina.session.StandardManager is fully qualified class name of the Standard Manager.

Persistent Manger

This mnager is to sote the session information into persistent place after some interval. here two types of store is available.
  • File Store
  • JDBC Store
File Store helps to store all session information in separate files in underlying file system (local HDD or shared file-system like NFS,..) 
JDBC Store helps to store the session information to relational database.

so using the Persistent Manager we can achieve the tomcat cluster. but its not swapped out in real time. its pushes the information after certain interval. so if anything badly happen(crash) before that interval then in-memory session data is gone.

Delta Manger

In this post we are going to use this manager. Its replicate the session to all other instances. so this manager usually used clustered environment. but not good for large cluster.

Backup Manager

this manager usually used clustered environment. Its like delta manger. but it will  replicate to exactly one other instance(backup instance). Its acted like one instance is Primary  and another instance as backup  

Steps to make Session Replication in Tomcat Clustering

here i will continue from exactly where i left in last session affinity post . so check that post and make sure jumRoute all are set properly. so steps are
  1. Enable Multicast routing
  2. Add <Cluster> Entries in conf/server.xml file for all instances.
  3. Enable the Web Application as distributable

    1. Enable Multicast routing


           In Linux Environment most of the system kernel is capable to process the multicast address. but we need to add route entry in kernel routing table.
    sudo route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0

    here eth0 is my Ethernet interface. so change according to your  interface
    In multicast address is belong to Class D address Range (224.0.0.0 to 239.255.255.255). so we inform to kernel if any one access these address then it goes through eth0 interface.

    2. Add <Cluster> Entries in conf/server.xml file for all instances.


         This very important part for tomcat clustering. We need to Add <Cluster> tag in conf/server.xml file in all tomcat instances.

    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"/>

    we can add this <Cluster> tag in either inside the<Engine> tag or <Host> tag.

    here SimpleTcpCluster is Tomcat Cluster implementation

    This tag is looks like simple but its has many inner tags. if we omitted then its takes the default values. if we want do any cutomization (like change multicat address, receving address port) we need to use complete <Cluster> tag

    this is complete <Cluster> 


    <Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster" 
                            channelSendOptions="8">

    <Manager className="org.apache.catalina.ha.session.DeltaManager"
    expireSessionsOnShutdown="false"
    notifyListenersOnReplication="true"/>
    <Channel className="org.apache.catalina.tribes.group.GroupChannel">
    <Membership className="org.apache.catalina.tribes.membership.McastService"
    address="228.0.0.4"
    port="45564"
    frequency="500"
    dropTime="3000"/>

    <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
    <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
    </Sender>
    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
    address="auto"
    port="4000"
    autoBind="100"
    selectorTimeout="5000"
    maxThreads="6"/>
    <Interceptor  
                                      className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
    <Interceptor 
                      className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
    </Channel>

    <Valve className="org.apache.catalina.ha.tcp.ReplicationValve" filter=""/>

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

    <ClusterListener className="org.apache.catalina.ha.session.JvmRouteSessionIDBinderListener"/>

    <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>

    </Cluster>


    Check my sample conf/server.xml file (for reference)

    here most of the code are  boiler plate code. just copy and paste. if we need we can customize. for example we can change the multicat address and port number.

    <Manager className="org.apache.catalina.ha.session.DeltaManager"/>

    here Manager tag define the delta manager. Delta manager means replicate to all instances.


    <Channel className="org.apache.catalina.tribes.group.GroupChannel">
    Tomcat Clustering use the
    Apache Tribes communication framework .  This group commnication framework is responsible for dynamic membership (using multicast) , send and receive the session delta information using uni-cast (normal TCP connection).


    <Membership className="org.apache.catalina.tribes.membership.McastService"
    address="228.0.0.4"
    port="45564"
    frequency="500"
    dropTime="3000"/>
    This is Membership definition. here address is multicast address. we can pick any address from Class D address range (224.0.0.0 to 239.255.255.255)and any port number.

    Each and every tomcat send the heart beat signal to multicast address in periodic (
    frequency ) interval. all other tomcat whose joined the multicast address they can receive these signals and add the membership to the cluster. if heat beat signal is not revive some particular interval ( dropTime ) from any one of the tomcat, then we need to consider that tomcat is failed.

    Note:-
         All tomcat instances which is part of the clustering,
    should have same multicast address and port number.


    <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
    <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
    </Sender>
    here sender use the PooledParallelSender have pooled connections to use the send the session information concurrently. so its speedup the session replication process.


    <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
    address="auto"
    port=" 4000 "
    autoBind="100"
    selectorTimeout="5000"
    maxThreads="6"/>
    here we define which port Receiver can bind and used for receiving the session replicate information. here two properties are important. address and port. here address is ur system IP address and port is any unused port. here
    address="auto" its automatically pick the system IP address.


    we have some interceptor
    TcpFailureDetector  -Its ensure that instance are dead. In some case multicast messages are delayed, all tomcat instances are think about that tomcat is dead. but this interceptor to make tcp unicast to failed tomcat and ensure that instances is actually failed or not

    another important listener is 
    JvmRouteSessionIDBinderListener,  we talk about later

    3. Enable the Web Application as distributable


       We need to make the our web application distribuable. its simple add <distributable/> tag in web.xml file. In according to servlet specification   <distributable/> tag in web.xml mention that any container to consider this application can work in distributed environment.

    Note:
    All session in our web application must me serializable.


    Do these steps to all tomcat instances and start the tomcat and httpd server. check my configuration in my github repo or get as ZIP


    This is my configuration. all 3 tomcat instances are configured in delta manager and i deployed the distributed web application. all tomcat use the multicast to maintain the membership.

    now client make the request and first tomcat process and create the session, then looks like this
    then tomcat 1 is responsible to replicate the session using Apache tribes group communication framework to replicate the session to all instances.

    now all tomcat instance have exact copy of the session. so if tomcat 1 crashed or shutdown, then any other tomcat still can process the request [see the video below]

    We used session affinity like 
    previous post . based on that cookie id contain the tomcat name (worker name). so when first tomcat1 return the session id end with tomcat1. but when tomcat 1 is failed and tomcat 2 take the responsible for all further request. but session id still contain the tomcat1. so its makes the load balancer difficult. because tomcat1 is down. and load balancer pick any other tomcat. but actually tomcat2 takes the responsible. so we need to reflect these changes in session id.
    JvmRouteSessionIDBinderListener   take care to change the client session id to tomcat2 when failure is occurred  so load balancer redirect to tomcat2 without confusing.

    Check the
    git hub for all configuration files and tomcat clustering setup is available. or u can download as ZIP

    Reference:




    Screen Cast: