Author: rmannibucau
Date: Fri Jul 20 13:47:29 2012
New Revision: 1363775

URL: http://svn.apache.org/viewvc?rev=1363775&view=rev
Log:
TOMEE-334 basic clustering deployment through tomcat cluster

Added:
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/ClusterObserver.java
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/DeployMessage.java
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/UndeployMessage.java
Modified:
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java
    
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
    openejb/trunk/openejb/tomee/tomee-catalina/pom.xml
    
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java?rev=1363775&r1=1363774&r2=1363775&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/AppInfo.java
 Fri Jul 20 13:47:29 2012
@@ -28,6 +28,7 @@ import java.util.TreeSet;
 public class AppInfo extends InfoObject {
     public String appId;
     public String path;
+    public boolean autoDeploy = true;
     public boolean standaloneModule;
     public final List<ClientInfo> clients = new ArrayList<ClientInfo>();
     public final List<EjbJarInfo> ejbJars = new ArrayList<EjbJarInfo>();

Modified: 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1363775&r1=1363774&r2=1363775&view=diff
==============================================================================
--- 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 (original)
+++ 
openejb/trunk/openejb/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
 Fri Jul 20 13:47:29 2012
@@ -121,6 +121,7 @@ import org.apache.openejb.javaagent.Agen
 import org.apache.openejb.jpa.integration.MakeTxLookup;
 import org.apache.openejb.loader.JarLocation;
 import org.apache.openejb.loader.Options;
+import org.apache.openejb.loader.ProvisioningUtil;
 import org.apache.openejb.loader.SystemInstance;
 import org.apache.openejb.monitoring.DynamicMBeanWrapper;
 import org.apache.openejb.assembler.monitoring.JMXContainer;
@@ -419,6 +420,10 @@ public class Assembler extends Assembler
         }
     }
 
+    public boolean isDeployed(final String path) {
+        return 
deployedApplications.containsKey(ProvisioningUtil.realLocation(path));
+    }
+
     public Collection<AppInfo> getDeployedApplications() {
         return new ArrayList<AppInfo>(deployedApplications.values());
     }

Modified: openejb/trunk/openejb/tomee/tomee-catalina/pom.xml
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/pom.xml?rev=1363775&r1=1363774&r2=1363775&view=diff
==============================================================================
--- openejb/trunk/openejb/tomee/tomee-catalina/pom.xml (original)
+++ openejb/trunk/openejb/tomee/tomee-catalina/pom.xml Fri Jul 20 13:47:29 2012
@@ -86,6 +86,12 @@
       <version>${tomcat.version}</version>
       <scope>provided</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.tomcat</groupId>
+      <artifactId>tomcat-catalina-ha</artifactId>
+      <version>${tomcat.version}</version>
+      <scope>provided</scope>
+    </dependency>
   </dependencies>
 </project>
 

Modified: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java?rev=1363775&r1=1363774&r2=1363775&view=diff
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
 (original)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/TomcatWebAppBuilder.java
 Fri Jul 20 13:47:29 2012
@@ -16,9 +16,7 @@
  */
 package org.apache.tomee.catalina;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.List;
+import org.apache.catalina.Cluster;
 import org.apache.catalina.Container;
 import org.apache.catalina.Engine;
 import org.apache.catalina.Host;
@@ -43,19 +41,31 @@ import org.apache.catalina.deploy.Contex
 import org.apache.catalina.deploy.ContextResourceLink;
 import org.apache.catalina.deploy.ContextTransaction;
 import org.apache.catalina.deploy.NamingResources;
+import org.apache.catalina.ha.CatalinaCluster;
 import org.apache.catalina.loader.WebappClassLoader;
 import org.apache.catalina.loader.WebappLoader;
 import org.apache.catalina.startup.Constants;
 import org.apache.catalina.startup.ContextConfig;
 import org.apache.catalina.startup.HostConfig;
 import org.apache.catalina.startup.RealmRuleSet;
+import org.apache.catalina.tribes.Member;
 import org.apache.naming.ContextAccessController;
 import org.apache.naming.ContextBindings;
 import org.apache.openejb.AppContext;
 import org.apache.openejb.BeanContext;
 import org.apache.openejb.Injection;
 import org.apache.openejb.OpenEJBException;
-import org.apache.openejb.assembler.classic.*;
+import org.apache.openejb.assembler.classic.AppInfo;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.assembler.classic.ClassListInfo;
+import org.apache.openejb.assembler.classic.ConnectorInfo;
+import org.apache.openejb.assembler.classic.DeploymentExceptionManager;
+import org.apache.openejb.assembler.classic.EjbJarInfo;
+import org.apache.openejb.assembler.classic.InjectionBuilder;
+import org.apache.openejb.assembler.classic.JndiEncBuilder;
+import org.apache.openejb.assembler.classic.ServletInfo;
+import org.apache.openejb.assembler.classic.WebAppBuilder;
+import org.apache.openejb.assembler.classic.WebAppInfo;
 import org.apache.openejb.cdi.CdiBuilder;
 import org.apache.openejb.config.AppModule;
 import org.apache.openejb.config.ConfigurationFactory;
@@ -74,6 +84,8 @@ import org.apache.openejb.util.LogCatego
 import org.apache.openejb.util.Logger;
 import org.apache.tomcat.InstanceManager;
 import org.apache.tomcat.util.digester.Digester;
+import org.apache.tomee.catalina.cluster.ClusterObserver;
+import org.apache.tomee.catalina.cluster.TomEEClusterListener;
 import org.apache.tomee.catalina.event.AfterApplicationCreated;
 import org.apache.tomee.common.LegacyAnnotationProcessor;
 import org.apache.tomee.common.TomcatVersion;
@@ -99,9 +111,12 @@ import java.io.File;
 import java.io.IOException;
 import java.io.InputStream;
 import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 import java.util.TreeMap;
@@ -178,6 +193,8 @@ public class TomcatWebAppBuilder impleme
 
     private String defaultHost = "localhost";
 
+    private Set<CatalinaCluster> clusters = new HashSet<CatalinaCluster>();
+
     /**
      * Creates a new web application builder
      * instance.
@@ -195,11 +212,13 @@ public class TomcatWebAppBuilder impleme
         for (final Service service : standardServer.findServices()) {
             if (service.getContainer() instanceof Engine) {
                 final Engine engine = (Engine) service.getContainer();
+                manageCluster(engine.getCluster());
                 defaultHost = engine.getDefaultHost();
                 addTomEERealm(engine);
                 for (final Container engineChild : engine.findChildren()) {
                     if (engineChild instanceof StandardHost) {
                         final StandardHost host = (StandardHost) engineChild;
+                        manageCluster(host.getCluster());
                         addTomEERealm(host);
                         hosts.put(host.getName(), host);
                         for (final LifecycleListener listener : 
host.findLifecycleListeners()) {
@@ -213,10 +232,24 @@ public class TomcatWebAppBuilder impleme
             }
         }
 
+        SystemInstance.get().addObserver(new ClusterObserver(clusters));
+
         configurationFactory = new ConfigurationFactory();
         deploymentLoader = new DeploymentLoader();
     }
 
+    private void manageCluster(final Cluster cluster) {
+        if (cluster == null) {
+            return;
+        }
+
+        if (cluster instanceof CatalinaCluster) {
+            final CatalinaCluster haCluster = (CatalinaCluster) cluster;
+            haCluster.addClusterListener(new TomEEClusterListener());
+            clusters.add(haCluster);
+        }
+    }
+
     private void addTomEERealm(final Engine engine) {
         final Realm realm = engine.getRealm();
         if (realm != null && !(realm instanceof TomEERealm)
@@ -388,6 +421,7 @@ public class TomcatWebAppBuilder impleme
 
                 // TODO: instead of storing deployers, we could just lookup 
the right hostconfig for the server.
                 final HostConfig deployer = deployers.get(host);
+                appInfo.autoDeploy = false;
                 if (isReady(deployer)) { // if not ready using directly host 
to avoid a NPE
                     // host isn't set until we call deployer.manageApp, so 
pass it
                     // ?? host is set through an event and it can be null here 
:(

Added: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/ClusterObserver.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/ClusterObserver.java?rev=1363775&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/ClusterObserver.java
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/ClusterObserver.java
 Fri Jul 20 13:47:29 2012
@@ -0,0 +1,38 @@
+package org.apache.tomee.catalina.cluster;
+
+import org.apache.catalina.ha.CatalinaCluster;
+import org.apache.catalina.ha.ClusterMessage;
+import org.apache.openejb.assembler.classic.AppInfo;
+import 
org.apache.openejb.assembler.classic.event.AssemblerAfterApplicationCreated;
+import 
org.apache.openejb.assembler.classic.event.AssemblerBeforeApplicationDestroyed;
+import org.apache.openejb.observer.Observes;
+
+import java.io.File;
+import java.util.Set;
+
+public class ClusterObserver {
+    private final Set<CatalinaCluster> clusters;
+
+    public ClusterObserver(final Set<CatalinaCluster> clusters) {
+        this.clusters = clusters;
+    }
+
+    public void deploy(@Observes final AssemblerAfterApplicationCreated app) {
+        final AppInfo appInfo = app.getApp();
+        send(new UndeployMessage(appInfo.path), appInfo);
+    }
+
+    public void undeploy(@Observes final AssemblerBeforeApplicationDestroyed 
app) {
+        final AppInfo appInfo = app.getApp();
+        send(new DeployMessage(appInfo.path), appInfo);
+    }
+
+    private void send(final ClusterMessage message, final AppInfo app) {
+        for (CatalinaCluster cluster : clusters) {
+            final String path = app.path;
+            if (new File(path).exists() && !app.autoDeploy) {
+                cluster.send(message);
+            }
+        }
+    }
+}

Added: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/DeployMessage.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/DeployMessage.java?rev=1363775&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/DeployMessage.java
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/DeployMessage.java
 Fri Jul 20 13:47:29 2012
@@ -0,0 +1,16 @@
+package org.apache.tomee.catalina.cluster;
+
+import org.apache.catalina.ha.ClusterMessageBase;
+
+// TODO: serialize file in byte[] to be able to send it over the network?
+public class DeployMessage extends ClusterMessageBase {
+    private String file;
+
+    public DeployMessage(final String path) {
+        file = path;
+    }
+
+    public String getFile() {
+        return file;
+    }
+}

Added: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java?rev=1363775&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/TomEEClusterListener.java
 Fri Jul 20 13:47:29 2012
@@ -0,0 +1,77 @@
+package org.apache.tomee.catalina.cluster;
+
+import org.apache.catalina.ha.ClusterListener;
+import org.apache.catalina.ha.ClusterMessage;
+import org.apache.openejb.NoSuchApplicationException;
+import org.apache.openejb.OpenEJBException;
+import org.apache.openejb.UndeployException;
+import org.apache.openejb.assembler.Deployer;
+import org.apache.openejb.assembler.classic.Assembler;
+import org.apache.openejb.core.LocalInitialContextFactory;
+import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.util.LogCategory;
+import org.apache.openejb.util.Logger;
+
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import java.io.File;
+import java.util.Properties;
+
+public class TomEEClusterListener extends ClusterListener {
+    private static final Logger LOGGER = 
Logger.getInstance(LogCategory.OPENEJB, TomEEClusterListener.class);
+    private static final Properties IC_PROPS = new Properties();
+
+    static {
+        IC_PROPS.setProperty(Context.INITIAL_CONTEXT_FACTORY, 
LocalInitialContextFactory.class.getName());
+    }
+
+    @Override
+    public void messageReceived(final ClusterMessage clusterMessage) {
+        final Class<?> type = clusterMessage.getClass();
+
+        if (DeployMessage.class.equals(type)) {
+            final DeployMessage msg = (DeployMessage) clusterMessage;
+            final String file = msg.getFile();
+            final boolean alreadyDeployed = 
SystemInstance.get().getComponent(Assembler.class).isDeployed(file);
+            final File ioFile = new File(file);
+            if (ioFile.exists() && !alreadyDeployed) {
+                try {
+                    deployer().deploy(file);
+                } catch (OpenEJBException e) {
+                    LOGGER.warning("can't deploy: " + ioFile.getPath(), e);
+                } catch (NamingException e) {
+                    LOGGER.warning("can't find deployer", e);
+                }
+            } else if (!alreadyDeployed) {
+                LOGGER.warning("file is remote, can't deploy it: " + 
ioFile.getPath());
+            } else {
+                LOGGER.info("application already deployed: " + file);
+            }
+        } else if (UndeployMessage.class.equals(type)) {
+            final String file = ((UndeployMessage) clusterMessage).getFile();
+            if 
(SystemInstance.get().getComponent(Assembler.class).isDeployed(file)) {
+                try {
+                    deployer().undeploy(file);
+                } catch (UndeployException e) {
+                    LOGGER.error("can't undeploy app", e);
+                } catch (NoSuchApplicationException e) {
+                    LOGGER.warning("no app toi deploy", e);
+                } catch (NamingException e) {
+                    LOGGER.warning("can't find deployer", e);
+                }
+            }
+        } else {
+            LOGGER.warning("message type not supported: " + type);
+        }
+    }
+
+    private Deployer deployer() throws NamingException {
+        return (Deployer) new 
InitialContext(IC_PROPS).lookup("openejb/DeployerBusinessRemote");
+    }
+
+    @Override
+    public boolean accept(final ClusterMessage clusterMessage) {
+        return DeployMessage.class.equals(clusterMessage.getClass()) || 
UndeployMessage.class.equals(clusterMessage.getClass());
+    }
+}

Added: 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/UndeployMessage.java
URL: 
http://svn.apache.org/viewvc/openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/UndeployMessage.java?rev=1363775&view=auto
==============================================================================
--- 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/UndeployMessage.java
 (added)
+++ 
openejb/trunk/openejb/tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/cluster/UndeployMessage.java
 Fri Jul 20 13:47:29 2012
@@ -0,0 +1,15 @@
+package org.apache.tomee.catalina.cluster;
+
+import org.apache.catalina.ha.ClusterMessageBase;
+
+public class UndeployMessage extends ClusterMessageBase {
+    private String file;
+
+    public UndeployMessage(final String path) {
+        file = path;
+    }
+
+    public String getFile() {
+        return file;
+    }
+}


Reply via email to