String version = rs.getString(5);
// let's see if we have this logical plugin on the filesystem (it may or may not be under the same filename)
File expectedFile = new File(this.agentPluginDeployer.getPluginDir(), path);
File currentFile = null; // will be non-null if we find that we have this plugin on the filesystem already
Plugin cachedPluginOnFilesystem = this.agentPluginsOnFilesystem.get(expectedFile);
if (cachedPluginOnFilesystem != null) {
currentFile = expectedFile; // we have it where we are expected to have it
if (!cachedPluginOnFilesystem.getName().equals(name)) {
// I have no idea when or if this would ever happen, but at least log it so we'll see it if it does happen
log.warn("For some reason, the plugin file [" + expectedFile + "] is plugin ["
+ cachedPluginOnFilesystem.getName() + "] but the database says it should be [" + name
+ "]");
} else {
log.debug("File system and database agree on a plugin location for [" + expectedFile + "]");
}
} else {
// the plugin might still be on the file system but under a different filename, see if we can find it
for (Map.Entry<File, Plugin> cachePluginEntry : this.agentPluginsOnFilesystem.entrySet()) {
if (cachePluginEntry.getValue().getName().equals(name)) {
currentFile = cachePluginEntry.getKey();
cachedPluginOnFilesystem = cachePluginEntry.getValue();
log.info("Filesystem has a plugin [" + name + "] at the file [" + currentFile
+ "] which is different than where the DB thinks it should be [" + expectedFile + "]");
break; // we found it, no need to continue the loop
}
}
}
if (cachedPluginOnFilesystem != null && currentFile != null && currentFile.exists()) {
Plugin dbPlugin = new Plugin(name, path);
dbPlugin.setMd5(md5);
dbPlugin.setVersion(version);
dbPlugin.setMtime(mtime);
Plugin obsoletePlugin = AgentPluginDescriptorUtil.determineObsoletePlugin(dbPlugin,
cachedPluginOnFilesystem);
if (obsoletePlugin == cachedPluginOnFilesystem) { // yes use == for reference equality!
StringBuilder logMsg = new StringBuilder();
logMsg.append("Found agent plugin [").append(name);
logMsg.append("] in the DB that is newer than the one on the filesystem: ");
logMsg.append("DB path=[").append(path);
logMsg.append("]; file path=[").append(currentFile.getName());
logMsg.append("]; DB MD5=[").append(md5);
logMsg.append("]; file MD5=[").append(cachedPluginOnFilesystem.getMd5());
logMsg.append("]; DB version=[").append(version);
logMsg.append("]; file version=[").append(cachedPluginOnFilesystem.getVersion());
logMsg.append("]; DB timestamp=[").append(new Date(mtime));
logMsg.append("]; file timestamp=[").append(new Date(cachedPluginOnFilesystem.getMtime()));
logMsg.append("]");
log.info(logMsg.toString());
updatedPlugins.add(dbPlugin);
if (currentFile.delete()) {
log.info("Deleted the obsolete agent plugin file to be updated: " + currentFile);
this.agentPluginsOnFilesystem.remove(currentFile);
} else {
log.warn("Failed to delete the obsolete (to-be-updated) agent plugin file: " + currentFile);
}
currentFile = null;
} else if (obsoletePlugin == null) {
// the db is up-to-date, but update the cache so we don't check MD5 or parse the descriptor again
currentFile.setLastModified(mtime);
cachedPluginOnFilesystem.setMtime(mtime);
cachedPluginOnFilesystem.setVersion(version);
cachedPluginOnFilesystem.setMd5(md5);
} else {
String message = "It appears the agent plugin [" + dbPlugin
+ "] in the database may be obsolete. If so, it will be updated soon by the version on the filesystem [" + currentFile + "].";
if (currentFile.getAbsolutePath().equals(expectedFile.getAbsolutePath())) {
if (log.isDebugEnabled()) {
log.debug(message);
}
} else {
//inform on the info level so that it's clear from the logs that the new file
//is going to be used.
log.info(message);
}
}
} else {
log.info("Found agent plugin in the DB that we do not yet have: " + name);
Plugin plugin = new Plugin(name, path, md5);
plugin.setMtime(mtime);
plugin.setVersion(version);
updatedPlugins.add(plugin);
this.agentPluginsOnFilesystem.remove(expectedFile); // paranoia, make sure the cache doesn't have this
}
}
JDBCUtil.safeClose(ps, rs);
// write all our updated plugins to the file system
if (!updatedPlugins.isEmpty()) {
ps = conn.prepareStatement("SELECT CONTENT FROM " + Plugin.TABLE_NAME
+ " WHERE DEPLOYMENT = 'AGENT' AND NAME = ? AND ENABLED = ?");
for (Plugin plugin : updatedPlugins) {
File file = new File(this.agentPluginDeployer.getPluginDir(), plugin.getPath());
ps.setString(1, plugin.getName());
setEnabledFlag(conn, ps, 2, true);
rs = ps.executeQuery();
rs.next();
InputStream content = rs.getBinaryStream(1);
StreamUtil.copy(content, new FileOutputStream(file));
rs.close();
file.setLastModified(plugin.getMtime()); // so our file matches the database mtime
updatedFiles.add(file);
}
}
} finally {
JDBCUtil.safeClose(conn, ps, rs);