Methods Summary |
---|
public boolean | accept(org.apache.catalina.ha.ClusterMessage msg)Before the cluster invokes messageReceived the cluster will ask the
receiver to accept or decline the message, In the future, when messages
get big, the accept method will only take a message header
return (msg instanceof FileMessage) || (msg instanceof UndeployMessage);
|
protected void | addServiced(java.lang.String name)Invoke the check method on the deployer.
String[] params = { name };
String[] signature = { "java.lang.String" };
mBeanServer.invoke(oname, "addServiced", params, signature);
|
public void | backgroundProcess()
if (started) {
count = (count + 1) % processDeployFrequency;
if (count == 0 && watchEnabled) {
watcher.check();
}
}
|
protected void | check(java.lang.String name)Invoke the check method on the deployer.
String[] params = { name };
String[] signature = { "java.lang.String" };
mBeanServer.invoke(oname, "check", params, signature);
|
public void | cleanDeployDir()
throw new java.lang.UnsupportedOperationException(
"Method cleanDeployDir() not yet implemented.");
|
protected boolean | copy(java.io.File from, java.io.File to)Copy a file to the specified temp directory.
try {
if (!to.exists())
to.createNewFile();
java.io.FileInputStream is = new java.io.FileInputStream(from);
java.io.FileOutputStream os = new java.io.FileOutputStream(to,
false);
byte[] buf = new byte[4096];
while (true) {
int len = is.read(buf);
if (len < 0)
break;
os.write(buf, 0, len);
}
is.close();
os.close();
} catch (IOException e) {
log.error("Unable to copy file from:" + from + " to:" + to, e);
return false;
}
return true;
|
public boolean | equals(java.lang.Object listener)
return super.equals(listener);
|
public void | fileModified(java.io.File newWar)
try {
File deployWar = new File(getDeployDir(), newWar.getName());
copy(newWar, deployWar);
String contextName = getContextName(deployWar);
if (log.isInfoEnabled())
log.info("Installing webapp[" + contextName + "] from "
+ deployWar.getAbsolutePath());
try {
remove(contextName, false);
} catch (Exception x) {
log.error("No removal", x);
}
install(contextName, deployWar.toURL());
} catch (Exception x) {
log.error("Unable to install WAR file", x);
}
|
public void | fileRemoved(java.io.File removeWar)
try {
String contextName = getContextName(removeWar);
if (log.isInfoEnabled())
log.info("Removing webapp[" + contextName + "]");
remove(contextName, true);
} catch (Exception x) {
log.error("Unable to remove WAR file", x);
}
|
protected java.io.File | getAppBase()Return a File object representing the "application root" directory for
our associated Host.
if (appBase != null) {
return appBase;
}
File file = new File(host.getAppBase());
if (!file.isAbsolute())
file = new File(System.getProperty("catalina.base"), host
.getAppBase());
try {
appBase = file.getCanonicalFile();
} catch (IOException e) {
appBase = file;
}
return (appBase);
|
public org.apache.catalina.ha.CatalinaCluster | getCluster()
return cluster;
|
protected java.lang.String | getConfigFile(java.lang.String path)Given a context path, get the config file name.
String basename = null;
if (path.equals("")) {
basename = "ROOT";
} else {
basename = path.substring(1).replace('/", '#");
}
return (basename);
|
protected java.lang.String | getContextName(java.io.File war)Create a context path from war
String contextName = "/"
+ war.getName().substring(0,
war.getName().lastIndexOf(".war"));
if("/ROOT".equals(contextName))
contextName= "" ;
return contextName ;
|
public java.lang.String | getDeployDir()
return deployDir;
|
protected java.lang.String | getDocBase(java.lang.String path)Given a context path, get the config file name.
String basename = null;
if (path.equals("")) {
basename = "ROOT";
} else {
basename = path.substring(1);
}
return (basename);
|
public synchronized FileMessageFactory | getFactory(FileMessage msg)create factory for all transported war files
File tmpFile = new File(msg.getFileName());
File writeToFile = new File(getTempDir(), tmpFile.getName());
FileMessageFactory factory = (FileMessageFactory) fileFactories.get(msg
.getFileName());
if (factory == null) {
factory = FileMessageFactory.getInstance(writeToFile, true);
fileFactories.put(msg.getFileName(), factory);
}
return factory;
|
public java.lang.String | getInfo()Return descriptive information about this deployer implementation and the
corresponding version number, in the format
<description>/<version> .
return (info);
|
public int | getProcessDeployFrequency()Return the frequency of watcher checks.
return (this.processDeployFrequency);
|
public java.lang.String | getTempDir()
return tempDir;
|
public java.lang.String | getWatchDir()
return watchDir;
|
public boolean | getWatchEnabled()
return watchEnabled;
|
public int | hashCode()
return super.hashCode();
|
public void | install(java.lang.String contextPath, java.net.URL war)Install a new web application, whose web application archive is at the
specified URL, into this container and all the other members of the
cluster with the specified context path. A context path of "" (the empty
string) should be used for the root application for this container.
Otherwise, the context path must start with a slash.
If this application is successfully installed locally, a ContainerEvent
of type INSTALL_EVENT will be sent to all registered
listeners, with the newly created Context as an argument.
Member[] members = getCluster().getMembers();
Member localMember = getCluster().getLocalMember();
FileMessageFactory factory = FileMessageFactory.getInstance(new File(
war.getFile()), false);
FileMessage msg = new FileMessage(localMember, war.getFile(),
contextPath);
if(log.isDebugEnabled())
log.debug("Send cluster war deployment [ path:"
+ contextPath + " war: " + war + " ] started.");
msg = factory.readMessage(msg);
while (msg != null) {
for (int i = 0; i < members.length; i++) {
if (log.isDebugEnabled())
log.debug("Send cluster war fragment [ path: "
+ contextPath + " war: " + war + " to: " + members[i] + " ]");
getCluster().send(msg, members[i]);
}
msg = factory.readMessage(msg);
}
if(log.isDebugEnabled())
log.debug("Send cluster war deployment [ path: "
+ contextPath + " war: " + war + " ] finished.");
|
protected boolean | isServiced(java.lang.String name)Invoke the check method on the deployer.
String[] params = { name };
String[] signature = { "java.lang.String" };
Boolean result = (Boolean) mBeanServer.invoke(oname, "isServiced",
params, signature);
return result.booleanValue();
|
public boolean | isWatchEnabled()
return watchEnabled;
|
public void | messageReceived(org.apache.catalina.ha.ClusterMessage msg)Callback from the cluster, when a message is received, The cluster will
broadcast it invoking the messageReceived on the receiver.
try {
if (msg instanceof FileMessage && msg != null) {
FileMessage fmsg = (FileMessage) msg;
if (log.isDebugEnabled())
log.debug("receive cluster deployment [ path: "
+ fmsg.getContextPath() + " war: "
+ fmsg.getFileName() + " ]");
FileMessageFactory factory = getFactory(fmsg);
// TODO correct second try after app is in service!
if (factory.writeMessage(fmsg)) {
//last message received war file is completed
String name = factory.getFile().getName();
if (!name.endsWith(".war"))
name = name + ".war";
File deployable = new File(getDeployDir(), name);
try {
String path = fmsg.getContextPath();
if (!isServiced(path)) {
addServiced(path);
try {
remove(path);
factory.getFile().renameTo(deployable);
check(path);
} finally {
removeServiced(path);
}
if (log.isDebugEnabled())
log.debug("deployment from " + path
+ " finished.");
} else
log.error("Application " + path
+ " in used. touch war file " + name
+ " again!");
} catch (Exception ex) {
log.error(ex);
} finally {
removeFactory(fmsg);
}
}
} else if (msg instanceof UndeployMessage && msg != null) {
try {
UndeployMessage umsg = (UndeployMessage) msg;
String path = umsg.getContextPath();
if (log.isDebugEnabled())
log.debug("receive cluster undeployment from " + path);
if (!isServiced(path)) {
addServiced(path);
try {
remove(path);
} finally {
removeServiced(path);
}
if (log.isDebugEnabled())
log.debug("undeployment from " + path
+ " finished.");
} else
log.error("Application "
+ path
+ " in used. Sorry not remove from backup cluster nodes!");
} catch (Exception ex) {
log.error(ex);
}
}
} catch (java.io.IOException x) {
log.error("Unable to read farm deploy file message.", x);
}
|
public void | remove(java.lang.String contextPath, boolean undeploy)Remove an existing web application, attached to the specified context
path. If this application is successfully removed, a ContainerEvent of
type REMOVE_EVENT will be sent to all registered
listeners, with the removed Context as an argument.
Deletes the web application war file and/or directory if they exist in
the Host's appBase.
if (log.isInfoEnabled())
log.info("Cluster wide remove of web app " + contextPath);
Member localMember = getCluster().getLocalMember();
UndeployMessage msg = new UndeployMessage(localMember, System
.currentTimeMillis(), "Undeploy:" + contextPath + ":"
+ System.currentTimeMillis(), contextPath, undeploy);
if (log.isDebugEnabled())
log.debug("Send cluster wide undeployment from "
+ contextPath );
cluster.send(msg);
// remove locally
if (undeploy) {
try {
if (!isServiced(contextPath)) {
addServiced(contextPath);
try {
remove(contextPath);
} finally {
removeServiced(contextPath);
}
} else
log.error("Local remove from " + contextPath
+ "failed, other manager has app in service!");
} catch (Exception ex) {
log.error("local remove from " + contextPath + " failed", ex);
}
}
|
protected void | remove(java.lang.String path)Invoke the remove method on the deployer.
// TODO Handle remove also work dir content !
// Stop the context first to be nicer
Context context = (Context) host.findChild(path);
if (context != null) {
if(log.isDebugEnabled())
log.debug("Undeploy local context " +path );
((Lifecycle) context).stop();
File war = new File(getAppBase(), getDocBase(path) + ".war");
File dir = new File(getAppBase(), getDocBase(path));
File xml = new File(configBase, getConfigFile(path) + ".xml");
if (war.exists()) {
war.delete();
} else if (dir.exists()) {
undeployDir(dir);
} else {
xml.delete();
}
// Perform new deployment and remove internal HostConfig state
check(path);
}
|
public void | removeFactory(FileMessage msg)Remove file (war) from messages)
fileFactories.remove(msg.getFileName());
|
protected void | removeServiced(java.lang.String name)Invoke the check method on the deployer.
String[] params = { name };
String[] signature = { "java.lang.String" };
mBeanServer.invoke(oname, "removeServiced", params, signature);
|
public void | setCluster(org.apache.catalina.ha.CatalinaCluster cluster)
this.cluster = cluster;
|
public void | setDeployDir(java.lang.String deployDir)
this.deployDir = deployDir;
|
public void | setProcessDeployFrequency(int processExpiresFrequency)Set the watcher checks frequency.
if (processExpiresFrequency <= 0) {
return;
}
this.processDeployFrequency = processExpiresFrequency;
|
public void | setTempDir(java.lang.String tempDir)
this.tempDir = tempDir;
|
public void | setWatchDir(java.lang.String watchDir)
this.watchDir = watchDir;
|
public void | setWatchEnabled(boolean watchEnabled)
this.watchEnabled = watchEnabled;
|
public void | start()
if (started)
return;
getCluster().addClusterListener(this);
if (watchEnabled) {
watcher = new WarWatcher(this, new File(getWatchDir()));
if (log.isInfoEnabled())
log.info("Cluster deployment is watching " + getWatchDir()
+ " for changes.");
}
// Check to correct engine and host setup
Object parent = getCluster().getContainer();
Engine engine = null;
String hostname = null;
if ( parent instanceof Host ) {
host = (Host) parent;
engine = (Engine) host.getParent();
hostname = host.getName();
}else {
engine = (Engine)parent;
hostname = engine.getDefaultHost();
}
try {
oname = new ObjectName(engine.getName() + ":type=Deployer,host="
+ hostname);
} catch (Exception e) {
log.error("Can't construct MBean object name" + e);
}
configBase = new File(System.getProperty("catalina.base"), "conf");
if (engine != null) {
configBase = new File(configBase, engine.getName());
} else if (host != null) {
configBase = new File(configBase, host.getName());
}
// Retrieve the MBean server
mBeanServer = Registry.getRegistry(null, null).getMBeanServer();
started = true;
count = 0;
if (log.isInfoEnabled())
log.info("Cluster FarmWarDeployer started.");
|
public void | stop()
started = false;
getCluster().removeClusterListener(this);
count = 0;
if (watcher != null) {
watcher.clear();
watcher = null;
}
if (log.isInfoEnabled())
log.info("Cluster FarmWarDeployer stopped.");
|
protected void | undeployDir(java.io.File dir)Delete the specified directory, including all of its contents and
subdirectories recursively.
String files[] = dir.list();
if (files == null) {
files = new String[0];
}
for (int i = 0; i < files.length; i++) {
File file = new File(dir, files[i]);
if (file.isDirectory()) {
undeployDir(file);
} else {
file.delete();
}
}
dir.delete();
|