Sunday, 31 August 2014

Aws Kinesis Integration (sending messages to kinesis)

I will be sharing here details about integration of Aws Kinesis here. If you have bit time, I would recommend you to visit here


1. Create a properties file for Kinesis.

@Component
public class KinesisProp {

    @Value("${kinesis.access.key}")
    private String  awsAccessKey;
    @Value("${kinesis.secret.key}")
    private String  awsSecretKey;
    @Value("${kinesis.streamName}")
    private String streamName;
    @Value("${kinesis.receive.limit}")
    private Integer receiveLimit;
    @Value("${kinesis.shradCount}")
    private Integer shardCount;
    @Value("${kinesis.region}")
    private String region;
    @Value("${kinesis.steam.initialPosition}")
    private String streamInitialPosition;
    @Value("${kinesis.endPoint}")
    private String endPoint; 


    // getters and setters here

}

2. Create a service call, which will be responsible for sending messages to Kinesis.

@Component
public class KinesisService {
    private static final Logger logger = LoggerFactory.getLogger(KinesisService.class);
    @Autowired
    private KinesisProp kinesisProp;
    private AmazonKinesisClient kinesisClient;
 

    @PostConstruct
    private void init() {
        try {
            instantiateKinesisClient();
        } catch (Exception e) {
            logger.error("Exception occurred while instantiating the Kinesis Client", e);
        }
    }

    private void instantiateKinesisClient() throws IOException {
        BasicAWSCredentials  credentials = new BasicAWSCredentials(this.kinesisProp.getAwsAccessKey(), this.kinesisProp.getAwsSecretKey());
        kinesisClient = new AmazonKinesisClient(credentials);
        final Region apac_east = Region.getRegion(Regions.valueOf(kinesisProp.getRegion()));
        kinesisClient.setRegion(apac_east);
        createStream();
    }

    private void createStream() {
        final ListStreamsRequest listStreamsRequest = new ListStreamsRequest();
        ListStreamsResult listStreamsResult = kinesisClient.listStreams(listStreamsRequest);
        if (listStreamsResult == null || listStreamsResult.getStreamNames().isEmpty() ||
                (!listStreamsResult.getStreamNames().contains(kinesisProp.getStreamName()))) {

            CreateStreamRequest createStreamRequest = new CreateStreamRequest();
            createStreamRequest.setStreamName(kinesisProp.getStreamName());
            createStreamRequest.setShardCount(kinesisProp.getShardCount());

            try {
                kinesisClient.createStream(createStreamRequest);
            } catch (Exception e) {
                logger.error("Error occurred while creating the stream!", e);
            }
        }
    }

    public void sendMessage(final String message) throws AmazonServiceException {
       PutRecordRequest putRecordRequest = new PutRecordRequest();
 putRecordRequest.setStreamName(kinesisProp.getStreamName());
 putRecordRequest.setData(ByteBuffer.wrap(message.getBytes()));                                                                      putRecordRequest.setPartitionKey(Constants.AWS_KINESIS_PARTITION_KEY);
          kinesisClient.putRecord(putRecordRequest);
    }
 

}


3. Fetching the messages can be done in two ways.

(a) Using Aws Kinesis API
(b) Using Aws Kinesis Client Library.

I will update on this in my next blog.

Note:
(a) Spring is used for DI.
(b) When you are creating the access key and secret key, make sure to create for the kinesis app.

Monday, 11 August 2014

Embedded jetty server with web app

Recently, I come across a situation where both maven-jetty plugin & embedded jetty server need to packed along with web-application. I have already written a blog on incorporating maven-jetty plugin in the web app here, hence will not be discussing here again. I will describe here about package of embedded jetty server with in web application below.

Firstly, why do we require to include embedded jetty?
1. Easy deployment, java -jar <web-app>.jar, once you build the artifact, it's ready for deployment without any hassle configurations/deployment procedures, etc
2. No requirement of application server.


Let's go through the following steps to include jetty server within web app.

1. Create a JettyServer class


package com.sateesh.application.server;

import org.eclipse.jetty.server.Connector;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.webapp.WebAppContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.DispatcherServlet;

import java.io.IOException;


public class JettyServer {

    private static final Logger logger = LoggerFactory.getLogger(JettyServer.class);
    private final String WEB_APP_DIR = "src/main/webapp";
    private final String WEB_XML_PATH = "src/main/webapp/WEB-INF/web.xml";
    private static final String MVC_SERVLET_NAME = "dispatcher";
    private static final String JSP_SERVLET_NAME = "jspServlet";
    private static final String DEFAULT_PORT = "8080";
    private static final String DEFAULT_CONTEXT_PATH = "/";



    public static void main(String[] args) throws Exception{
        JettyServer jettyServer = new JettyServer();
        jettyServer.start();
    }

    private JettyServer() {

      // none can instantiate this class
    }

    private void start() throws Exception{
        try {
            QueuedThreadPool threadPool = new QueuedThreadPool(512);

            final Server server = new Server(threadPool);
            server.setStopAtShutdown(true);
            server.setStopTimeout(5000);

            ServerConnector connector = new ServerConnector(server);
            connector.setPort(getPort());
            connector.setIdleTimeout(30000);
            server.setConnectors(new Connector[]{connector});
            server.setHandler(getServletContextHandler());

            server.start();
            server.join();
            logger.info("Embedded Jetty Server is started!");
        } catch (Exception e) {
            logger.error("Exception occurred while starting the jetty server ", e);
        }
    }

    private WebAppContext getServletContextHandler() throws IOException {
        final WebAppContext contextHandler = new WebAppContext();
        contextHandler.setContextPath(getContextPath());
        contextHandler.setWar(WEB_APP_DIR);
        contextHandler.setDefaultsDescriptor(WEB_XML_PATH);
        ServletHolder jspServletHolder = new ServletHolder("jspServlet", new org.apache.jasper.servlet.JspServlet());

        // jsp servelet is required to parse the jsp passed by the spring-mvc  
        contextHandler.addServlet(jspServletHolder, "*.jsp");
        return contextHandler;
    }

 

  /**
  * Consider default port as "8080" until unless not passed using java args
  **/  private int getPort() {
        Integer port = Integer.parseInt(System.getProperty("jetty.port"));

        if (port == null || port == 0) {
            port = Integer.parseInt(DEFAULT_PORT);
        }

        return port;
    }

    

  /**
  * Consider default context path as "/" until unless not passed using java args
  **/
  private String getContextPath() {
        String contextPath = System.getProperty("jetty.contextPath");

        if (contextPath == null ||  contextPath.equals("")) {
            contextPath = DEFAULT_CONTEXT_PATH;
        }

        return contextPath;
    }

}



2. Contents of web.xml (default descriptor executed by JettyServer).

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns="http://java.sun.com/xml/ns/javaee"
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
        id="YourWebAppID"
        version="2.5">

    <display-name>Web App Server</display-name>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:META-INF/spring/application-context.xml
        </param-value>
    </context-param>

    <servlet>
        <servlet-name>dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>dispatcher</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

</web-app>



3. Contents of application-context.xml & dispatcher-servlet.xml files

application-context.xml --- is spring descriptor file. 
dispatcher-servlet.xml --- is servlet dispatcher file, which will scan @Controller annotated packages.


4. Package structure of the project

   --- src
       --- main
           --- java 
               --- com.sateesh.application.server
           --- resources
               --- META-INF
                   --- spring
                       --- application-context.xml
               --- dispatcher-servlet.xml
               --- logback.xml
           --- webapp
               --- views
                   ---  ***.jsp
               --- web.xml


5. below plugin needs to be added in pom.xml

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-shade-plugin</artifactId>
                <version>2.3</version>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals>
                            <goal>shade</goal>
                        </goals>
                        <configuration>
                            <filters>
                                <filter>
                                    <artifact>*:*</artifact>
                                    <excludes>
                                        <exclude>META-INF/*.SF</exclude>
                                        <exclude>META-INF/*.DSA</exclude>
                                        <exclude>META-INF/*.RSA</exclude>
                                    </excludes>
                                </filter>
                            </filters>
                            <createDependencyReducedPom>true</createDependencyReducedPom>
                            <transformers>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                                    <mainClass>com.sateesh.application.server.JettyServer</mainClass>
                                </transformer>
                            </transformers>
                        </configuration>
                    </execution>
                </executions>
            </plugin>


6. add below dependencies in pom.xml

    <properties>
        <jetty.server.scope>compile</jetty.server.scope>
        <jetty.version>9.1.2.v20140210</jetty.version>
    </properties>


        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-server</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-webapp</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-servlet</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>
        <dependency>
            <groupId>org.eclipse.jetty</groupId>
            <artifactId>jetty-jsp</artifactId>
            <version>${jetty.version}</version>
            <scope>${jetty.server.scope}</scope>
        </dependency>


7. You are almost there.. now run the web application now.

build the project (default package is jar in maven):
mvn clean package

run the webapp:
java -jar target/webapp.jar


PS: we can also create embedded jetty server with in web-app without web.xml file also.

Thursday, 31 October 2013

Performance improvement in JSF2

Recently, I come across performance issues with JSF2. The challenge was to improve the time response for rendering the page. I am here with configuration of jsf2 parameters, which helped us to reduce the time response to render the page contents,

Set the state method as server.

        <context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>

Limit the number of views in session to small number.

    <context-param>
            <param-name>org.apache.myfaces.NUMBER_OF_VIEWS_IN_SESSION</param-name>
            <param-value>15</param-value>
    </context-param>

Don't serialize the state, set the compress state as false
    <context-param>
        <param-name>org.apache.myfaces.SERIALIZE_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>


    <context-param>
        <param-name>org.apache.myfaces.COMPRESS_STATE_IN_SESSION</param-name>
        <param-value>false</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.PRETTY_HTML</param-name>
        <param-value>false</param-value>
    </context-param>


cache the el-expressions
    <context-param>
        <param-name>org.apache.myfaces.CACHE_EL_EXPRESSIONS</param-name>
        <param-value>always</param-value>
    </context-param>
    <context-param>
        <param-name>org.apache.myfaces.CHECK_ID_PRODUCTION_MODE</param-name>
        <param-value>false</param-value>
    </context-param>



below parameters are added to not refresh facelets for static pages
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>-1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.REFRESH_PERIOD</param-name>
        <param-value>-1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>false</param-value>
    </context-param>



Sunday, 7 July 2013

Dynamically displaying the modification of .xhtml files in JSF/MyFaces apps

To see any changes in the static files of jsf/myfaces application at run time, we need to add following context-params in the web.xml file.


<!-- below parameters are added to refresh facelets for static pages -->
    <context-param>
        <param-name>javax.faces.FACELETS_REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.REFRESH_PERIOD</param-name>
        <param-value>1</param-value>
    </context-param>
    <context-param>
        <param-name>facelets.DEVELOPMENT</param-name>
        <param-value>true</param-value>
    </context-param>


Thursday, 4 July 2013

Tiles framework for Jsps

I am here with the introduction of tiles framework for Java Servlet Page (JSP)s. I am not giving the information on integration of tiles with sturts/spring here. It is simple tiles usage with jsps.

Following the steps. Considering web app is build by maven tool, tiles version is 2.1.2.

1. Maven dependencies required to include in the project object model file pom.xml


       <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-extras</artifactId>
            <version>2.2.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-core</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-servlet</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-jsp</artifactId>
            <version>2.1.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tiles</groupId>
            <artifactId>tiles-api</artifactId>
            <version>2.1.2</version>
        </dependency>


2. Modifications in web descriptor file web.xml


    <!-- listener needs to be added for tiles -->

    <listener>
        <listener-class>org.apache.tiles.web.startup.TilesListener</listener-class>
    </listener>


    <!-- servlet needs to be added for tiles -->


    <servlet>
        <servlet-name>tiles</servlet-name>
        <servlet-class>org.apache.tiles.web.startup.TilesServlet</servlet-class>
        <init-param>
            <param-name>
                org.apache.tiles.impl.BasicTilesContainer.DEFINITIONS_CONFIG
            </param-name>
            <param-value>
                /WEB-INF/tiles-defs.xml
            </param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>


3. Add a tiles descriptor file tiles-defs.xml file


<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE tiles-definitions PUBLIC "-//Apache Software Foundation//DTD Tiles Configuration 2.1//EN"
        "http://tiles.apache.org/dtds/tiles-config_2_1.dtd">
<tiles-definitions>

    <definition name="unauthorized_default" template="/appName/templates/layout.jsp">
        <put-attribute name="header" value="/appName/templates/nonAuthenticatedHeader.jsp" />
        <put-attribute name="menu" value="/appName/templates/menu.jsp" />
        <put-attribute name="body" value="/appName/templates/body.jsp" />
        <put-attribute name="footer" value="/appName/templates/footer.jsp" />
    </definition>

    <definition name="authorized_default" template="/appName/templates/layout.jsp">
        <put-attribute name="header" value="/appName/templates/header.jsp" />
        <put-attribute name="menu" value="/appName/templates/menu.jsp" />
        <put-attribute name="body" value="/appName/templates/body.jsp" />
        <put-attribute name="footer" value="/appName/templates/footer.jsp" />
    </definition>

    <definition name="authorized_home" template="/appName/templates/layout_leftmenu.jsp">
        <put-attribute name="header" value="/appName/templates/header.jsp" />
        <put-attribute name="menu" value="/appName/templates/menu.jsp" />
        <put-attribute name="leftMenu" value="/appName/templates/leftMenu.jsp" />
        <put-attribute name="body" value="/appName/templates/body.jsp" />
        <put-attribute name="footer" value="/appName/templates/footer.jsp" />
    </definition>

</tiles-definitions>




4. Template files required to add:

(a) layout.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>



      <table width="100%">
      <tr>
        <td>
          <tiles:insertAttribute name="header" />
        </td>
      </tr>
      <tr>
        <td>
          <tiles:insertAttribute name="menu" />
        </td>
      </tr>
      <tr>
        <td>
          <tiles:insertAttribute name="body" />
        </td>
      </tr>
      <tr>
        <td>
          <tiles:insertAttribute name="footer" />
        </td>
      </tr>
    </table>

(b) layout_leftmenu.jsp

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<%@ taglib uri="http://tiles.apache.org/tags-tiles" prefix="tiles" %>



      <table width="100%">
      <tr>
        <td colspan="2">
          <tiles:insertAttribute name="header" />
        </td>
      </tr>
      <tr>
        <td colspan="2">
          <tiles:insertAttribute name="menu" />
        </td>
      </tr>
      <tr>
        <td width="25%">
          <tiles:insertAttribute name="leftMenu" />
        </td>
        <td>
          <tiles:insertAttribute name="body" />
        </td>
      </tr>
      <tr>
        <td align="center">
          <tiles:insertAttribute name="footer" />
        </td>
      </tr>
    </table>




5. Calling the tiles definitions on any jsp


<html>
<body>
    <div align="center" width="100%">
        <tiles:insertDefinition name="unauthorized_default">
            <tiles:putAttribute name="menu" value="/callCenter/templates/blank.jsp" />
            <tiles:putAttribute name="body" value="/callCenter/loginPage.jsp" />
        </tiles:insertDefinition>
    </div>
</body>
</html>





Wednesday, 3 July 2013

URL change while redirecting the page in JSF application

In JSF applications, url will not be changing while redirecting the page using navigation rules. However, sometimes, it might be a damn need to change the url while redirecting from one page to another page. This request can be fulfilled by following way.

In general navigation rule is defined as:

<navigation-rule>
       <from-view-id>/callCenter/crmLogin.jsp</from-view-id>
       <navigation-case>
<from-outcome>gotoMainPanel</from-outcome>
<to-view-id>/callCenter/crmMainPanel.jsp</to-view-id>
       </navigation-case>
</navigation-rule>

However, you need to add <redirect /> tag to do the url change as mentioned below.


<navigation-rule>
       <from-view-id>/callCenter/crmLogin.jsp</from-view-id>
       <navigation-case>
<from-outcome>gotoMainPanel</from-outcome>
<to-view-id>/callCenter/crmMainPanel.jsp</to-view-id>
                <redirect />
</navigation-case>
</navigation-rule>

PS: Navigation rules are mentioned in the faces-config.xml file ( inside WEB-INF directory)

Monday, 17 June 2013

Clustering of tomcat servers

I am here with brief notes on how to form a clustering on tomcat servers.

1. Set up two tomcat servers (tomcat-pri & tomcat-sec)
2. In the setup of tomcat-pri, go the conf directory, and add following content in the server.xml file in the <Host> tag.

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

          <Manager className="org.apache.catalina.ha.session.BackupManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"
                   mapSendOptions="6"/>

          <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"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="5000"
                      selectorTimeout="100"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/host/Work/servers/tomcat-pri/webapps"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="true"/>

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

NOTE: If you observe carefully, the server.xml will have <Cluster> tag is commented out with in the <Engine> tag. However, we need to keep the <Cluster> tag with in the <Host> tag.


3. In the setup of tomcat-pri, go the conf directory, and edit the server.xml file.
Change the port information so that, you wouldn't see port already used messages in the logs.
(i) Server Port
(ii) Connector Port (two places)


4. Also add following content in the server.xml file of tomcat-sec setup.

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

          <Manager className="org.apache.catalina.ha.session.BackupManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"
                   mapSendOptions="6"/>
          <!--
          <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"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="5020"
                      selectorTimeout="100"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatch15Interceptor"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.ThroughputInterceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=".*\.gif|.*\.js|.*\.jpeg|.*\.jpg|.*\.png|.*\.htm|.*\.html|.*\.css|.*\.txt"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/host/Work/servers/apache-tomcat-7.0.41-sec/webapps"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="true"/>

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

5. Now, deploy the web-application artifact in the directory "/tmp/war-listen"

6. Start the tomcat-pri server

7. Start the tomcat-sec server (once tomcat-pri server is started)

8. You would observer following in logs.

Jun 17, 2013 1:53:11 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Jun 17, 2013 1:53:11 PM org.apachecatalina.startup.Catalina load
INFO: Initialization processed in 524 ms
Jun 17, 2013 1:53:11 PM org.apache..coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Jun 17, 2013 1:53:11 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Jun 17, 2013 1:53:11 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.41
Jun 17, 2013 1:53:11 PM org.apache.catalina.ha.tcp.SimpleTcpCluster startInternal
INFO: Cluster is about to start
Jun 17, 2013 1:53:11 PM org.apache.catalina.tribes.transport.ReceiverBase bind
INFO: Receiver Server Socket bound to:/127.0.1.1:5000
Jun 17, 2013 1:53:11 PM org.apache.catalina.tribes.membership.McastServiceImpl setupSocket
INFO: Setting cluster mcast soTimeout to 500
Jun 17, 2013 1:53:11 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:4
Jun 17, 2013 1:53:12 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:4
Jun 17, 2013 1:53:12 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Sleeping for 1000 milliseconds to establish cluster membership, start level:8
Jun 17, 2013 1:53:13 PM org.apache.catalina.tribes.membership.McastServiceImpl waitForMembers
INFO: Done sleeping, membership established, start level:8
Jun 17, 2013 1:53:13 PM org.apache.catalina.ha.deploy.FarmWarDeployer start
INFO: Cluster deployment is watching [/tmp/war-listen/] for changes.
Jun 17, 2013 1:53:13 PM org.apache.catalina.ha.deploy.FarmWarDeployer start
INFO: Cluster FarmWarDeployer started.