[seam-commits] Seam SVN: r10032 - in branches/enterprise/JBPAPP_4_3_FP01: examples/booking and 6 other directories.

seam-commits at lists.jboss.org seam-commits at lists.jboss.org
Wed Feb 11 10:08:15 EST 2009


Author: manaRH
Date: 2009-02-11 10:08:14 -0500 (Wed, 11 Feb 2009)
New Revision: 10032

Added:
   branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/META-INF/jboss.xml
   branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/jmx/
   branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java
Modified:
   branches/enterprise/JBPAPP_4_3_FP01/examples/booking/readme.txt
   branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/components.xml
   branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/web.xml
   branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/components.properties
   branches/enterprise/JBPAPP_4_3_FP01/examples/build.xml
   branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/servlet/SeamListener.java
Log:
JBPAPP-1495

Modified: branches/enterprise/JBPAPP_4_3_FP01/examples/booking/readme.txt
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/examples/booking/readme.txt	2009-02-11 15:00:23 UTC (rev 10031)
+++ branches/enterprise/JBPAPP_4_3_FP01/examples/booking/readme.txt	2009-02-11 15:08:14 UTC (rev 10032)
@@ -4,4 +4,13 @@
 Transaction and persistence context management is handled by the
 EJB container.
 
-example.name=booking
\ No newline at end of file
+example.name=booking
+
+To deploy this application to a cluster, first follow the steps 1-9 clustering-howto.txt in the root folder of the Seam distribution. Then execute the following command:
+ ant farm
+This command will deploy the archive to the farm directory of the "all" JBoss AS domain. To undeploy, run the following command:
+ ant unfarm
+HTTP session replication is enabled by default. You can disable it with the following commandline switch:
+ -Dsession.replication=false
+You can also toggle Seam's ManagedEntityInterceptor for any deployment with the following commandline switch:
+ -Ddistributable=false
\ No newline at end of file

Added: branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/META-INF/jboss.xml
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/META-INF/jboss.xml	                        (rev 0)
+++ branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/META-INF/jboss.xml	2009-02-11 15:08:14 UTC (rev 10032)
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE jboss PUBLIC "-//JBoss//DTD JBOSS 4.0//EN" "http://www.jboss.org/j2ee/dtd/jboss_4_2.dtd">
+<jboss>
+   <enterprise-beans>
+      <session>
+         <ejb-name>BookingListAction</ejb-name>
+         <clustered>@distributable@</clustered>
+      </session>
+      <session>
+         <ejb-name>HotelBookingAction</ejb-name>
+         <clustered>@distributable@</clustered>
+      </session>
+      <session>
+         <ejb-name>HotelSearchingAction</ejb-name>
+         <clustered>@distributable@</clustered>
+      </session>
+   </enterprise-beans>
+</jboss> 
\ No newline at end of file

Modified: branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/components.xml
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/components.xml	2009-02-11 15:00:23 UTC (rev 10031)
+++ branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/components.xml	2009-02-11 15:08:14 UTC (rev 10032)
@@ -10,7 +10,7 @@
                  http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd
                  http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.0.xsd">
 
-    <core:init jndi-pattern="@jndiPattern@" debug="true"/>
+    <core:init jndi-pattern="@jndiPattern@" debug="true" distributable="@distributable@"/>
 
     <core:manager conversation-timeout="120000"
                   concurrent-request-timeout="500"

Modified: branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/web.xml
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/web.xml	2009-02-11 15:00:23 UTC (rev 10031)
+++ branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/WEB-INF/web.xml	2009-02-11 15:08:14 UTC (rev 10032)
@@ -4,6 +4,8 @@
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
     
+    <!-- <distributable/> -->
+    
     <display-name>Seam Booking Example</display-name>
     
     <!-- Seam -->

Modified: branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/components.properties
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/components.properties	2009-02-11 15:00:23 UTC (rev 10031)
+++ branches/enterprise/JBPAPP_4_3_FP01/examples/booking/resources/components.properties	2009-02-11 15:08:14 UTC (rev 10032)
@@ -1,3 +1,4 @@
 # The pattern in components.xml is replaced by an application server specific value in the ant build. This value is used for running tests
 
-jndiPattern \#{ejbName}/local
\ No newline at end of file
+jndiPattern \#{ejbName}/local
+distributable true
\ No newline at end of file

Modified: branches/enterprise/JBPAPP_4_3_FP01/examples/build.xml
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/examples/build.xml	2009-02-11 15:00:23 UTC (rev 10031)
+++ branches/enterprise/JBPAPP_4_3_FP01/examples/build.xml	2009-02-11 15:08:14 UTC (rev 10032)
@@ -32,6 +32,7 @@
 	<!-- Deployment directories -->
 	<property name="deploy.dir" value="${jboss.home}/server/production/deploy" />
 	<property name="tomcat.deploy.dir" value="${tomcat.home}/webapps" />
+	<property name="farm.deploy.dir" value="${jboss.home}/server/all/farm" />
 	<property name="conf.dir" value="${jboss.home}/server/production/conf" />
 
 	<!-- Library directories -->
@@ -531,10 +532,15 @@
 		<copy todir="${jar.dir}">
 			<fileset refid="jar.resources" />
 			<fileset refid="jar.extras" />
+			<filterset>
+            	<filter token="distributable" value="${distributable}" />
+            </filterset>
 		</copy>
 	</target>
 	
-	<target name="init.war" />
+	<target name="init.war">
+    	<property name="distributable" value="false"/>
+    </target>
 
 	<!-- Build the exploded war -->
 	<target name="war" depends="compile, init.war">
@@ -586,18 +592,25 @@
 			<fileset refid="war.resources" />
 			<filterset>
 				<filter token="debug" value="${debug}" />
-				<filter token="jndiPattern" value="${example.name}/#{ejbName}/local" />
-				<filter token="embeddedEjb" value="false" />
+				<filter token="distributable" value="${distributable}" />
+				<filter token="jndiPattern" value="${example.name}/#{ejbName}/local" />				
 			</filterset>
 		</copy>
 	</target>
+	
+	<target name="distributable.war" if="use.session.replication">
+	    <replace file="${war.dir}/WEB-INF/web.xml">
+	            <replacetoken><![CDATA[<!-- <distributable/> -->]]></replacetoken>
+	            <replacevalue><![CDATA[<distributable/>]]></replacevalue>
+	    </replace>
+    </target>
 
 	<!-- Build the exploded ear -->
 	<target name="ear">
 		<copy todir="${ear.dir}">
 			<fileset refid="seam.jar" />
-			<fileset refid="ear.extras" />
 			<fileset refid="ear.resources" />
+			<fileset refid="ear.extras" />			
 		</copy>
 		<mkdir dir="${ear.dir}/lib" />
 		<copy todir="${ear.dir}/lib">
@@ -622,7 +635,7 @@
 		</copy>
 	</target>
 
-	<target name="archive" depends="jar,jboss.war,ear" description="Package the archives">
+	<target name="archive" depends="jar,jboss.war,distributable.war,ear" description="Package the archives">
 		<jar jarfile="${dist.dir}/${example.name}.jar" basedir="${jar.dir}" />
 		<jar jarfile="${dist.dir}/${example.name}.war" basedir="${war.dir}" />
 		<jar jarfile="${dist.dir}/${example.name}.ear">
@@ -633,6 +646,37 @@
 			</fileset>
 		</jar>
 	</target>
+	
+    <target name="init.distributable">
+       <property name="distributable" value="true"/>
+       <condition property="use.session.replication">
+          <or>
+            <not><isset property="session.replication"/></not>
+            <equals arg1="${session.replication}" arg2="true"/>
+          </or>
+       </condition>
+     </target>
+     
+     <target name="farm-archive" depends="init.distributable,archive"/>
+     <!-- FIXME Set the deploy.dir dynamically to avoid the duplicate targets for farming -->
+     <target name="farm-datasource" description="Deploy the datasource to a JBoss AS cluster">
+             <fail unless="jboss.home">jboss.home not set</fail>
+             <copy todir="${farm.deploy.dir}">
+                     <fileset dir="${resources.dir}">
+                             <include name="${example.ds}" />
+                     </fileset>
+             </copy>
+     </target>
+     <target name="farm" depends="farm-archive,farm-datasource" description="Deploy the example to a JBoss AS cluster">
+             <fail unless="jboss.home">
+                     jboss.home not set, update build.properties
+             </fail>
+             <copy file="${dist.dir}/${example.name}.ear" todir="${farm.deploy.dir}" />
+     </target>
+     <target name="unfarm" description="Undeploy the example from a JBoss AS cluster">
+             <delete file="${farm.deploy.dir}/${example.name}.ear" />
+             <delete file="${farm.deploy.dir}/${example.ds}" />
+     </target>
 
 	<!-- Deploy the target to JBoss AS -->
 	<target name="deploy" depends="archive, datasource" description="Deploy the example to JBoss AS">
@@ -755,8 +799,8 @@
 			<fileset refid="war.resources" />
 			<filterset>
 				<filter token="debug" value="${debug}" />
-				<filter token="jndiPattern" value="#{ejbName}/local" />
-				<filter token="embeddedEjb" value="false" />
+				<filter token="distributable" value="${distributable}" />
+				<filter token="jndiPattern" value="#{ejbName}/local" />				
 			</filterset>
 		</copy>
 	</target>
@@ -824,13 +868,13 @@
 			<fileset refid="war.resources" />
 			<filterset>
 				<filter token="debug" value="${debug}" />
+				<filter token="distributable" value="${distributable}" />
 				<filter token="jndiPattern" value="#{ejbName}/local" />
-				<filter token="embeddedEjb" value="false" />
 			</filterset>
 		</copy>
 	</target>
 
-	<target name="noejb.archive" depends="noejb.jar,noejb.war" description="Package the archives for non-ejb war">
+	<target name="noejb.archive" depends="noejb.jar,noejb.war,distributable.war" description="Package the archives for non-ejb war">
 		<jar jarfile="${dist.dir}/${example.name}.war">
 			<fileset dir="${war.dir}" />
 			<zipfileset dir="${dist.dir}" prefix="WEB-INF/lib">
@@ -852,6 +896,20 @@
 		<delete file="${deploy.dir}/${example.name}.war" />
 	</target>
 	
+	<target name="noejb.farm-archive" depends="init.distributable,noejb.archive"/>
+    
+      <!-- FIXME Set the deploy.dir dynamically to avoid the duplicate targets for farming -->
+    <target name="jbosswar.farm" depends="noejb.farm-archive,farm-datasource" description="Deploy the example to a JBoss AS cluster">
+              <fail unless="jboss.home">
+                      jboss.home not set, update build.properties
+              </fail>
+              <copy file="${dist.dir}/${example.name}.war" todir="${farm.deploy.dir}" />
+    </target>
+    
+    <target name="jbosswar.unfarm" description="Undeploy the example from a JBoss AS cluster">
+              <delete file="${farm.deploy.dir}/${example.name}.war" />
+    </target>
+	
 	<target name="jbosswar.explode" depends="noejb.jar, noejb.war, datasource" description="Deploy the example (exploded) to JBoss AS">
 		<fail unless="jboss.home">
 			jboss.home not set, update build.properties

Added: branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java	                        (rev 0)
+++ branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/jmx/JBossClusterMonitor.java	2009-02-11 15:08:14 UTC (rev 10032)
@@ -0,0 +1,158 @@
+package org.jboss.seam.jmx;
+
+import static org.jboss.seam.ScopeType.APPLICATION;
+import static org.jboss.seam.annotations.Install.BUILT_IN;
+
+import java.util.Iterator;
+import java.util.Vector;
+
+import javax.management.MBeanServer;
+import javax.management.MBeanServerFactory;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+import javax.servlet.ServletContext;
+
+import org.jboss.seam.Seam;
+import org.jboss.seam.annotations.Create;
+import org.jboss.seam.annotations.Install;
+import org.jboss.seam.annotations.Name;
+import org.jboss.seam.annotations.Scope;
+import org.jboss.seam.annotations.Startup;
+import org.jboss.seam.annotations.intercept.BypassInterceptors;
+import org.jboss.seam.log.Log;
+import org.jboss.seam.log.Logging;
+
+/**
+ * The purpose of this component is to detect a clustered environment and
+ * to inform the HttpSessionListener whether the origin of a session destroyed
+ * event is the failover of a session from one node to the next. If a node
+ * is failing over, we don't want the SFSBs referenced by the session to be
+ * destroyed.
+ * 
+ * @author Dan Allen
+ */
+ at Name("org.jboss.seam.jmx.jbossClusterMonitor")
+ at BypassInterceptors
+ at Scope(APPLICATION)
+ at Startup
+ at Install(precedence=BUILT_IN, classDependencies="org.jgroups.MembershipListener")
+public class JBossClusterMonitor
+{
+   private static Log log = Logging.getLog(JBossClusterMonitor.class);
+   
+   private MBeanServer jbossMBeanServer;
+   
+   private boolean clustered;
+   
+   private ObjectName clusteringCacheObjectName;
+   
+   private ObjectName serverObjectName;
+   
+   @Create
+   public void create()
+   {
+      jbossMBeanServer = locateJBoss();
+      
+      if (!isJBoss())
+      {
+         return;
+      }
+      
+      try
+      {
+         clusteringCacheObjectName = new ObjectName("jboss.cache:service=TomcatClusteringCache");
+         serverObjectName = new ObjectName("jboss.system:type=Server");
+      }
+      catch (MalformedObjectNameException e)
+      {
+         log.warn("Invalid JMX name: " + e.getMessage());
+      }
+      
+      try
+      {
+         jbossMBeanServer.getMBeanInfo(clusteringCacheObjectName);
+         clustered = true;
+         log.info("JBoss cluster detected");
+      }
+      catch (Exception e) {}
+   }
+   
+   public boolean isClustered()
+   {
+      return clustered;
+   }
+   
+   /**
+    * Consults the jboss.system:type=Server MBean to determine if this instance
+    * of JBoss AS is currently being shutdown. Note that the flag only returns
+    * true if the shutdown() method on this MBean is used. It does not detect a
+    * force halt via a process signal (i.e., CTRL-C).
+    */
+   public boolean nodeIsShuttingDown()
+   {
+      if (!isJBoss())
+      {
+         return false;
+      }
+      
+      try
+      {
+         return (Boolean) jbossMBeanServer.getAttribute(serverObjectName, "InShutdown");
+      }
+      catch (Exception e)
+      {
+         return false;
+      }
+   }
+   
+   public boolean isLastNode()
+   {
+      if (!clustered)
+      {
+         return true;
+      }
+      
+      // other options
+      // object name => jboss.jgroups:cluster=DefaultPartition,type=channel
+      // object name => jboss.jgroups:cluster=Tomcat-Cluster,type=channel
+      // attribute => NumberOfTasksInTimer
+      
+      try
+      {
+         return ((Vector) jbossMBeanServer.getAttribute(clusteringCacheObjectName, "Members")).size() == 1;
+      }
+      catch (Exception e) {
+         log.warn("Could not determine number of members in cluster", e);
+         return true;
+      }
+   }
+   
+   public boolean failover()
+   {
+      return isClustered() && nodeIsShuttingDown() && !isLastNode();
+   }
+   
+   public boolean isJBoss()
+   {
+      return jbossMBeanServer != null;
+   }
+   
+   protected MBeanServer locateJBoss()
+   {
+      for (Iterator i = MBeanServerFactory.findMBeanServer(null).iterator(); i.hasNext(); )
+      {
+         MBeanServer server = (MBeanServer) i.next();
+         if (server.getDefaultDomain().equals("jboss"))
+         {
+            return server;
+         }
+      }
+      return null;
+   }
+   
+   // FIXME my sense is that this could lookup could be more elegant or conforming
+   public static JBossClusterMonitor getInstance(ServletContext ctx)
+   {
+      return (JBossClusterMonitor) ctx.getAttribute(Seam.getComponentName(JBossClusterMonitor.class));
+   }
+}

Modified: branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/servlet/SeamListener.java
===================================================================
--- branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/servlet/SeamListener.java	2009-02-11 15:00:23 UTC (rev 10031)
+++ branches/enterprise/JBPAPP_4_3_FP01/src/main/org/jboss/seam/servlet/SeamListener.java	2009-02-11 15:08:14 UTC (rev 10032)
@@ -14,6 +14,7 @@
 import org.jboss.seam.Seam;
 import org.jboss.seam.contexts.ServletLifecycle;
 import org.jboss.seam.init.Initialization;
+import org.jboss.seam.jmx.JBossClusterMonitor;
 import org.jboss.seam.log.LogProvider;
 import org.jboss.seam.log.Logging;
 
@@ -46,7 +47,16 @@
    
    public void sessionDestroyed(HttpSessionEvent event) 
    {
-      ServletLifecycle.endSession( event.getSession() );
+      JBossClusterMonitor monitor = JBossClusterMonitor.getInstance(event.getSession().getServletContext());
+      if (monitor != null && monitor.failover())
+      {
+         // If application is unfarmed or all nodes shutdown simultaneously, cluster cache may still fail to retrieve SFSBs to destroy
+         log.info("Detected fail-over, not destroying session context");
+      }
+      else
+      {
+         ServletLifecycle.endSession( event.getSession() );
+      }
    }
    
 }




More information about the seam-commits mailing list