You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ke...@apache.org on 2011/04/08 00:18:58 UTC

svn commit: r1090049 - in /geronimo/server/branches/2.2/plugins/hotdeploy: geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/ hot-deployer/src/main/plan/

Author: kevan
Date: Thu Apr  7 22:18:58 2011
New Revision: 1090049

URL: http://svn.apache.org/viewvc?rev=1090049&view=rev
Log:
GERONIMO-5891 persist the DirectoryMonitor state to disk. Used to read initial state on server start. So, hot-deploy changes made while server was stopped will be processed

Modified:
    geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
    geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java
    geronimo/server/branches/2.2/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml

Modified: geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java?rev=1090049&r1=1090048&r2=1090049&view=diff
==============================================================================
--- geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java (original)
+++ geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java Thu Apr  7 22:18:58 2011
@@ -65,6 +65,7 @@ public class DirectoryHotDeployer implem
             "is 'deploy/' and your file is 'webapp.war' then you could unpack it into a directory 'deploy/webapp.war/'";
     private DirectoryMonitor monitor;
     private String path;
+    private String monitorFileName;
     private ServerInfo serverInfo;
     private ConfigurationManager configManager;
     private int pollIntervalMillis;
@@ -76,8 +77,10 @@ public class DirectoryHotDeployer implem
     private transient TargetModuleID[] startupModules = null;
     private transient boolean serverRunning = false;
 
-    public DirectoryHotDeployer(String path, int pollIntervalMillis, ServerInfo serverInfo, ConfigurationManager configManager, Kernel kernel) {
+    public DirectoryHotDeployer(String path, String monitorFileName, int pollIntervalMillis, 
+                                ServerInfo serverInfo, ConfigurationManager configManager, Kernel kernel) {
         this.path = path;
+        this.monitorFileName = monitorFileName;
         this.serverInfo = serverInfo;
         this.pollIntervalMillis = pollIntervalMillis;
         this.kernel = kernel;
@@ -147,6 +150,7 @@ public class DirectoryHotDeployer implem
         if (factory == null) {
             factory = new DeploymentFactoryWithKernel(kernel);
         }
+        
         File dir = serverInfo.resolveServer(path);
         if (!dir.exists()) {
             if (!dir.mkdirs()) {
@@ -155,6 +159,17 @@ public class DirectoryHotDeployer implem
         } else if (!dir.canRead() || !dir.isDirectory()) {
             throw new IllegalStateException("Hot deploy directory " + dir.getAbsolutePath() + " is not a readable directory!");
         }
+        
+        File monitorFile = null;
+        if (monitorFileName != null && !monitorFileName.isEmpty()) {
+            monitorFile = serverInfo.resolveServer(dir + File.separator + monitorFileName);
+            if (!monitorFile.createNewFile()) {
+                if (!monitorFile.canWrite()) {
+                    throw new IllegalStateException("Hot deploy persist state file " + monitorFile.getAbsolutePath() + " could not be created or is not writable");
+                }
+            }
+        }
+        
         DeploymentManager mgr = null;
         try {
             mgr = getDeploymentManager();
@@ -162,7 +177,7 @@ public class DirectoryHotDeployer implem
             startupModules = mgr.getAvailableModules(null, targets);
             mgr.release();
             mgr = null;
-            monitor = new DirectoryMonitor(dir, this, pollIntervalMillis);
+            monitor = new DirectoryMonitor(dir, monitorFile, this, pollIntervalMillis);
             log.debug("Hot deploy scanner intialized; starting main loop.");
             Thread t = new Thread(monitor, "Geronimo hot deploy scanner");
             t.setDaemon(true);
@@ -299,22 +314,22 @@ public class DirectoryHotDeployer implem
                     }
                 }
             } else {
-            	 //Try to delete the module , that failed to successfully hot-deploy  
-            	log.error("Unable to deploy: " + po.getDeploymentStatus().getMessage());
-            	String delfile=file.getAbsolutePath();
+                //Try to delete the module , that failed to successfully hot-deploy  
+                log.error("Unable to deploy: " + po.getDeploymentStatus().getMessage());
+                String delfile=file.getAbsolutePath();
                 File fd = new File(delfile);
                 if(fd.isDirectory()){
-               	    log.info("Deleting the Directory: "+delfile);
-               	    if(DeploymentUtil.recursiveDelete(fd))
-               		    log.debug("Successfully deleted the Directory: "+delfile);
-               	    else
-               		    log.error("Couldn't delete the hot deployed directory"+delfile);
+                    log.info("Deleting the Directory: "+delfile);
+                    if(DeploymentUtil.recursiveDelete(fd))
+                        log.debug("Successfully deleted the Directory: "+delfile);
+                    else
+                        log.error("Couldn't delete the hot deployed directory"+delfile);
                 }else if(fd.isFile()){
-               	    log.info("Deleting the File: "+delfile);
-               	    if(fd.delete()){
-               		log.debug("Successfully deleted the File: "+delfile); 
-               	}else
-               		log.error("Couldn't delete the hot deployed directory"+delfile); 
+                    log.info("Deleting the File: "+delfile);
+                    if(fd.delete()){
+                        log.debug("Successfully deleted the File: "+delfile); 
+                    }else
+                        log.error("Couldn't delete the hot deployed directory"+delfile); 
                 }
                             
                 return null;
@@ -466,6 +481,7 @@ public class DirectoryHotDeployer implem
         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(DirectoryHotDeployer.class);
 
         infoFactory.addAttribute("path", String.class, true, true);
+        infoFactory.addAttribute("monitorFileName", String.class, true, true);
         infoFactory.addAttribute("pollIntervalMillis", int.class, true, true);
 
         // The next 3 args can be used to configure the hot deployer for a remote (out of VM) server
@@ -478,7 +494,7 @@ public class DirectoryHotDeployer implem
         infoFactory.addAttribute("kernel", Kernel.class, false, false);
         infoFactory.addInterface(HotDeployer.class);
 
-        infoFactory.setConstructor(new String[]{"path", "pollIntervalMillis", "ServerInfo", "ConfigManager", "kernel"});
+        infoFactory.setConstructor(new String[]{"path", "monitorFileName", "pollIntervalMillis", "ServerInfo", "ConfigManager", "kernel"});
 
         GBEAN_INFO = infoFactory.getBeanInfo();
     }

Modified: geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java?rev=1090049&r1=1090048&r2=1090049&view=diff
==============================================================================
--- geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java (original)
+++ geronimo/server/branches/2.2/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java Thu Apr  7 22:18:58 2011
@@ -23,7 +23,12 @@ import org.apache.geronimo.deployment.ut
 import org.apache.geronimo.kernel.repository.Artifact;
 import org.apache.geronimo.kernel.config.IOUtil;
 
+import java.io.EOFException;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.io.IOException;
 import java.util.Map;
@@ -117,13 +122,30 @@ public class DirectoryMonitor implements
     private File directory;
     private boolean done = false;
     private Listener listener; // a little cheesy, but do we really need multiple listeners?
-    private final Map files = new HashMap();
+    private Map<String,FileInfo> files;
     private volatile String workingOnConfigId;
+    private File monitorFile;
 
     public DirectoryMonitor(File directory, Listener listener, int pollIntervalMillis) {
+        this(directory, null, listener, pollIntervalMillis);
+    }
+
+    public DirectoryMonitor(File directory, File monitorFile, Listener listener, int pollIntervalMillis) {
         this.directory = directory;
         this.listener = listener;
         this.pollIntervalMillis = pollIntervalMillis;
+        this.monitorFile = monitorFile;
+        this.files = new HashMap<String,FileInfo>();
+
+        if (monitorFile != null) {
+            if (monitorFile.canRead()) {
+                log.info("Found monitorFile. Reading initial directory monitor state from " + monitorFile.getName());
+                readState();
+            } else {
+                log.info("Did not find monitorFile. Saving initial state to " + monitorFile.getName());
+                persistState();
+            }
+        }
     }
 
     public int getPollIntervalMillis() {
@@ -194,6 +216,57 @@ public class DirectoryMonitor implements
         }
     }
 
+    private void persistState() {
+        if (monitorFile == null) {
+            return;
+        }
+    
+        log.info("Persisting directory monitor state to " + monitorFile.getName());
+        ObjectOutputStream outputStream = null;
+        try {
+            outputStream = new ObjectOutputStream(new FileOutputStream(monitorFile));
+            outputStream.writeObject(files);
+        } catch (IOException ioe) {
+            log.warn("Error persisting directory monitor state to " + monitorFile.getName(), ioe);
+        } finally {
+            if (outputStream != null) {
+                try {
+                    outputStream.close();
+                } catch (IOException ioe) {
+
+                }
+            }
+        }    
+    }
+    
+    @SuppressWarnings("unchecked")
+    private void readState() {
+    if (monitorFile == null) {
+    return;
+    }
+    ObjectInputStream inputStream = null;
+    try {
+        inputStream = new ObjectInputStream(new FileInputStream(monitorFile));
+        files = (Map<String,FileInfo>) inputStream.readObject();
+        if (files == null) {
+            this.files = new HashMap<String,FileInfo>();
+        }
+    } catch (IOException ex) {
+        log.info("IOException reading directory monitor state from " + monitorFile.getName(), ex);
+    } catch (ClassNotFoundException cnfe) {
+        log.warn("ClassNotFoundException reading directory monitor state from " + monitorFile.getName(), cnfe);
+    } finally {
+        try {
+            if (inputStream != null) {
+                inputStream.close();
+            }
+        } catch (IOException ioe) {
+            // ignore
+        }
+    }
+        
+    }
+    
     public void run() {
         boolean serverStarted = false, initialized = false;
         while (!done) {
@@ -231,6 +304,9 @@ public class DirectoryMonitor implements
             if (!child.canRead()) {
                 continue;
             }
+            if (child.equals(monitorFile)) {
+                continue;
+            }
             FileInfo now = child.isDirectory() ? getDirectoryInfo(child) : getFileInfo(child);
             now.setChanging(false);
             try {
@@ -246,6 +322,7 @@ log.info("At startup, found "+now.getPat
                 log.error("Unable to scan file " + child.getAbsolutePath() + " during initialization", e);
             }
         }
+        persistState();
     }
 
     /**
@@ -262,16 +339,21 @@ log.info("At startup, found "+now.getPat
         synchronized (files) {
             Set oldList = new HashSet(files.keySet());
             List actions = new LinkedList();
+            boolean changeMade = false;
             for (int i = 0; i < children.length; i++) {
                 File child = children[i];
                 if (!child.canRead()) {
                     continue;
                 }
+                if (child.equals(monitorFile)) {
+                    continue;
+                }
                 FileInfo now = child.isDirectory() ? getDirectoryInfo(child) : getFileInfo(child);
                 FileInfo then = (FileInfo) files.get(now.getPath());
                 if (then == null) { // Brand new, wait a bit to make sure it's not still changing
                     now.setNewFile(true);
                     files.put(now.getPath(), now);
+                    changeMade = true;
                     log.debug("New File: " + now.getPath());
                 } else {
                     oldList.remove(then.getPath());
@@ -292,6 +374,7 @@ log.info("At startup, found "+now.getPat
                         now.setConfigId(then.getConfigId());
                         now.setNewFile(then.isNewFile());
                         files.put(now.getPath(), now);
+                        changeMade = true;
                         log.debug("File Changed: " + now.getPath());
                     }
                 }
@@ -303,6 +386,7 @@ log.info("At startup, found "+now.getPat
                 log.debug("File removed: " + name);
                 if (info.isNewFile()) { // Was never added, just whack it
                     files.remove(name);
+                    changeMade = true;
                 } else {
                     actions.add(new FileAction(FileAction.REMOVED_FILE, new File(name), info));
                 }
@@ -324,6 +408,7 @@ log.info("At startup, found "+now.getPat
                             workingOnConfigId = action.info.getConfigId();
                             if (action.info.getConfigId() == null || listener.fileRemoved(action.child, action.info.getConfigId())) {
                                 files.remove(action.child.getPath());
+                                changeMade = true;
                             }
                             workingOnConfigId = null;
                         } else if (action.action == FileAction.NEW_FILE) {
@@ -361,6 +446,7 @@ log.info("At startup, found "+now.getPat
                                                 log.error("Couldn't delete the hot deployed file="+path); 
                                         }
                                         files.remove(path);
+                                        changeMade = true;
                                     }
                                 }
                                 workingOnConfigId = null;
@@ -377,6 +463,7 @@ log.info("At startup, found "+now.getPat
                                 }
                             }
                             action.info.setNewFile(false);
+                            changeMade = true;
                         } else if (action.action == FileAction.UPDATED_FILE) {
                             workingOnConfigId = action.info.getConfigId();
                             String result = listener.fileUpdated(action.child, action.info.getConfigId());
@@ -397,6 +484,9 @@ log.info("At startup, found "+now.getPat
                     }
                 }
             }
+            if (changeMade) {
+                persistState();
+            }
         }
     }
 

Modified: geronimo/server/branches/2.2/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml
URL: http://svn.apache.org/viewvc/geronimo/server/branches/2.2/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml?rev=1090049&r1=1090048&r2=1090049&view=diff
==============================================================================
--- geronimo/server/branches/2.2/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml (original)
+++ geronimo/server/branches/2.2/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml Thu Apr  7 22:18:58 2011
@@ -28,6 +28,7 @@
             <name>ConfigurationManager</name>
         </reference>
         <attribute name="path">deploy/</attribute>
+        <attribute name="monitorFileName">.DirectoryMonitor</attribute>
         <attribute name="pollIntervalMillis">2000</attribute>
         <dependency>
             <name>EARBuilder</name>