You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomee.apache.org by Romain Manni-Bucau <rm...@gmail.com> on 2012/07/20 15:52:04 UTC

Fwd: svn commit: r1363775 - in /openejb/trunk/openejb: container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ tomee/tomee-catalina/ tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ tomee/tomee-catalina/src/main/java/o

just pushed some cluster deployment feature. It still needs a lot of
improvement but i pushed it more for the idea.

1) currently it needs an app deploy through our deployer
(appinfo.autodeploy = false) -> here some work to do, the autodeploy
boolean should be true when tomcat manage the app or tomee manage it from
apps/ or a deployment defines in tomee.xml
2) assembler deploy/undeploy events are observed and then a deploy/undeploy
tomcat message cluster is sent to the cluster
3) other listeneing member do the same

it doesn't loop because we test if the app is already deployed.

currently the filesystem should be the same

here the todo we can discuss on:
1) autodeploy boolean
2) do we serialize the app to be able to deploy it even on remote hosts
3) others

any comments are welcomed of course ;)

- Romain


---------- Forwarded message ----------
From: <rm...@apache.org>
Date: 2012/7/20
Subject: svn commit: r1363775 - in /openejb/trunk/openejb:
container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
tomee/tomee-catalina/
tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/
tomee/tomee-catalina/src/main/java/org/apac...
To: commits@openejb.apache.org


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;
+    }
+}

Re: Fwd: svn commit: r1363775 - in /openejb/trunk/openejb: container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/ tomee/tomee-catalina/ tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/ tomee/tomee-catalina/src/main/java/o

Posted by Enrico Olivelli <eo...@gmail.com>.
this sounds very interesting !
Have you got some design doc about this cluster deployment feature ?

the app have to be managed only on one TomEE in the cluster 
(deploy/undeploy....) ?
in GF there is the concept of DAS, a Node in the cluster which does 
configuration things and coordinates deployment on the other nodes

The admin have to configure many things....
- Resources (Datasources, Queues....) have to be configured cluster-wide
- Tomcat session replication must be configured
- OpenEJB cluster features must be configured
- Quartz configuration must be the same (except from the scheduler local 
instance id) and it must use a datasource
- Embedded ActiveMQ configuration will not be trivial (need to configure 
as master/slaver, use a shared datasource, client url to use MUST use 
failover or discovery.....) or the useer have tto use an external activemq
- JPA issues ??
- Configuration of Reverse-Proxy/Load balancers (maybe this is a Tomcat 
problem)

- Enrico






Il 20/07/2012 15:52, Romain Manni-Bucau ha scritto:
> just pushed some cluster deployment feature. It still needs a lot of
> improvement but i pushed it more for the idea.
>
> 1) currently it needs an app deploy through our deployer
> (appinfo.autodeploy = false) -> here some work to do, the autodeploy
> boolean should be true when tomcat manage the app or tomee manage it from
> apps/ or a deployment defines in tomee.xml
> 2) assembler deploy/undeploy events are observed and then a deploy/undeploy
> tomcat message cluster is sent to the cluster
> 3) other listeneing member do the same
>
> it doesn't loop because we test if the app is already deployed.
>
> currently the filesystem should be the same
>
> here the todo we can discuss on:
> 1) autodeploy boolean
> 2) do we serialize the app to be able to deploy it even on remote hosts
> 3) others
>
> any comments are welcomed of course ;)
>
> - Romain
>
>
> ---------- Forwarded message ----------
> From: <rm...@apache.org>
> Date: 2012/7/20
> Subject: svn commit: r1363775 - in /openejb/trunk/openejb:
> container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/
> tomee/tomee-catalina/
> tomee/tomee-catalina/src/main/java/org/apache/tomee/catalina/
> tomee/tomee-catalina/src/main/java/org/apac...
> To: commits@openejb.apache.org
>
>
> 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;
> +    }
> +}
>