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>