Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3

...

John A. Lewis
Unicon, Inc.

Introduction

Excerpt

JSR-168 Portlet applications represent a special challenge when it comes to clustering within Tomcat (or any other servlet container, for that matter). In order to effectively cluster web applications, session data must be replicated or shared between the nodes in the cluster. Otherwise, the user experiences a complete loss of context during a node failover. While Tomcat has provided session replication for quite some time, it has not supported replication of session changes resulting from a cross-context call from one webapp to another.

Portlets that are deployed as separate webapps from the portal webapp must be accessed by cross-context calls from the portal. This cross-context access creates a number of issues: servlet filters are not applied, session sharing between servlets and portlets is difficult, and session replication in Tomcat did not work.

At The University of Wisconsin-Madison (www.wisc.edu) and Pearson Education (www.pearsoned.com) both recently identified a need for full support of portlet session replication within Tomcat. They engaged with Unicon (www.unicon.net) , weto work with the Tomcat community to provide this capability. We've recently worked directly with the Tomcat developers to get Cross-Context Session Replication built into Tomcat 5.5 and we've demonstrated that portlet session data can now be properly replicated. I'd like to give a special thanks to Peter Rossbach from the Tomcat team for working on this with us and for getting this done so quickly. The changes for Tomcat are currently in the latest development codebase and will be included in version 5.5.16 and later.

...

  • The HTTP <Connector> declaration and the AJP/1.3 <Connector> declaration both contain 'emptySessionPath="true"' -- this is necessary so that we can share session information between servlets and portlets by having the path on the session cookie be set to '/' instead of the path of the webapp. Without this, the portal webapp and the portlet webapp will get separate session cookies and therefore separate session IDs.
  • The <Engine> declaration has 'jvmRoute="tomcatA"' set in it. This is needed to identify the engine to enable sticky sessions (i.e. a user stays with the same engine for his entire session unless the engine becomes unavailable).
  • The entire section for the <Cluster> declaration has been enabled using all the default settings.
  • The 'port' for the <Server> declaration, the 'port' for both <Connector> declarations, the 'redirectPort' for the AJP <Connector> declaration, and the 'tcpListenPort' for the <Receiver> declaration inside the <Cluster> declaration have all been incremented by one in order to not conflict with any preexisting install of Tomcat.

...

Obtain the current pluto-lib-core and pluto-lib-tools downloads from the Pluto website -- they are available in both .zip and .tar.gz format, depending on your preference. I'm working with the 1.0.1 release at this point.

...

The definition of 'crossContext="true"' is critical here -- this allows the Pluto Portal Driver to make calls into the portlets running inside other webapps.

The testsuite webapp comes packaged generically and must be deployed into the target JSR-168 portal platform. Unfortunately, the pluto webapp comes configured as if the testsuite was already installed. So instead of running the testsuite through the deployment process, we will hand-modify it to complete the deployment. To do this, modify the tomcatA/webapps/testsuite/WEB-INF/web.xml by adding file.

Add the following content<servlet> entries after the existing ones:

Code Block
<servlet>

       <servlet-name>TestPortlet1</servlet-name>
 
      <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
  
     <init-param>
            <param-name>portlet-class</param-name>
   
        <param-value>org.apache.pluto.portalImpl.portlet.TestPortlet</param-value>

       </init-param>
        <init-param>
            <param-name>portlet-guid</param-name>
  
         <param-value>testsuite.TestPortlet1</param-value>
   
    </init-param>
   
    <security-role-ref>

           <role-name>plutoTestRole</role-name>
 
          <role-link>tomcat</role-link>
        </security-role-ref>
   
</servlet>

    <servlet>
        <servlet-name>TestPortlet2</servlet-name>
        <servlet-class>org.apache.pluto.core.PortletServlet</servlet-class>
        <init<init-param>

           <param-name>portlet-class</param-name>
 
          <param-value>org.apache.pluto.portalImpl.portlet.TestPortlet</param-value>
  
     </init-param>
        <init-param>
   
        <param-name>portlet-guid</param-name>

           <param-value>testsuite.TestPortlet2</param-value>
        </init-param>
        <security-role-ref>

           <role-name>plutoTestRole</role-name>
   
        <role-link>tomcat</role-link>
        </security-role-ref>
    </servlet>

    <servlet-mapping>
        <servlet-name>extAppScopedTest</servlet-name>
        <url-pattern>/test/extAppScopedTest</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
      <servlet-name>includeTest</servlet-name>
      <url-pattern>/tests/include</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
  

And then add the following <servlet-mapping> entries after the existing ones:

Code Block

<servlet-mapping>
     <servlet-name>TestPortlet1</servlet-name>
        <url-pattern>/TestPortlet1/*</url-pattern>
    </servlet-mapping>

  

<servlet-mapping>

       <servlet-name>TestPortlet2</servlet-name>
 
      <url-pattern>/TestPortlet2/*</url-pattern>
  
 </servlet-mapping>

This should come between the last existing <servlet> declaration and the existing <security-role> declaration.

At this point you should be able to start the tomcatA instance and connect to http://localhost:8081/pluto/portal/ and see the portal and try out the test suite portlets. Do not proceed until this is all working correctly.

...

Use the deployment portlet inside Pluto to deploy the session-test.war file. Do not just deploy the war file into Tomcat directly -- the deployment process makes some necessary modifications to the web.xml file. To do this, complete the following:

...

The Pluto Portal Driver does not come declared as distributable. We specifically held off on modifying the pluto webapp for this because the 'Deploy War Admin Portlet' violates the rules -- it puts something in the session that is not serializable. Since we are done using that tool now, we can proceed.

...

Now open a separate browser window and go to http://localhost/pluto/portal/session-test/ -- you should see the Pluto environment and the two instances of the session-test portlet. You should also see an entry at the bottom of the portlets that lists the phyiscal location of the JSP file you are viewing. The path in this entry will indicate whether the loadbalancer is sending you to tomcatA or tomcatB.

...