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 18:56:59 UTC

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

Author: kevan
Date: Fri Apr  8 16:56:59 2011
New Revision: 1090351

URL: http://svn.apache.org/viewvc?rev=1090351&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 can be processed

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

Modified: geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java?rev=1090351&r1=1090350&r2=1090351&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java (original)
+++ geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryHotDeployer.java Fri Apr  8 16:56:59 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);
@@ -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/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java?rev=1090351&r1=1090350&r2=1090351&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java (original)
+++ geronimo/server/trunk/plugins/hotdeploy/geronimo-hot-deploy/src/main/java/org/apache/geronimo/deployment/hot/DirectoryMonitor.java Fri Apr  8 16:56:59 2011
@@ -17,7 +17,11 @@
 package org.apache.geronimo.deployment.hot;
 
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.HashMap;
@@ -117,13 +121,21 @@ 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<String, FileInfo> files = new HashMap<String, FileInfo>();
+    private final Map<String, FileInfo> files;
     private final List<Artifact> toRemove = new ArrayList<Artifact>();
+    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 = readState();
+        persistState();
     }
 
     public int getPollIntervalMillis() {
@@ -197,6 +209,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 Map<String,FileInfo> readState() {
+    	Map<String,FileInfo> newFiles = null;
+    	if (monitorFile != null) {
+    		ObjectInputStream inputStream = null;
+    		try {
+    			inputStream = new ObjectInputStream(new FileInputStream(monitorFile));
+    			newFiles = (Map<String,FileInfo>) inputStream.readObject();
+    		} 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
+    			}
+    		}
+    	}
+		if (newFiles == null) {
+			newFiles = new HashMap<String,FileInfo>();
+		}
+		return newFiles;
+    }
+    
     public void run() {
         boolean serverStarted = false, initialized = false;
         while (!done) {
@@ -234,6 +297,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 {
@@ -249,6 +315,7 @@ log.info("At startup, found "+now.getPat
                 log.error("Unable to scan file " + child.getAbsolutePath() + " during initialization", e);
             }
         }
+        persistState();
     }
 
     /**
@@ -266,16 +333,21 @@ log.info("At startup, found "+now.getPat
         synchronized (files) {
             Set<String> oldList = new HashSet<String>(files.keySet());
             List<FileAction> actions = new LinkedList<FileAction>();
+            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 = 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());
@@ -296,6 +368,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());
                     }
                 }
@@ -307,6 +380,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));
                 }
@@ -327,6 +401,7 @@ log.info("At startup, found "+now.getPat
                         if (action.action == FileAction.REMOVED_FILE) {
                             if (action.info.getConfigId() == null || listener.fileRemoved(action.child, action.info.getConfigId())) {
                                 files.remove(action.child.getPath());
+                                changeMade = true;
                             }
                         } else if (action.action == FileAction.NEW_FILE) {
                             if (listener.isFileDeployed(action.child, calculateModuleId(action.child))) {
@@ -363,6 +438,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;
@@ -379,6 +455,7 @@ log.info("At startup, found "+now.getPat
                                 }
                             }
                             action.info.setNewFile(false);
+                            changeMade = true;
                         } else if (action.action == FileAction.UPDATED_FILE) {
                             String result = listener.fileUpdated(action.child, action.info.getConfigId());
                             FileInfo update = action.info;
@@ -397,6 +474,9 @@ log.info("At startup, found "+now.getPat
                     }
                 }
             }
+            if (changeMade) {
+                persistState();
+            }
         }
     }
 
@@ -487,7 +567,7 @@ log.info("At startup, found "+now.getPat
     }
 
     private static class FileInfo implements Serializable {
-        private String path;
+		private String path;
         private long size;
         private long modified;
         private boolean newFile;

Modified: geronimo/server/trunk/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml?rev=1090351&r1=1090350&r2=1090351&view=diff
==============================================================================
--- geronimo/server/trunk/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml (original)
+++ geronimo/server/trunk/plugins/hotdeploy/hot-deployer/src/main/plan/plan.xml Fri Apr  8 16:56:59 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>